eeaabc4ba2
Lottie shapes (paths) are expressed as a sequence of vertices, where each vertex has a - position - in-tangent control point (relative to position) - out-tangent control point (relative to position) A nice property of this representation, is that interpolation can be performed independently on each scalar component. This seems really close to what VectorAnimator is good at - so can we shoe-horn shapes into vectors and drop the ShapeValue KeyframeAnimator specialization? Yes, we can! To support the conversion, we need to abstract out two aspects of the VectorKeyframeAnimator builder: - parsing the encoding length of a vector-representable object - parsing the actual encoding data of a vector-representable object (For current/regular vector values, the encoding length is the same as the json array length, and the encoding data is just the array of json numbers.) Shapes are encoded as a sequence of 6 floats per vertex, plus an additional/trailing boolean maker for the "closed shape" property: [v0.posX, v0.posY, v0.inX, v0.inY, v0.outX, v0.outY, ..., closed_flag ] (thus encoding_len == 6 * vertex_count + 1) After we're done with parsing, animation/interpolation is handled via existing VectorKeyframeAnimator - so we can remove KeyframeAnimator<ShapeValue>. Converting to SkPath is pretty much the same as for the previous representation, except the input is now flattened. Change-Id: I822797fceae561b52b709bf258163bbcc6b565fb Reviewed-on: https://skia-review.googlesource.com/c/skia/+/280898 Reviewed-by: Mike Klein <mtklein@google.com> Commit-Queue: Florin Malita <fmalita@chromium.org>
52 lines
1.3 KiB
C++
52 lines
1.3 KiB
C++
/*
|
|
* Copyright 2020 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "modules/skottie/src/Adapter.h"
|
|
#include "modules/skottie/src/SkottieJson.h"
|
|
#include "modules/skottie/src/SkottiePriv.h"
|
|
#include "modules/skottie/src/SkottieValue.h"
|
|
#include "modules/sksg/include/SkSGPath.h"
|
|
|
|
namespace skottie {
|
|
namespace internal {
|
|
|
|
namespace {
|
|
|
|
class PathAdapter final : public DiscardableAdapterBase<PathAdapter, sksg::Path> {
|
|
public:
|
|
PathAdapter(const skjson::Value& jpath, const AnimationBuilder& abuilder)
|
|
: INHERITED(sksg::Path::Make()) {
|
|
this->bind(abuilder, jpath, fShape);
|
|
}
|
|
|
|
private:
|
|
void onSync() override {
|
|
const auto& path_node = this->node();
|
|
|
|
SkPath path = fShape;
|
|
|
|
// FillType is tracked in the SG node, not in keyframes -- make sure we preserve it.
|
|
path.setFillType(path_node->getFillType());
|
|
path.setIsVolatile(!this->isStatic());
|
|
|
|
path_node->setPath(path);
|
|
}
|
|
|
|
ShapeValue fShape;
|
|
|
|
using INHERITED = DiscardableAdapterBase<PathAdapter, sksg::Path>;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
sk_sp<sksg::Path> AnimationBuilder::attachPath(const skjson::Value& jpath) const {
|
|
return this->attachDiscardableAdapter<PathAdapter>(jpath, *this);
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace skottie
|