@tldraw/utils
Version:
tldraw infinite canvas SDK (private utilities).
89 lines (88 loc) • 1.92 kB
JavaScript
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