1 /*
2 * Copyright 2020 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "modules/skottie/src/SkottieJson.h"
9 #include "modules/skottie/src/SkottieValue.h"
10 #include "modules/skottie/src/animator/Animator.h"
11 #include "modules/skottie/src/animator/KeyframeAnimator.h"
12
13 namespace skottie::internal {
14
15 namespace {
16
17 // Scalar specialization: stores scalar values (floats) inline in keyframes.
18 class ScalarKeyframeAnimator final : public KeyframeAnimator {
19 public:
ScalarKeyframeAnimator(std::vector<Keyframe> kfs,std::vector<SkCubicMap> cms,ScalarValue * target_value)20 ScalarKeyframeAnimator(std::vector<Keyframe> kfs,
21 std::vector<SkCubicMap> cms,
22 ScalarValue* target_value)
23 : INHERITED(std::move(kfs), std::move(cms))
24 , fTarget(target_value) {}
25
26 private:
27
onSeek(float t)28 StateChanged onSeek(float t) override {
29 const auto& lerp_info = this->getLERPInfo(t);
30 const auto old_value = *fTarget;
31
32 *fTarget = Lerp(lerp_info.vrec0.flt, lerp_info.vrec1.flt, lerp_info.weight);
33
34 return *fTarget != old_value;
35 }
36
37 ScalarValue* fTarget;
38
39 using INHERITED = KeyframeAnimator;
40 };
41
42 // Scalar specialization: stores scalar values (floats).
43 class ScalarExpressionAnimator final : public Animator {
44 public:
ScalarExpressionAnimator(sk_sp<ExpressionEvaluator<ScalarValue>> expression_evaluator,ScalarValue * target_value)45 ScalarExpressionAnimator(sk_sp<ExpressionEvaluator<ScalarValue>> expression_evaluator,
46 ScalarValue* target_value)
47 : fExpressionEvaluator(std::move(expression_evaluator))
48 , fTarget(target_value) {}
49
50 private:
51
onSeek(float t)52 StateChanged onSeek(float t) override {
53 auto old_value = *fTarget;
54
55 *fTarget = fExpressionEvaluator->evaluate(t);
56
57 return *fTarget != old_value;
58 }
59
60 sk_sp<ExpressionEvaluator<ScalarValue>> fExpressionEvaluator;
61 ScalarValue* fTarget;
62 };
63
64 class ScalarAnimatorBuilder final : public AnimatorBuilder {
65 public:
ScalarAnimatorBuilder(ScalarValue * target)66 explicit ScalarAnimatorBuilder(ScalarValue* target)
67 : INHERITED(Keyframe::Value::Type::kScalar)
68 , fTarget(target) {}
69
makeFromKeyframes(const AnimationBuilder & abuilder,const skjson::ArrayValue & jkfs)70 sk_sp<KeyframeAnimator> makeFromKeyframes(const AnimationBuilder& abuilder,
71 const skjson::ArrayValue& jkfs) override {
72 SkASSERT(jkfs.size() > 0);
73 if (!this->parseKeyframes(abuilder, jkfs)) {
74 return nullptr;
75 }
76
77 return sk_sp<ScalarKeyframeAnimator>(
78 new ScalarKeyframeAnimator(std::move(fKFs), std::move(fCMs), fTarget));
79 }
80
makeFromExpression(ExpressionManager & em,const char * expr)81 sk_sp<Animator> makeFromExpression(ExpressionManager& em, const char* expr) override {
82 sk_sp<ExpressionEvaluator<ScalarValue>> expression_evaluator =
83 em.createNumberExpressionEvaluator(expr);
84 return sk_make_sp<ScalarExpressionAnimator>(expression_evaluator, fTarget);
85 }
86
87
parseValue(const AnimationBuilder &,const skjson::Value & jv) const88 bool parseValue(const AnimationBuilder&, const skjson::Value& jv) const override {
89 return Parse(jv, fTarget);
90 }
91
92 private:
parseKFValue(const AnimationBuilder &,const skjson::ObjectValue &,const skjson::Value & jv,Keyframe::Value * v)93 bool parseKFValue(const AnimationBuilder&,
94 const skjson::ObjectValue&,
95 const skjson::Value& jv,
96 Keyframe::Value* v) override {
97 return Parse(jv, &v->flt);
98 }
99
100 ScalarValue* fTarget;
101
102 using INHERITED = AnimatorBuilder;
103 };
104
105 } // namespace
106
107 template <>
bind(const AnimationBuilder & abuilder,const skjson::ObjectValue * jprop,ScalarValue * v)108 bool AnimatablePropertyContainer::bind<ScalarValue>(const AnimationBuilder& abuilder,
109 const skjson::ObjectValue* jprop,
110 ScalarValue* v) {
111 ScalarAnimatorBuilder builder(v);
112
113 return this->bindImpl(abuilder, jprop, builder);
114 }
115
116 } // namespace skottie::internal
117