diff options
author | Florin Malita <fmalita@chromium.org> | 2018-01-24 11:17:42 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-01-24 16:37:20 +0000 |
commit | 7b3415cb1031e515e632fba678bcff0024f884b8 (patch) | |
tree | 1e005afb17cc73ad7cc6d2865d5f15e8ebd81793 /experimental | |
parent | 44804c030bc2313966388f53dbf4db9166984d0a (diff) |
[skottie] "hold" keyframe support
TBR=
Change-Id: I5388bc5a5d24b3bbe3962b2da646719e95efe858
Reviewed-on: https://skia-review.googlesource.com/99281
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'experimental')
-rw-r--r-- | experimental/skottie/SkottieAnimator.cpp | 30 | ||||
-rw-r--r-- | experimental/skottie/SkottieAnimator.h | 24 |
2 files changed, 39 insertions, 15 deletions
diff --git a/experimental/skottie/SkottieAnimator.cpp b/experimental/skottie/SkottieAnimator.cpp index 6568d1b183..da00beb2fe 100644 --- a/experimental/skottie/SkottieAnimator.cpp +++ b/experimental/skottie/SkottieAnimator.cpp @@ -48,16 +48,20 @@ bool KeyframeIntervalBase::parse(const Json::Value& k, KeyframeIntervalBase* pre prev->fT1 = fT0; } - // default is linear lerp - static constexpr SkPoint kDefaultC0 = { 0, 0 }, - kDefaultC1 = { 1, 1 }; - const auto c0 = ParsePoint(k["i"], kDefaultC0), - c1 = ParsePoint(k["o"], kDefaultC1); - - if (c0 != kDefaultC0 || c1 != kDefaultC1) { - fCubicMap = skstd::make_unique<SkCubicMap>(); - // TODO: why do we have to plug these inverted? - fCubicMap->setPts(c1, c0); + fHold = ParseBool(k["h"], false); + + if (!fHold) { + // default is linear lerp + static constexpr SkPoint kDefaultC0 = { 0, 0 }, + kDefaultC1 = { 1, 1 }; + const auto c0 = ParsePoint(k["i"], kDefaultC0), + c1 = ParsePoint(k["o"], kDefaultC1); + + if (c0 != kDefaultC0 || c1 != kDefaultC1) { + fCubicMap = skstd::make_unique<SkCubicMap>(); + // TODO: why do we have to plug these inverted? + fCubicMap->setPts(c1, c0); + } } return true; @@ -65,6 +69,12 @@ bool KeyframeIntervalBase::parse(const Json::Value& k, KeyframeIntervalBase* pre float KeyframeIntervalBase::localT(float t) const { SkASSERT(this->isValid()); + + // 'hold' pins to v0 + if (fHold) { + return 0; + } + auto lt = (t - fT0) / (fT1 - fT0); if (fCubicMap) { diff --git a/experimental/skottie/SkottieAnimator.h b/experimental/skottie/SkottieAnimator.h index 4ab877ecaf..c03449d11a 100644 --- a/experimental/skottie/SkottieAnimator.h +++ b/experimental/skottie/SkottieAnimator.h @@ -29,7 +29,7 @@ public: float t0() const { return fT0; } float t1() const { return fT1; } - bool isValid() const { return fT0 < fT1; } + bool isValid() const { return fT0 < fT1 || fHold; } bool contains(float t) const { return t >= fT0 && t <= fT1; } protected: @@ -40,6 +40,8 @@ protected: // through the cubic (if applicable). float localT(float t) const; + bool isHold() const { return fHold; } + private: // Initialized for non-linear interpolation. std::unique_ptr<SkCubicMap> fCubicMap; @@ -47,6 +49,8 @@ private: // Start/end times. float fT0 = 0, fT1 = 0; + + bool fHold = false; }; // Describes a keyframe interpolation interval (v0@t0) -> (v1@t1). @@ -56,10 +60,20 @@ public: bool parse(const Json::Value& k, KeyframeInterval* prev) { SkASSERT(k.isObject()); - return this->INHERITED::parse(k, prev) && - ValueTraits<T>::Parse(k["s"], &fV0) && - ValueTraits<T>::Parse(k["e"], &fV1) && - ValueTraits<T>::Cardinality(fV0) == ValueTraits<T>::Cardinality(fV1) && + if (!this->INHERITED::parse(k, prev) || + !ValueTraits<T>::Parse(k["s"], &fV0)) { + return false; + } + + if (this->isHold()) { + // Hold v1 == v0. + fV1 = fV0; + } else if (!ValueTraits<T>::Parse(k["e"], &fV1)) { + return false; + } + + + return ValueTraits<T>::Cardinality(fV0) == ValueTraits<T>::Cardinality(fV1) && (!prev || ValueTraits<T>::Cardinality(fV0) == ValueTraits<T>::Cardinality(prev->fV0)); } |