just-animate
Version:
_Making Animation Simple_
56 lines (55 loc) • 1.91 kB
JavaScript
import { abs } from '../lib/utils/math';
import { RUNNING } from './constants';
import { memoize } from '../lib/utils/functional';
const frameSize = 17;
export function animate(effect) {
const { keyframes, prop, from, to, target } = effect;
const duration = to - from;
const getAnimator = memoize(() => {
const frames = keyframes.map(({ offset, value, easing }) => ({
offset,
[prop]: value,
easing
}));
const a = target.animate(frames, {
duration,
fill: 'both'
});
a.pause();
return a;
});
return {
cancel() {
getAnimator().cancel();
},
update(offset, rate, isPlaying) {
const animator = getAnimator();
const time = duration * offset;
if (abs(animator.currentTime - time) > 1) {
animator.currentTime = time;
}
if (isPlaying && animator.playbackRate !== rate) {
const currentTime = animator.currentTime;
if (currentTime < 1) {
animator.currentTime = 1;
}
else if (currentTime >= duration - 1) {
animator.currentTime = duration - 1;
}
animator.playbackRate = rate;
}
const needsToPlay = isPlaying &&
!(animator.playState === RUNNING || animator.playState === 'finish') &&
!(rate < 0 && time < frameSize) &&
!(rate >= 0 && time > duration - frameSize);
if (needsToPlay) {
animator.play();
}
const needsToPause = !isPlaying &&
(animator.playState === RUNNING || animator.playState === 'pending');
if (needsToPause) {
animator.pause();
}
}
};
}