[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:
parent
44804c030b
commit
7b3415cb10
@ -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) {
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user