Flutter Engine
The Flutter Engine
Animator.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
9
14#include "src/utils/SkJSON.h"
15
16#include <utility>
17
18namespace skottie::internal {
19
20Animator::StateChanged AnimatablePropertyContainer::onSeek(float t) {
21 // The very first seek must trigger a sync, to ensure proper SG setup.
22 bool changed = !fHasSynced;
23
24 for (const auto& animator : fAnimators) {
25 changed |= animator->seek(t);
26 }
27
28 if (changed) {
29 this->onSync();
30 fHasSynced = true;
31 }
32
33 return changed;
34}
35
38 if (!child) {
39 return;
40 }
41
42 if (child->isStatic()) {
43 child->seek(0);
44 return;
45 }
46
47 fAnimators.push_back(std::move(child));
48}
49
51 fAnimators.shrink_to_fit();
52}
53
54bool AnimatablePropertyContainer::bindImpl(const AnimationBuilder& abuilder,
55 const skjson::ObjectValue* jprop,
57 if (!jprop) {
58 return false;
59 }
60
61 if (const skjson::StringValue* jpropSlotID = (*jprop)["sid"] ) {
62 if (!abuilder.getSlotsRoot()) {
63 abuilder.log(Logger::Level::kWarning, jprop,
64 "Slotid found but no slots were found in the json. Using default values.");
65 } else {
66 const skjson::ObjectValue* slot = (*(abuilder.getSlotsRoot()))[jpropSlotID->begin()];
67 if (!slot) {
68 abuilder.log(Logger::Level::kWarning, jprop,
69 "Specified slotID not found in 'slots'. Using default values.");
70 } else {
71 jprop = (*slot)["p"];
72 }
73 }
74 }
75
76 const auto& jpropA = (*jprop)["a"];
77 const auto& jpropK = (*jprop)["k"];
78
79 // Handle expressions on the property.
80 if (const skjson::StringValue* expr = (*jprop)["x"]) {
81 if (!abuilder.expression_manager()) {
82 abuilder.log(Logger::Level::kWarning, jprop,
83 "Expression encountered but ExpressionManager not provided.");
84 } else {
85 builder.parseValue(abuilder, jpropK);
86 sk_sp<Animator> expression_animator = builder.makeFromExpression(
87 *abuilder.expression_manager(),
88 expr->begin());
89 if (expression_animator) {
90 fAnimators.push_back(std::move(expression_animator));
91 return true;
92 }
93 }
94 }
95
96 // Older Json versions don't have an "a" animation marker.
97 // For those, we attempt to parse both ways.
98 if (!ParseDefault<bool>(jpropA, false)) {
99 if (builder.parseValue(abuilder, jpropK)) {
100 // Static property.
101 return true;
102 }
103
104 if (!jpropA.is<skjson::NullValue>()) {
105 abuilder.log(Logger::Level::kError, jprop,
106 "Could not parse (explicit) static property.");
107 return false;
108 }
109 }
110
111 // Keyframed property.
113 const skjson::ArrayValue* jkfs = jpropK;
114 if (jkfs && jkfs->size() > 0) {
115 animator = builder.makeFromKeyframes(abuilder, *jkfs);
116 }
117
118 if (!animator) {
119 abuilder.log(Logger::Level::kError, jprop, "Could not parse keyframed property.");
120 return false;
121 }
122
123 if (animator->isConstant()) {
124 // If all keyframes are constant, there is no reason to treat this
125 // as an animated property - apply immediately and discard the animator.
126 animator->seek(0);
127 } else {
128 fAnimators.push_back(std::move(animator));
129 }
130
131 return true;
132}
133
134} // namespace skottie::internal
size_t size() const
Definition: SkJSON.h:262
void attachDiscardableAdapter(sk_sp< AnimatablePropertyContainer >)
Definition: Animator.cpp:36
const skjson::ObjectValue * getSlotsRoot() const
Definition: SkottiePriv.h:197
sk_sp< ExpressionManager > expression_manager() const
Definition: Skottie.cpp:292
void log(Logger::Level, const skjson::Value *, const char fmt[],...) const SK_PRINTF_LIKE(4
Definition: Skottie.cpp:71