UNPKG

melt

Version:

The next generation of Melt UI. Built for Svelte 5.

57 lines (56 loc) 1.74 kB
import { untrack } from "svelte"; /** * Wrapper over {@link https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame}, * with controls for pausing and resuming the animation, reactive tracking and optional limiting of fps, and utilities. */ export class AnimationFrames { #callback; #previousTimestamp = null; frame = null; #fps = $state(0); #running = $state(false); constructor(callback) { this.#callback = callback; this.start = this.start.bind(this); this.stop = this.stop.bind(this); this.toggle = this.toggle.bind(this); this.start(); } #loop(timestamp) { if (!this.#running) return; if (this.#previousTimestamp === null) { this.#previousTimestamp = timestamp; } const delta = timestamp - this.#previousTimestamp; const fps = 1000 / delta; this.#fps = fps; this.#previousTimestamp = timestamp; this.#callback({ delta, timestamp }); this.frame = window.requestAnimationFrame(this.#loop.bind(this)); } start() { if (this.#running) return; this.#running = true; this.#previousTimestamp = null; this.frame = window.requestAnimationFrame(this.#loop.bind(this)); } stop() { if (!this.#running) return; this.#running = false; if (this.frame) window.cancelAnimationFrame(this.frame); this.frame = null; } toggle() { this.#running ? this.stop() : this.start(); } get fps() { return !this.#running ? 0 : this.#fps; } get running() { return this.#running; } }