UNPKG

@tldraw/utils

Version:

tldraw infinite canvas SDK (private utilities).

89 lines (88 loc) 1.92 kB
const isTest = () => typeof process !== "undefined" && process.env.NODE_ENV === "test" && // @ts-expect-error !globalThis.__FORCE_RAF_IN_TESTS__; const fpsQueue = []; const targetFps = 60; const targetTimePerFrame = Math.floor(1e3 / targetFps) * 0.9; let frameRaf; let flushRaf; let lastFlushTime = -targetTimePerFrame; const flush = () => { const queue = fpsQueue.splice(0, fpsQueue.length); for (const fn of queue) { fn(); } }; function tick(isOnNextFrame = false) { if (frameRaf) return; const now = Date.now(); const elapsed = now - lastFlushTime; if (elapsed < targetTimePerFrame) { frameRaf = requestAnimationFrame(() => { frameRaf = void 0; tick(true); }); return; } if (isOnNextFrame) { if (flushRaf) return; lastFlushTime = now; flush(); } else { if (flushRaf) return; flushRaf = requestAnimationFrame(() => { flushRaf = void 0; lastFlushTime = now; flush(); }); } } function fpsThrottle(fn) { if (isTest()) { fn.cancel = () => { if (frameRaf) { cancelAnimationFrame(frameRaf); frameRaf = void 0; } if (flushRaf) { cancelAnimationFrame(flushRaf); flushRaf = void 0; } }; return fn; } const throttledFn = () => { if (fpsQueue.includes(fn)) { return; } fpsQueue.push(fn); tick(); }; throttledFn.cancel = () => { const index = fpsQueue.indexOf(fn); if (index > -1) { fpsQueue.splice(index, 1); } }; return throttledFn; } function throttleToNextFrame(fn) { if (isTest()) { fn(); return () => void 0; } if (!fpsQueue.includes(fn)) { fpsQueue.push(fn); tick(); } return () => { const index = fpsQueue.indexOf(fn); if (index > -1) { fpsQueue.splice(index, 1); } }; } export { fpsThrottle, throttleToNextFrame }; //# sourceMappingURL=throttle.mjs.map