computeAnimFromKeyframes function
Computes the NibAnim at progress t along keyframes.
keyframes is sorted by NibKeyframe.at first if it isn't already.
- If
tis at or before the first keyframe, returns its NibKeyframe.value directly. - If
tis at or after the last keyframe, returns its NibKeyframe.value directly. - Otherwise, finds the two keyframes surrounding
t, normalizestinto that segment, applies the upcoming keyframe's NibKeyframe.curve (ordefaultCurveif unset), and interpolates between the two keyframes' values with NibAnim.lerp.
Implementation
NibAnim computeAnimFromKeyframes(
List<NibKeyframe> keyframes, double t, Curve defaultCurve) {
assert(keyframes.isNotEmpty, 'NibMotion.keyframes must not be empty.');
var sorted = keyframes;
for (var i = 1; i < sorted.length; i++) {
if (sorted[i].at < sorted[i - 1].at) {
sorted = List<NibKeyframe>.of(keyframes)
..sort((a, b) => a.at.compareTo(b.at));
break;
}
}
if (sorted.length == 1) return sorted.first.value;
if (t <= sorted.first.at) return sorted.first.value;
if (t >= sorted.last.at) return sorted.last.value;
var lo = 0;
var hi = sorted.length - 1;
while (hi - lo > 1) {
final mid = (lo + hi) >> 1;
if (sorted[mid].at <= t) {
lo = mid;
} else {
hi = mid;
}
}
final from = sorted[lo];
final to = sorted[hi];
final segmentT = (t - from.at) / (to.at - from.at);
final curvedT = (to.curve ?? defaultCurve).transform(segmentT);
return from.value.lerp(to.value, curvedT);
}