UNPKG

@react-spring/rafz

Version:

react-spring's fork of rafz one frameloop to rule them all

208 lines (206 loc) 5.17 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { __raf: () => __raf, raf: () => raf }); module.exports = __toCommonJS(src_exports); var updateQueue = makeQueue(); var raf = (fn) => schedule(fn, updateQueue); var writeQueue = makeQueue(); raf.write = (fn) => schedule(fn, writeQueue); var onStartQueue = makeQueue(); raf.onStart = (fn) => schedule(fn, onStartQueue); var onFrameQueue = makeQueue(); raf.onFrame = (fn) => schedule(fn, onFrameQueue); var onFinishQueue = makeQueue(); raf.onFinish = (fn) => schedule(fn, onFinishQueue); var timeouts = []; raf.setTimeout = (handler, ms) => { const time = raf.now() + ms; const cancel = () => { const i = timeouts.findIndex((t) => t.cancel == cancel); if (~i) timeouts.splice(i, 1); pendingCount -= ~i ? 1 : 0; }; const timeout = { time, handler, cancel }; timeouts.splice(findTimeout(time), 0, timeout); pendingCount += 1; start(); return timeout; }; var findTimeout = (time) => ~(~timeouts.findIndex((t) => t.time > time) || ~timeouts.length); raf.cancel = (fn) => { onStartQueue.delete(fn); onFrameQueue.delete(fn); onFinishQueue.delete(fn); updateQueue.delete(fn); writeQueue.delete(fn); }; raf.sync = (fn) => { sync = true; raf.batchedUpdates(fn); sync = false; }; raf.throttle = (fn) => { let lastArgs; function queuedFn() { try { fn(...lastArgs); } finally { lastArgs = null; } } function throttled(...args) { lastArgs = args; raf.onStart(queuedFn); } throttled.handler = fn; throttled.cancel = () => { onStartQueue.delete(queuedFn); lastArgs = null; }; return throttled; }; var nativeRaf = typeof window != "undefined" ? window.requestAnimationFrame : ( // eslint-disable-next-line @typescript-eslint/no-empty-function () => { } ); raf.use = (impl) => nativeRaf = impl; raf.now = typeof performance != "undefined" ? () => performance.now() : Date.now; raf.batchedUpdates = (fn) => fn(); raf.catch = console.error; raf.frameLoop = "always"; raf.advance = () => { if (raf.frameLoop !== "demand") { console.warn( "Cannot call the manual advancement of rafz whilst frameLoop is not set as demand" ); } else { update(); } }; var ts = -1; var pendingCount = 0; var sync = false; function schedule(fn, queue) { if (sync) { queue.delete(fn); fn(0); } else { queue.add(fn); start(); } } function start() { if (ts < 0) { ts = 0; if (raf.frameLoop !== "demand") { nativeRaf(loop); } } } function stop() { ts = -1; } function loop() { if (~ts) { nativeRaf(loop); raf.batchedUpdates(update); } } function update() { const prevTs = ts; ts = raf.now(); const count = findTimeout(ts); if (count) { eachSafely(timeouts.splice(0, count), (t) => t.handler()); pendingCount -= count; } if (!pendingCount) { stop(); return; } onStartQueue.flush(); updateQueue.flush(prevTs ? Math.min(64, ts - prevTs) : 16.667); onFrameQueue.flush(); writeQueue.flush(); onFinishQueue.flush(); } function makeQueue() { let next = /* @__PURE__ */ new Set(); let current = next; return { add(fn) { pendingCount += current == next && !next.has(fn) ? 1 : 0; next.add(fn); }, delete(fn) { pendingCount -= current == next && next.has(fn) ? 1 : 0; return next.delete(fn); }, flush(arg) { if (current.size) { next = /* @__PURE__ */ new Set(); pendingCount -= current.size; eachSafely(current, (fn) => fn(arg) && next.add(fn)); pendingCount += next.size; current = next; } } }; } function eachSafely(values, each) { values.forEach((value) => { try { each(value); } catch (e) { raf.catch(e); } }); } var __raf = { /** The number of pending tasks */ count() { return pendingCount; }, /** Whether there's a raf update loop running */ isRunning() { return ts >= 0; }, /** Clear internal state. Never call from update loop! */ clear() { ts = -1; timeouts = []; onStartQueue = makeQueue(); updateQueue = makeQueue(); onFrameQueue = makeQueue(); writeQueue = makeQueue(); onFinishQueue = makeQueue(); pendingCount = 0; } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { __raf, raf });