[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>
This commit is contained in:
Florin Malita 2018-01-24 11:17:42 -05:00 committed by Skia Commit-Bot
parent 44804c030b
commit 7b3415cb10
2 changed files with 38 additions and 14 deletions

View File

@ -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);
fHold = ParseBool(k["h"], false);
if (c0 != kDefaultC0 || c1 != kDefaultC1) {
fCubicMap = skstd::make_unique<SkCubicMap>();
// TODO: why do we have to plug these inverted?
fCubicMap->setPts(c1, c0);
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) {

View File

@ -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));
}