[skottie] Split-position support
TBR=
Change-Id: I82433bc9a73f89956c2b25146e1521412d125945
Reviewed-on: https://skia-review.googlesource.com/102622
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/experimental/skottie/SkottieAnimator.cpp b/experimental/skottie/SkottieAnimator.cpp
index 838bf2a..c1e83f7 100644
--- a/experimental/skottie/SkottieAnimator.cpp
+++ b/experimental/skottie/SkottieAnimator.cpp
@@ -279,7 +279,7 @@
static inline bool BindPropertyImpl(const Json::Value& jprop,
sksg::AnimatorList* animators,
std::function<void(const T&)>&& apply,
- const T* noop) {
+ const T* noop = nullptr) {
if (!jprop.isObject())
return false;
@@ -316,6 +316,74 @@
return true;
}
+class SplitPointAnimator final : public sksg::Animator {
+public:
+ static std::unique_ptr<SplitPointAnimator> Make(const Json::Value& jprop,
+ std::function<void(const VectorValue&)>&& apply,
+ const VectorValue*) {
+ if (!jprop.isObject())
+ return nullptr;
+
+ std::unique_ptr<SplitPointAnimator> split_animator(
+ new SplitPointAnimator(std::move(apply)));
+
+ // This raw pointer is captured in lambdas below. But the lambdas are owned by
+ // the object itself, so the scope is bound to the life time of the object.
+ auto* split_animator_ptr = split_animator.get();
+
+ if (!BindPropertyImpl<ScalarValue>(jprop["x"], &split_animator->fAnimators,
+ [split_animator_ptr](const ScalarValue& x) { split_animator_ptr->setX(x); }) ||
+ !BindPropertyImpl<ScalarValue>(jprop["y"], &split_animator->fAnimators,
+ [split_animator_ptr](const ScalarValue& y) { split_animator_ptr->setY(y); })) {
+ LogFail(jprop, "Could not parse split property");
+ return nullptr;
+ }
+
+ if (split_animator->fAnimators.empty()) {
+ // Static split property, no need to hold on to the split animator.
+ return nullptr;
+ }
+
+ return split_animator;
+ }
+
+ void onTick(float t) override {
+ for (const auto& animator : fAnimators) {
+ animator->tick(t);
+ }
+
+ const VectorValue vec = { fX, fY };
+ fApplyFunc(vec);
+ }
+
+ void setX(const ScalarValue& x) { fX = x; }
+ void setY(const ScalarValue& y) { fY = y; }
+
+private:
+ explicit SplitPointAnimator(std::function<void(const VectorValue&)>&& apply)
+ : fApplyFunc(std::move(apply)) {}
+
+ const std::function<void(const VectorValue&)> fApplyFunc;
+ sksg::AnimatorList fAnimators;
+
+ ScalarValue fX = 0,
+ fY = 0;
+
+ using INHERITED = sksg::Animator;
+};
+
+bool BindSplitPositionProperty(const Json::Value& jprop,
+ sksg::AnimatorList* animators,
+ std::function<void(const VectorValue&)>&& apply,
+ const VectorValue* noop) {
+ if (auto split_animator = SplitPointAnimator::Make(jprop, std::move(apply), noop)) {
+ animators->push_back(std::unique_ptr<sksg::Animator>(split_animator.release()));
+ return true;
+ }
+
+ return false;
+}
+
} // namespace
template <>
@@ -331,7 +399,9 @@
sksg::AnimatorList* animators,
std::function<void(const VectorValue&)>&& apply,
const VectorValue* noop) {
- return BindPropertyImpl(jprop, animators, std::move(apply), noop);
+ return ParseDefault(jprop["s"], false)
+ ? BindSplitPositionProperty(jprop, animators, std::move(apply), noop)
+ : BindPropertyImpl(jprop, animators, std::move(apply), noop);
}
template <>