blob: 8fb1ad1fe873973bcc2889a30b08103da4f4bad5 [file] [log] [blame]
/*
* Copyright 2020 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "modules/skottie/src/SkottieJson.h"
#include "modules/skottie/src/SkottieValue.h"
#include "modules/skottie/src/animator/KeyframeAnimator.h"
#include "modules/skottie/src/text/TextValue.h"
namespace skottie::internal {
namespace {
class TextKeyframeAnimator final : public KeyframeAnimator {
public:
class Builder final : public KeyframeAnimatorBuilder {
public:
explicit Builder(TextValue* target) : fTarget(target) {}
sk_sp<KeyframeAnimator> make(const AnimationBuilder& abuilder,
const skjson::ArrayValue& jkfs) override {
SkASSERT(jkfs.size() > 0);
fValues.reserve(jkfs.size());
if (!this->parseKeyframes(abuilder, jkfs)) {
return nullptr;
}
fValues.shrink_to_fit();
return sk_sp<TextKeyframeAnimator>(
new TextKeyframeAnimator(std::move(fKFs),
std::move(fCMs),
std::move(fValues),
fTarget));
}
bool parseValue(const AnimationBuilder& abuilder, const skjson::Value& jv) const override {
return Parse(jv, abuilder, fTarget);
}
private:
bool parseKFValue(const AnimationBuilder& abuilder,
const skjson::ObjectValue&,
const skjson::Value& jv,
Keyframe::Value* v) override {
TextValue val;
if (!Parse(jv, abuilder, &val)) {
return false;
}
// TODO: full deduping?
if (fValues.empty() || val != fValues.back()) {
fValues.push_back(std::move(val));
}
v->idx = SkToU32(fValues.size() - 1);
return true;
}
std::vector<TextValue> fValues;
TextValue* fTarget;
};
private:
TextKeyframeAnimator(std::vector<Keyframe> kfs, std::vector<SkCubicMap> cms,
std::vector<TextValue> vs, TextValue* target_value)
: INHERITED(std::move(kfs), std::move(cms))
, fValues(std::move(vs))
, fTarget(target_value) {}
StateChanged onSeek(float t) override {
const auto& lerp_info = this->getLERPInfo(t);
// Text value keyframes are treated as selectors, not as interpolated values.
if (*fTarget != fValues[SkToSizeT(lerp_info.vrec0.idx)]) {
*fTarget = fValues[SkToSizeT(lerp_info.vrec0.idx)];
return true;
}
return false;
}
const std::vector<TextValue> fValues;
TextValue* fTarget;
using INHERITED = KeyframeAnimator;
};
} // namespace
template <>
bool AnimatablePropertyContainer::bind<TextValue>(const AnimationBuilder& abuilder,
const skjson::ObjectValue* jprop,
TextValue* v) {
TextKeyframeAnimator::Builder builder(v);
return this->bindImpl(abuilder, jprop, builder);
}
} // namespace skottie::internal