Create VectorExpressionAnimator
Change-Id: I9ac04e316fd5cc21f9400ff56cf6bc6db77ca046 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/444871 Commit-Queue: Avinash Parchuri <aparchur@google.com> Reviewed-by: Avinash Parchuri <aparchur@google.com> Reviewed-by: Florin Malita <fmalita@google.com>
This commit is contained in:
parent
907c593fad
commit
0bfac0127c
@ -54,12 +54,16 @@ bool AnimatablePropertyContainer::bindImpl(const AnimationBuilder& abuilder,
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& jpropA = (*jprop)["a"];
|
||||
const auto& jpropK = (*jprop)["k"];
|
||||
|
||||
// Handle expressions on the property.
|
||||
if (const skjson::StringValue* expr = (*jprop)["x"]) {
|
||||
if (!abuilder.expression_manager()) {
|
||||
abuilder.log(Logger::Level::kWarning, jprop,
|
||||
"Expression encountered but ExpressionManager not provided.");
|
||||
} else {
|
||||
builder.parseValue(abuilder, jpropK);
|
||||
sk_sp<Animator> expression_animator = builder.makeFromExpression(
|
||||
*abuilder.expression_manager(),
|
||||
expr->begin());
|
||||
@ -70,9 +74,6 @@ bool AnimatablePropertyContainer::bindImpl(const AnimationBuilder& abuilder,
|
||||
}
|
||||
}
|
||||
|
||||
const auto& jpropA = (*jprop)["a"];
|
||||
const auto& jpropK = (*jprop)["k"];
|
||||
|
||||
// Older Json versions don't have an "a" animation marker.
|
||||
// For those, we attempt to parse both ways.
|
||||
if (!ParseDefault<bool>(jpropA, false)) {
|
||||
|
@ -142,6 +142,33 @@ private:
|
||||
using INHERITED = KeyframeAnimator;
|
||||
};
|
||||
|
||||
class VectorExpressionAnimator final : public Animator {
|
||||
public:
|
||||
VectorExpressionAnimator(sk_sp<ExpressionEvaluator<std::vector<float>>> expression_evaluator,
|
||||
std::vector<float>* target_value)
|
||||
: fExpressionEvaluator(std::move(expression_evaluator))
|
||||
, fTarget(target_value) {}
|
||||
|
||||
private:
|
||||
|
||||
StateChanged onSeek(float t) override {
|
||||
std::vector<float> result = fExpressionEvaluator->evaluate(t);
|
||||
bool changed = false;
|
||||
for (size_t i = 0; i < fTarget->size(); i++) {
|
||||
// Use 0 as a default if the result is too small.
|
||||
float val = i >= result.size() ? 0 : result[i];
|
||||
if (!SkScalarNearlyEqual(val, (*fTarget)[i])) {
|
||||
changed = true;
|
||||
}
|
||||
(*fTarget)[i] = val;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
sk_sp<ExpressionEvaluator<std::vector<float>>> fExpressionEvaluator;
|
||||
std::vector<float>* fTarget;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
VectorAnimatorBuilder::VectorAnimatorBuilder(std::vector<float>* target,
|
||||
@ -189,8 +216,10 @@ sk_sp<KeyframeAnimator> VectorAnimatorBuilder::makeFromKeyframes(const Animation
|
||||
fTarget));
|
||||
}
|
||||
|
||||
sk_sp<Animator> VectorAnimatorBuilder::makeFromExpression(ExpressionManager&, const char*) {
|
||||
return nullptr;
|
||||
sk_sp<Animator> VectorAnimatorBuilder::makeFromExpression(ExpressionManager& em, const char* expr) {
|
||||
sk_sp<ExpressionEvaluator<std::vector<SkScalar>>> expression_evaluator =
|
||||
em.createArrayExpressionEvaluator(expr);
|
||||
return sk_make_sp<VectorExpressionAnimator>(expression_evaluator, fTarget);
|
||||
}
|
||||
|
||||
bool VectorAnimatorBuilder::parseValue(const AnimationBuilder&,
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
class FakeVectorExpressionEvaluator : public ExpressionEvaluator<std::vector<float>> {
|
||||
public:
|
||||
std::vector<float> evaluate(float t) override {
|
||||
return {1.0f, 2.0f};
|
||||
return {0.1f, 0.2f, 0.3f, 1.0f};
|
||||
}
|
||||
};
|
||||
|
||||
@ -59,12 +59,18 @@ class FakePropertyObserver : public PropertyObserver {
|
||||
transform_handle_.reset(transform_handle().release());
|
||||
}
|
||||
|
||||
void onColorProperty(const char node_name[],
|
||||
const LazyHandle<ColorPropertyHandle>& color_handle) override {
|
||||
color_handle_.reset(color_handle().release());
|
||||
}
|
||||
|
||||
std::unique_ptr<OpacityPropertyHandle> opacity_handle_;
|
||||
std::unique_ptr<TransformPropertyHandle> transform_handle_;
|
||||
std::unique_ptr<ColorPropertyHandle> color_handle_;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
DEF_TEST(Skottie_ScalarExpression, r) {
|
||||
DEF_TEST(Skottie_Expression, r) {
|
||||
static constexpr char json[] =
|
||||
R"({
|
||||
"v": "5.2.1",
|
||||
@ -124,10 +130,105 @@ DEF_TEST(Skottie_ScalarExpression, r) {
|
||||
"l": 2
|
||||
}
|
||||
},
|
||||
"ef": [
|
||||
{
|
||||
"ty": 21,
|
||||
"nm": "Fill",
|
||||
"np": 9,
|
||||
"mn": "ADBE Fill",
|
||||
"ix": 1,
|
||||
"en": 1,
|
||||
"ef": [
|
||||
{
|
||||
"ty": 10,
|
||||
"nm": "Fill Mask",
|
||||
"mn": "ADBE Fill-0001",
|
||||
"ix": 1,
|
||||
"v": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ty": 7,
|
||||
"nm": "All Masks",
|
||||
"mn": "ADBE Fill-0007",
|
||||
"ix": 2,
|
||||
"v": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"ty": 2,
|
||||
"nm": "Color",
|
||||
"mn": "ADBE Fill-0002",
|
||||
"ix": 3,
|
||||
"v": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"ix": 3,
|
||||
"x": "fake; return value is specified by the FakeArrayExpressionEvaluator."
|
||||
}
|
||||
},
|
||||
{
|
||||
"ty": 7,
|
||||
"nm": "Invert",
|
||||
"mn": "ADBE Fill-0006",
|
||||
"ix": 4,
|
||||
"v": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"ty": 0,
|
||||
"nm": "Horizontal Feather",
|
||||
"mn": "ADBE Fill-0003",
|
||||
"ix": 5,
|
||||
"v": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"ty": 0,
|
||||
"nm": "Vertical Feather",
|
||||
"mn": "ADBE Fill-0004",
|
||||
"ix": 6,
|
||||
"v": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"ty": 0,
|
||||
"nm": "Opacity",
|
||||
"mn": "ADBE Fill-0005",
|
||||
"ix": 7,
|
||||
"v": {
|
||||
"a": 0,
|
||||
"k": 1,
|
||||
"ix": 7
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"ao": 0,
|
||||
"sw": 100,
|
||||
"sh": 100,
|
||||
"sc": "#51251d",
|
||||
"sc": "#000000",
|
||||
"st": 0,
|
||||
"bm": 0
|
||||
}
|
||||
@ -150,6 +251,7 @@ DEF_TEST(Skottie_ScalarExpression, r) {
|
||||
|
||||
REPORTER_ASSERT(r, SkScalarNearlyEqual(observer->opacity_handle_->get(), 7.0f));
|
||||
SkPoint anchor_point = observer->transform_handle_->get().fAnchorPoint;
|
||||
REPORTER_ASSERT(r, SkScalarNearlyEqual(anchor_point.fX, 1.0f));
|
||||
REPORTER_ASSERT(r, SkScalarNearlyEqual(anchor_point.fY, 2.0f));
|
||||
REPORTER_ASSERT(r, SkScalarNearlyEqual(anchor_point.fX, 0.1f));
|
||||
REPORTER_ASSERT(r, SkScalarNearlyEqual(anchor_point.fY, 0.2f));
|
||||
REPORTER_ASSERT(r, (observer->color_handle_->get() == SkColor4f{0.1f, 0.2f, 0.3f, 1.0f}.toSkColor()));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user