UNPKG

ziko

Version:

A versatile JavaScript library offering a rich set of Hyperscript Based UI components, advanced mathematical utilities, interactivity ,animations, client side routing and more ...

104 lines (87 loc) 2.27 kB
export class TimeLoop { constructor(callback, { step = 1000, t0 = 0, t1 = Infinity, autoplay = true } = {}) { this.callback = callback; this.cache = { isRunning: false, id: null, last_tick: null, step, t0, t1, autoplay, pauseTime: null, frame : 0, }; if (autoplay) { t0 ? this.startAfter(t0) : this.start(); if (t1 !== Infinity) this.stopAfter(t1); } } get frame(){ return this.cache.frame; } get elapsed(){ return this.cache.elapsed; } start() { if (!this.cache.isRunning) { this.cache.frame = 0; this.cache.isRunning = true; this.cache.last_tick = Date.now(); this.animate(); } return this; } pause() { if (this.cache.isRunning) { clearTimeout(this.cache.id); this.cache.isRunning = false; this.cache.pauseTime = Date.now(); } return this; } resume() { if (!this.cache.isRunning) { this.cache.isRunning = true; if (this.cache.pauseTime) { // adjust start time so delta stays consistent const pausedDuration = Date.now() - this.cache.pauseTime; this.cache.last_tick += pausedDuration; } this.animate(); } return this; } stop() { this.pause(); this.cache.frame = 0; return this; } startAfter(t = 1000) { setTimeout(() => this.start(), t); return this; } stopAfter(t = 1000) { setTimeout(() => this.stop(), t); return this; } animate = () => { if (this.cache.isRunning) { const now = Date.now(); const delta = now - this.cache.last_tick; if (delta >= this.cache.step) { this.cache.elapsed = now - (this.cache.t0 || 0); this.callback(this); this.cache.frame++; this.cache.last_tick = now - (delta % this.cache.step); } this.cache.id = setTimeout(this.animate, 0); } } } export const loop = (callback, options = {}) => new TimeLoop(callback, options); // Helpers // const useFps = (fps) => 1000 / fps; // const _loop = loop( e => { // console.log("Frame:", e.frame, " Elapsed: ", e.elapsed); // });