motion
Version:
The Motion library for the web
41 lines (38 loc) • 1.65 kB
JavaScript
import { useRef, useEffect } from 'react';
import { animateStyle } from '../../dom/animate-style.es.js';
import { noop } from '../../../utils/noop.es.js';
import { hasChanged } from '../utils/has-changed.es.js';
import { getOptions } from '../../dom/utils/options.es.js';
function useAnimation(ref, initial, target, options, onStart, onComplete) {
const prevTarget = useRef(initial);
useEffect(() => {
const targetKeyframe = {};
const allKeys = new Set([
...Object.keys(target),
...Object.keys(prevTarget.current),
]);
allKeys.forEach((key) => {
let next = target[key];
if (!hasChanged(next, prevTarget.current[key]))
return;
/**
* TODO: If next is undefined, throw error or record a "base value"
* to animate back down to
*/
targetKeyframe[key] = next;
});
if (Object.keys(targetKeyframe).length && ref.current) {
onStart === null || onStart === void 0 ? void 0 : onStart(targetKeyframe);
const animations = [];
for (const key in targetKeyframe) {
const animation = animateStyle(ref.current, key, targetKeyframe[key], getOptions(options, key));
animation && animations.push(animation);
}
Promise.all(animations.map((animation) => animation.finished))
.then(() => onComplete === null || onComplete === void 0 ? void 0 : onComplete(targetKeyframe))
.catch(noop);
}
prevTarget.current = target;
});
}
export { useAnimation };