aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2018-01-24 11:17:42 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-24 16:37:20 +0000
commit7b3415cb1031e515e632fba678bcff0024f884b8 (patch)
tree1e005afb17cc73ad7cc6d2865d5f15e8ebd81793 /experimental
parent44804c030bc2313966388f53dbf4db9166984d0a (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.cpp30
-rw-r--r--experimental/skottie/SkottieAnimator.h24
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));
}