loader/lottie: support hold interpolation.

This commit is contained in:
Hermet Park 2023-09-02 15:52:52 +09:00
parent aa0ca8dc78
commit ac8f3b8be6
2 changed files with 15 additions and 1 deletions

View file

@ -384,7 +384,7 @@ void LottieParser::parseKeyFrame(T& prop)
Point inTangent, outTangent; Point inTangent, outTangent;
const char* interpolatorKey = nullptr; const char* interpolatorKey = nullptr;
auto& frame = prop.newFrame(); auto& frame = prop.newFrame();
bool interpolator = false; auto interpolator = false;
enterObject(); enterObject();
@ -415,6 +415,8 @@ void LottieParser::parseKeyFrame(T& prop)
getValue(frame2.value); getValue(frame2.value);
} else if (parseTangent(key, frame)) { } else if (parseTangent(key, frame)) {
continue; continue;
} else if (!strcmp(key, "h")) {
frame.hold = getInt();
} else skip(key); } else skip(key);
} }

View file

@ -94,11 +94,17 @@ struct LottieScalarFrame
T value; //keyframe value T value; //keyframe value
int32_t no; //frame number int32_t no; //frame number
LottieInterpolator* interpolator; LottieInterpolator* interpolator;
bool hold = false; //do not interpolate.
T interpolate(LottieScalarFrame<T>* next, int32_t frameNo) T interpolate(LottieScalarFrame<T>* next, int32_t frameNo)
{ {
auto t = float(frameNo - no) / float(next->no - no); auto t = float(frameNo - no) / float(next->no - no);
if (interpolator) t = interpolator->progress(t); if (interpolator) t = interpolator->progress(t);
if (hold) {
if (t < 1.0f) return value;
else return next->value;
}
return mathLerp(value, next->value, t); return mathLerp(value, next->value, t);
} }
}; };
@ -113,12 +119,18 @@ struct LottieVectorFrame
T outTangent, inTangent; T outTangent, inTangent;
float length; float length;
bool hasTangent = false; bool hasTangent = false;
bool hold = false;
T interpolate(LottieVectorFrame* next, int32_t frameNo) T interpolate(LottieVectorFrame* next, int32_t frameNo)
{ {
auto t = float(frameNo - no) / float(next->no - no); auto t = float(frameNo - no) / float(next->no - no);
if (interpolator) t = interpolator->progress(t); if (interpolator) t = interpolator->progress(t);
if (hold) {
if (t < 1.0f) return value;
else return next->value;
}
if (hasTangent) { if (hasTangent) {
Bezier bz = {value, value + outTangent, next->value + inTangent, next->value}; Bezier bz = {value, value + outTangent, next->value + inTangent, next->value};
t = bezAt(bz, t * length, length); t = bezAt(bz, t * length, length);