Flutter Engine
The Flutter Engine
KeyframeAnimator.h
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
8#ifndef SkottieKeyframeAnimator_DEFINED
9#define SkottieKeyframeAnimator_DEFINED
10
17
18#include <cstdint>
19#include <utility>
20#include <vector>
21
22namespace skjson {
23class ArrayValue;
24class ObjectValue;
25class Value;
26} // namespace skjson
27
28namespace skottie {
29class ExpressionManager;
30}
31
32namespace skottie::internal {
33
34class AnimationBuilder;
35
36struct Keyframe {
37 // We can store scalar values inline; other types are stored externally,
38 // and we track them by index.
39 struct Value {
40 enum class Type {
41 kIndex,
42 kScalar,
43 };
44
45 union {
46 uint32_t idx;
47 float flt;
48 };
49
50 bool equals(const Value& other, Type ty) const {
51 return ty == Type::kIndex
52 ? idx == other.idx
53 : flt == other.flt;
54 }
55 };
56
57 float t;
59 uint32_t mapping; // Encodes the value interpolation in [KFRec_n .. KFRec_n+1):
60 // 0 -> constant
61 // 1 -> linear
62 // n -> cubic: cubic_mappers[n-2]
63
64 inline static constexpr uint32_t kConstantMapping = 0;
65 inline static constexpr uint32_t kLinearMapping = 1;
66 inline static constexpr uint32_t kCubicIndexOffset = 2;
67};
68
69class KeyframeAnimator : public Animator {
70public:
72
73 bool isConstant() const {
74 SkASSERT(!fKFs.empty());
75
76 // parseKeyFrames() ensures we only keep a single frame for constant properties.
77 return fKFs.size() == 1;
78 }
79
80protected:
81 KeyframeAnimator(std::vector<Keyframe> kfs, std::vector<SkCubicMap> cms)
82 : fKFs(std::move(kfs))
83 , fCMs(std::move(cms)) {}
84
85 struct LERPInfo {
86 float weight; // vrec0/vrec1 weight [0..1]
88 };
89
90 // Main entry point: |t| -> LERPInfo
91 LERPInfo getLERPInfo(float t) const;
92
93private:
94 // Two sequential KFRecs determine how the value varies within [kf0 .. kf1)
95 struct KFSegment {
96 const Keyframe* kf0;
97 const Keyframe* kf1;
98
99 bool contains(float t) const {
100 SkASSERT(!!kf0 == !!kf1);
101 SkASSERT(!kf0 || kf1 == kf0 + 1);
102
103 return kf0 && kf0->t <= t && t < kf1->t;
104 }
105 };
106
107 // Find the KFSegment containing |t|.
108 KFSegment find_segment(float t) const;
109
110 // Given a |t| and a containing KFSegment, compute the local interpolation weight.
111 float compute_weight(const KFSegment& seg, float t) const;
112
113 const std::vector<Keyframe> fKFs; // Keyframe records, one per AE/Lottie keyframe.
114 const std::vector<SkCubicMap> fCMs; // Optional cubic mappers (Bezier interpolation).
115 mutable KFSegment fCurrentSegment = { nullptr, nullptr }; // Cached segment.
116};
117
119public:
121
123 const skjson::ArrayValue&) = 0;
124
126
127 virtual bool parseValue(const AnimationBuilder&, const skjson::Value&) const = 0;
128
129protected:
131 : keyframe_type(ty) {}
132
133 virtual bool parseKFValue(const AnimationBuilder&,
134 const skjson::ObjectValue&,
135 const skjson::Value&,
136 Keyframe::Value*) = 0;
137
139
140 std::vector<Keyframe> fKFs; // Keyframe records, one per AE/Lottie keyframe.
141 std::vector<SkCubicMap> fCMs; // Optional cubic mappers (Bezier interpolation).
142
143private:
144 uint32_t parseMapping(const skjson::ObjectValue&);
145
146 const Keyframe::Value::Type keyframe_type;
147
148 // Track previous cubic map parameters (for deduping).
149 SkPoint prev_c0 = { 0, 0 },
150 prev_c1 = { 0, 0 };
151};
152
153template <typename T>
154T Lerp(const T& a, const T& b, float t) { return a + (b - a) * t; }
155
156} // namespace skottie::internal
157
158#endif // SkottieKeyframeAnimator_DEFINED
#define SkASSERT(cond)
Definition: SkAssert.h:116
virtual sk_sp< Animator > makeFromExpression(ExpressionManager &, const char *)=0
virtual bool parseValue(const AnimationBuilder &, const skjson::Value &) const =0
std::vector< SkCubicMap > fCMs
AnimatorBuilder(Keyframe::Value::Type ty)
bool parseKeyframes(const AnimationBuilder &, const skjson::ArrayValue &)
virtual bool parseKFValue(const AnimationBuilder &, const skjson::ObjectValue &, const skjson::Value &, Keyframe::Value *)=0
virtual sk_sp< KeyframeAnimator > makeFromKeyframes(const AnimationBuilder &, const skjson::ArrayValue &)=0
KeyframeAnimator(std::vector< Keyframe > kfs, std::vector< SkCubicMap > cms)
static bool b
struct MyStruct a[10]
T Lerp(const T &a, const T &b, float t)
constexpr bool contains(std::string_view str, std::string_view needle)
Definition: SkStringView.h:41
Definition: ref_ptr.h:256
#define T
Definition: precompiler.cc:65
bool equals(const Value &other, Type ty) const
static constexpr uint32_t kConstantMapping
static constexpr uint32_t kCubicIndexOffset
static constexpr uint32_t kLinearMapping