UNPKG

bits-ui

Version:

The headless components for Svelte.

56 lines (55 loc) 1.57 kB
import { afterTick, onDestroyEffect } from "svelte-toolbelt"; export class AnimationsComplete { #opts; #currentFrame = undefined; #isRunning = false; constructor(opts) { this.#opts = opts; onDestroyEffect(() => this.#cleanup()); } #cleanup() { if (this.#currentFrame) { window.cancelAnimationFrame(this.#currentFrame); this.#currentFrame = undefined; } this.#isRunning = false; } run(fn) { // prevent multiple concurrent runs if (this.#isRunning) return; this.#cleanup(); this.#isRunning = true; const node = this.#opts.ref.current; if (!node) { this.#isRunning = false; return; } if (typeof node.getAnimations !== "function") { this.#executeCallback(fn); return; } this.#currentFrame = window.requestAnimationFrame(() => { const animations = node.getAnimations(); if (animations.length === 0) { this.#executeCallback(fn); return; } Promise.allSettled(animations.map((animation) => animation.finished)).then(() => { this.#executeCallback(fn); }); }); } #executeCallback(fn) { const execute = () => { fn(); this.#isRunning = false; }; if (this.#opts.afterTick) { afterTick(execute); } else { execute(); } } }