Flutter Engine
The Flutter Engine
ScalarKeyframeAnimator.cpp
Go to the documentation of this file.
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
19#include "src/utils/SkJSON.h"
20
21#include <utility>
22#include <vector>
23
24namespace skottie::internal {
25
26namespace {
27
28 // Scalar specialization: stores scalar values (floats) inline in keyframes.
29class ScalarKeyframeAnimator final : public KeyframeAnimator {
30public:
31 ScalarKeyframeAnimator(std::vector<Keyframe> kfs,
32 std::vector<SkCubicMap> cms,
33 ScalarValue* target_value)
34 : INHERITED(std::move(kfs), std::move(cms))
35 , fTarget(target_value) {}
36
37private:
38
39 StateChanged onSeek(float t) override {
40 const auto& lerp_info = this->getLERPInfo(t);
41 const auto old_value = *fTarget;
42
43 *fTarget = Lerp(lerp_info.vrec0.flt, lerp_info.vrec1.flt, lerp_info.weight);
44
45 return *fTarget != old_value;
46 }
47
48 ScalarValue* fTarget;
49
50 using INHERITED = KeyframeAnimator;
51};
52
53 // Scalar specialization: stores scalar values (floats).
54class ScalarExpressionAnimator final : public Animator {
55public:
56 ScalarExpressionAnimator(sk_sp<ExpressionEvaluator<ScalarValue>> expression_evaluator,
57 ScalarValue* target_value)
58 : fExpressionEvaluator(std::move(expression_evaluator))
59 , fTarget(target_value) {}
60
61private:
62
63 StateChanged onSeek(float t) override {
64 auto old_value = *fTarget;
65
66 *fTarget = fExpressionEvaluator->evaluate(t);
67
68 return *fTarget != old_value;
69 }
70
71 sk_sp<ExpressionEvaluator<ScalarValue>> fExpressionEvaluator;
72 ScalarValue* fTarget;
73};
74
75class ScalarAnimatorBuilder final : public AnimatorBuilder {
76 public:
77 explicit ScalarAnimatorBuilder(ScalarValue* target)
78 : INHERITED(Keyframe::Value::Type::kScalar)
79 , fTarget(target) {}
80
81 sk_sp<KeyframeAnimator> makeFromKeyframes(const AnimationBuilder& abuilder,
82 const skjson::ArrayValue& jkfs) override {
83 SkASSERT(jkfs.size() > 0);
84 if (!this->parseKeyframes(abuilder, jkfs)) {
85 return nullptr;
86 }
87
89 new ScalarKeyframeAnimator(std::move(fKFs), std::move(fCMs), fTarget));
90 }
91
92 sk_sp<Animator> makeFromExpression(ExpressionManager& em, const char* expr) override {
93 sk_sp<ExpressionEvaluator<ScalarValue>> expression_evaluator =
94 em.createNumberExpressionEvaluator(expr);
95 return sk_make_sp<ScalarExpressionAnimator>(expression_evaluator, fTarget);
96 }
97
98
99 bool parseValue(const AnimationBuilder&, const skjson::Value& jv) const override {
100 return ::skottie::Parse(jv, fTarget);
101 }
102
103 private:
104 bool parseKFValue(const AnimationBuilder&,
105 const skjson::ObjectValue&,
106 const skjson::Value& jv,
107 Keyframe::Value* v) override {
108 return ::skottie::Parse(jv, &v->flt);
109 }
110
111 ScalarValue* fTarget;
112
113 using INHERITED = AnimatorBuilder;
114 };
115
116} // namespace
117
118template <>
119bool AnimatablePropertyContainer::bind<ScalarValue>(const AnimationBuilder& abuilder,
120 const skjson::ObjectValue* jprop,
121 ScalarValue* v) {
122 if (const auto* sid = ParseSlotID(jprop)) {
123 fHasSlotID = true;
124 abuilder.fSlotManager->trackScalarValue(SkString(sid->begin()), v, sk_ref_sp(this));
125 }
126 ScalarAnimatorBuilder builder(v);
127
128 return this->bindImpl(abuilder, jprop, builder);
129}
130
131} // namespace skottie::internal
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define INHERITED(method,...)
Definition: SkRecorder.cpp:128
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
size_t size() const
Definition: SkJSON.h:262
uint32_t * target
void SK_API Parse(Metadata &metadata, const SkData *data)
Definition: SkExif.cpp:182
T Lerp(const T &a, const T &b, float t)
SkScalar ScalarValue
Definition: SkottieValue.h:22
const skjson::StringValue * ParseSlotID(const skjson::ObjectValue *jobj)
Definition: ref_ptr.h:256