just-animate
Version:
_Making Animation Simple_
48 lines (47 loc) • 1.59 kB
JavaScript
import { cssFunction } from 'just-curves';
import { isNumber, isFunction } from '../utils/inspect';
import { memoize } from '../utils/functional';
import { all } from '../utils/lists';
function findEndIndex(ns, n) {
const ilen = ns.length;
for (let i = 0; i < ilen; i++) {
if (ns[i] > n) {
return i;
}
}
return ilen - 1;
}
const getEasing = memoize(cssFunction);
const getInterpolator = memoize((fn) => memoize(fn));
export function interpolate(l, r, o) {
return l + (r - l) * o;
}
function fallbackInterpolator(l, r, o) {
return o < 0.5 ? l : r;
}
export function interpolator(duration, keyframes) {
const times = keyframes.map(k => k.offset * duration);
all(keyframes, k => {
const isSimple = !isFunction(k.interpolate);
k.simpleFn = isSimple;
k.interpolate = !isSimple
? getInterpolator(k.interpolate)
: isNumber(k.value)
? interpolate
: fallbackInterpolator;
});
return function (timelineOffset) {
const absTime = duration * timelineOffset;
const r = findEndIndex(times, absTime);
const l = r ? r - 1 : 0;
const rt = times[r];
const lt = times[l];
const lk = keyframes[l];
const time = (absTime - lt) / (rt - lt);
const progression = lk.easing ? getEasing(lk.easing)(time) : time;
if (lk.simpleFn) {
return lk.interpolate(lk.value, keyframes[r].value, progression);
}
return lk.interpolate(lk.value, keyframes[r].value)(progression);
};
}