44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
const defaults = {
|
|
animation: "slideIn",
|
|
duration: 500,
|
|
easing: "ease",
|
|
delay: 0,
|
|
fill: "backwards",
|
|
initialDelay: 0,
|
|
fullDuration: 1000,
|
|
clear: false,
|
|
direction: "normal",
|
|
};
|
|
|
|
const clearAnimation = new Map<HTMLElement, number>();
|
|
|
|
export function animateElement(el: HTMLElement, opts = {}) {
|
|
const { animation, duration, direction, easing, delay, fill, clear } = Object.assign({}, defaults, opts);
|
|
clearTimeout(clearAnimation.get(el));
|
|
el.style.animation = "";
|
|
el.offsetLeft;
|
|
el.style.animation = `${animation} ${direction} ${duration}ms ${easing} ${delay}ms ${fill}`;
|
|
if (clear) {
|
|
const clearDelay = typeof clear === "number" ? clear : 0;
|
|
clearAnimation.set(
|
|
el,
|
|
window.setTimeout(() => (el.style.animation = ""), delay + duration + clearDelay)
|
|
);
|
|
}
|
|
|
|
return new Promise((resolve) => setTimeout(resolve, delay + duration));
|
|
}
|
|
|
|
export function animateCascade(nodes: Iterable<Node | Element>, opts = {}) {
|
|
const els = Array.from(nodes);
|
|
const { fullDuration, duration, initialDelay } = Object.assign({}, defaults, opts);
|
|
const dt = Math.max(30, Math.floor((fullDuration - duration) / els.length));
|
|
|
|
const promises = [];
|
|
for (const [i, e] of els.entries()) {
|
|
promises.push(animateElement(e as HTMLElement, Object.assign(opts, { delay: initialDelay + i * dt })));
|
|
}
|
|
|
|
return Promise.all(promises);
|
|
}
|