@lytjs/common-raf 6.5.0 → 6.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +97 -97
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAKA,IAAM,IAAA,GACJ,OAAO,qBAAA,KAA0B,WAAA,GAC7B,wBACA,CAAC,EAAA,KACC,UAAA,CAAW,MAAM,EAAA,CAAG,WAAA,CAAY,GAAA,EAAK,GAAG,EAAE,CAAA;AAElD,IAAM,IAAA,GACJ,OAAO,oBAAA,KAAyB,WAAA,GAC5B,uBACA,CAAC,EAAA,KAAqB,aAAa,EAAE,CAAA;AAKpC,SAAS,IAAI,QAAA,EAAwC;AAC1D,EAAA,OAAO,KAAK,QAAQ,CAAA;AACtB;AAKO,SAAS,IAAI,EAAA,EAAkB;AACpC,EAAA,IAAA,CAAK,EAAE,CAAA;AACT;AAKO,SAAS,SAAA,GAA2B;AACzC,EAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACpC,IAAA,GAAA,CAAI,MAAM,SAAS,CAAA;AAAA,EACrB,CAAC,CAAA;AACH;AAKO,SAAS,YAAuD,EAAA,EAAU;AAC/E,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,IAAI,UAAA,GAA+B,IAAA;AAEnC,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,KAAoB;AACxC,IAAA,UAAA,GAAa,IAAA;AACb,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,GAAA,CAAI,MAAM;AACR,QAAA,OAAA,GAAU,KAAA;AACV,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,EAAA,CAAG,GAAG,UAAU,CAAA;AAChB,UAAA,UAAA,GAAa,IAAA;AAAA,QACf;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,SAAA;AACT;AAKO,SAAS,WAAA,CAAuD,IAAO,KAAA,EAAmB;AAC/F,EAAA,IAAI,EAAA,GAAoB,IAAA;AACxB,EAAA,IAAI,UAAA,GAA+B,IAAA;AACnC,EAAA,IAAI,YAAY,KAAA,IAAS,CAAA;AAEzB,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,KAAoB;AACxC,IAAA,UAAA,GAAa,IAAA;AACb,IAAA,SAAA,GAAY,KAAA,IAAS,CAAA;AAErB,IAAA,IAAI,OAAO,IAAA,EAAM;AACf,MAAA,GAAA,CAAI,EAAE,CAAA;AAAA,IACR;AAEA,IAAA,MAAM,OAAO,MAAM;AACjB,MAAA,SAAA,EAAA;AACA,MAAA,IAAI,aAAa,CAAA,EAAG;AAClB,QAAA,EAAA,GAAK,IAAA;AACL,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,EAAA,CAAG,GAAG,UAAU,CAAA;AAChB,UAAA,UAAA,GAAa,IAAA;AAAA,QACf;AAAA,MACF,CAAA,MAAO;AACL,QAAA,EAAA,GAAK,IAAI,IAAI,CAAA;AAAA,MACf;AAAA,IACF,CAAA;AAEA,IAAA,EAAA,GAAK,IAAI,IAAI,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,OAAO,SAAA;AACT","file":"index.cjs","sourcesContent":["/**\
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAKA,IAAM,IAAA,GACJ,OAAO,qBAAA,KAA0B,WAAA,GAC7B,wBACA,CAAC,EAAA,KACC,UAAA,CAAW,MAAM,EAAA,CAAG,WAAA,CAAY,GAAA,EAAK,GAAG,EAAE,CAAA;AAElD,IAAM,IAAA,GACJ,OAAO,oBAAA,KAAyB,WAAA,GAC5B,uBACA,CAAC,EAAA,KAAqB,aAAa,EAAE,CAAA;AAKpC,SAAS,IAAI,QAAA,EAAwC;AAC1D,EAAA,OAAO,KAAK,QAAQ,CAAA;AACtB;AAKO,SAAS,IAAI,EAAA,EAAkB;AACpC,EAAA,IAAA,CAAK,EAAE,CAAA;AACT;AAKO,SAAS,SAAA,GAA2B;AACzC,EAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACpC,IAAA,GAAA,CAAI,MAAM,SAAS,CAAA;AAAA,EACrB,CAAC,CAAA;AACH;AAKO,SAAS,YAAuD,EAAA,EAAU;AAC/E,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,IAAI,UAAA,GAA+B,IAAA;AAEnC,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,KAAoB;AACxC,IAAA,UAAA,GAAa,IAAA;AACb,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,GAAA,CAAI,MAAM;AACR,QAAA,OAAA,GAAU,KAAA;AACV,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,EAAA,CAAG,GAAG,UAAU,CAAA;AAChB,UAAA,UAAA,GAAa,IAAA;AAAA,QACf;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,SAAA;AACT;AAKO,SAAS,WAAA,CAAuD,IAAO,KAAA,EAAmB;AAC/F,EAAA,IAAI,EAAA,GAAoB,IAAA;AACxB,EAAA,IAAI,UAAA,GAA+B,IAAA;AACnC,EAAA,IAAI,YAAY,KAAA,IAAS,CAAA;AAEzB,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,KAAoB;AACxC,IAAA,UAAA,GAAa,IAAA;AACb,IAAA,SAAA,GAAY,KAAA,IAAS,CAAA;AAErB,IAAA,IAAI,OAAO,IAAA,EAAM;AACf,MAAA,GAAA,CAAI,EAAE,CAAA;AAAA,IACR;AAEA,IAAA,MAAM,OAAO,MAAM;AACjB,MAAA,SAAA,EAAA;AACA,MAAA,IAAI,aAAa,CAAA,EAAG;AAClB,QAAA,EAAA,GAAK,IAAA;AACL,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,EAAA,CAAG,GAAG,UAAU,CAAA;AAChB,UAAA,UAAA,GAAa,IAAA;AAAA,QACf;AAAA,MACF,CAAA,MAAO;AACL,QAAA,EAAA,GAAK,IAAI,IAAI,CAAA;AAAA,MACf;AAAA,IACF,CAAA;AAEA,IAAA,EAAA,GAAK,IAAI,IAAI,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,OAAO,SAAA;AACT","file":"index.cjs","sourcesContent":["/**\n * @lytjs/common-raf\n * Cross-platform requestAnimationFrame utilities\n */\n\nconst _raf =\n typeof requestAnimationFrame !== 'undefined'\n ? requestAnimationFrame\n : (cb: FrameRequestCallback): ReturnType<typeof setTimeout> =>\n setTimeout(() => cb(performance.now()), 16);\n\nconst _caf =\n typeof cancelAnimationFrame !== 'undefined'\n ? cancelAnimationFrame\n : (id: number): void => clearTimeout(id);\n\n/**\n * requestAnimationFrame cross-platform wrapper\n */\nexport function raf(callback: FrameRequestCallback): number {\n return _raf(callback) as number;\n}\n\n/**\n * cancelAnimationFrame cross-platform wrapper\n */\nexport function caf(id: number): void {\n _caf(id);\n}\n\n/**\n * Wait for the next animation frame\n */\nexport function nextFrame(): Promise<void> {\n return new Promise<void>((resolve) => {\n raf(() => resolve());\n });\n}\n\n/**\n * Throttle a function to run at most once per animation frame\n */\nexport function rafThrottle<T extends (...args: unknown[]) => unknown>(fn: T): T {\n let pending = false;\n let latestArgs: unknown[] | null = null;\n\n const throttled = (...args: unknown[]) => {\n latestArgs = args;\n if (!pending) {\n pending = true;\n raf(() => {\n pending = false;\n if (latestArgs) {\n fn(...latestArgs);\n latestArgs = null;\n }\n });\n }\n };\n\n return throttled as T;\n}\n\n/**\n * Debounce a function to run after a specified number of frames (default: 1)\n */\nexport function rafDebounce<T extends (...args: unknown[]) => unknown>(fn: T, delay?: number): T {\n let id: number | null = null;\n let latestArgs: unknown[] | null = null;\n let remaining = delay ?? 1;\n\n const debounced = (...args: unknown[]) => {\n latestArgs = args;\n remaining = delay ?? 1;\n\n if (id !== null) {\n caf(id);\n }\n\n const tick = () => {\n remaining--;\n if (remaining <= 0) {\n id = null;\n if (latestArgs) {\n fn(...latestArgs);\n latestArgs = null;\n }\n } else {\n id = raf(tick);\n }\n };\n\n id = raf(tick);\n };\n\n return debounced as T;\n}\n"]}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAKA,IAAM,IAAA,GACJ,OAAO,qBAAA,KAA0B,WAAA,GAC7B,wBACA,CAAC,EAAA,KACC,UAAA,CAAW,MAAM,EAAA,CAAG,WAAA,CAAY,GAAA,EAAK,GAAG,EAAE,CAAA;AAElD,IAAM,IAAA,GACJ,OAAO,oBAAA,KAAyB,WAAA,GAC5B,uBACA,CAAC,EAAA,KAAqB,aAAa,EAAE,CAAA;AAKpC,SAAS,IAAI,QAAA,EAAwC;AAC1D,EAAA,OAAO,KAAK,QAAQ,CAAA;AACtB;AAKO,SAAS,IAAI,EAAA,EAAkB;AACpC,EAAA,IAAA,CAAK,EAAE,CAAA;AACT;AAKO,SAAS,SAAA,GAA2B;AACzC,EAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACpC,IAAA,GAAA,CAAI,MAAM,SAAS,CAAA;AAAA,EACrB,CAAC,CAAA;AACH;AAKO,SAAS,YAAuD,EAAA,EAAU;AAC/E,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,IAAI,UAAA,GAA+B,IAAA;AAEnC,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,KAAoB;AACxC,IAAA,UAAA,GAAa,IAAA;AACb,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,GAAA,CAAI,MAAM;AACR,QAAA,OAAA,GAAU,KAAA;AACV,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,EAAA,CAAG,GAAG,UAAU,CAAA;AAChB,UAAA,UAAA,GAAa,IAAA;AAAA,QACf;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,SAAA;AACT;AAKO,SAAS,WAAA,CAAuD,IAAO,KAAA,EAAmB;AAC/F,EAAA,IAAI,EAAA,GAAoB,IAAA;AACxB,EAAA,IAAI,UAAA,GAA+B,IAAA;AACnC,EAAA,IAAI,YAAY,KAAA,IAAS,CAAA;AAEzB,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,KAAoB;AACxC,IAAA,UAAA,GAAa,IAAA;AACb,IAAA,SAAA,GAAY,KAAA,IAAS,CAAA;AAErB,IAAA,IAAI,OAAO,IAAA,EAAM;AACf,MAAA,GAAA,CAAI,EAAE,CAAA;AAAA,IACR;AAEA,IAAA,MAAM,OAAO,MAAM;AACjB,MAAA,SAAA,EAAA;AACA,MAAA,IAAI,aAAa,CAAA,EAAG;AAClB,QAAA,EAAA,GAAK,IAAA;AACL,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,EAAA,CAAG,GAAG,UAAU,CAAA;AAChB,UAAA,UAAA,GAAa,IAAA;AAAA,QACf;AAAA,MACF,CAAA,MAAO;AACL,QAAA,EAAA,GAAK,IAAI,IAAI,CAAA;AAAA,MACf;AAAA,IACF,CAAA;AAEA,IAAA,EAAA,GAAK,IAAI,IAAI,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,OAAO,SAAA;AACT","file":"index.mjs","sourcesContent":["/**\
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAKA,IAAM,IAAA,GACJ,OAAO,qBAAA,KAA0B,WAAA,GAC7B,wBACA,CAAC,EAAA,KACC,UAAA,CAAW,MAAM,EAAA,CAAG,WAAA,CAAY,GAAA,EAAK,GAAG,EAAE,CAAA;AAElD,IAAM,IAAA,GACJ,OAAO,oBAAA,KAAyB,WAAA,GAC5B,uBACA,CAAC,EAAA,KAAqB,aAAa,EAAE,CAAA;AAKpC,SAAS,IAAI,QAAA,EAAwC;AAC1D,EAAA,OAAO,KAAK,QAAQ,CAAA;AACtB;AAKO,SAAS,IAAI,EAAA,EAAkB;AACpC,EAAA,IAAA,CAAK,EAAE,CAAA;AACT;AAKO,SAAS,SAAA,GAA2B;AACzC,EAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACpC,IAAA,GAAA,CAAI,MAAM,SAAS,CAAA;AAAA,EACrB,CAAC,CAAA;AACH;AAKO,SAAS,YAAuD,EAAA,EAAU;AAC/E,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,IAAI,UAAA,GAA+B,IAAA;AAEnC,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,KAAoB;AACxC,IAAA,UAAA,GAAa,IAAA;AACb,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,GAAA,CAAI,MAAM;AACR,QAAA,OAAA,GAAU,KAAA;AACV,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,EAAA,CAAG,GAAG,UAAU,CAAA;AAChB,UAAA,UAAA,GAAa,IAAA;AAAA,QACf;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,SAAA;AACT;AAKO,SAAS,WAAA,CAAuD,IAAO,KAAA,EAAmB;AAC/F,EAAA,IAAI,EAAA,GAAoB,IAAA;AACxB,EAAA,IAAI,UAAA,GAA+B,IAAA;AACnC,EAAA,IAAI,YAAY,KAAA,IAAS,CAAA;AAEzB,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,KAAoB;AACxC,IAAA,UAAA,GAAa,IAAA;AACb,IAAA,SAAA,GAAY,KAAA,IAAS,CAAA;AAErB,IAAA,IAAI,OAAO,IAAA,EAAM;AACf,MAAA,GAAA,CAAI,EAAE,CAAA;AAAA,IACR;AAEA,IAAA,MAAM,OAAO,MAAM;AACjB,MAAA,SAAA,EAAA;AACA,MAAA,IAAI,aAAa,CAAA,EAAG;AAClB,QAAA,EAAA,GAAK,IAAA;AACL,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,EAAA,CAAG,GAAG,UAAU,CAAA;AAChB,UAAA,UAAA,GAAa,IAAA;AAAA,QACf;AAAA,MACF,CAAA,MAAO;AACL,QAAA,EAAA,GAAK,IAAI,IAAI,CAAA;AAAA,MACf;AAAA,IACF,CAAA;AAEA,IAAA,EAAA,GAAK,IAAI,IAAI,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,OAAO,SAAA;AACT","file":"index.mjs","sourcesContent":["/**\n * @lytjs/common-raf\n * Cross-platform requestAnimationFrame utilities\n */\n\nconst _raf =\n typeof requestAnimationFrame !== 'undefined'\n ? requestAnimationFrame\n : (cb: FrameRequestCallback): ReturnType<typeof setTimeout> =>\n setTimeout(() => cb(performance.now()), 16);\n\nconst _caf =\n typeof cancelAnimationFrame !== 'undefined'\n ? cancelAnimationFrame\n : (id: number): void => clearTimeout(id);\n\n/**\n * requestAnimationFrame cross-platform wrapper\n */\nexport function raf(callback: FrameRequestCallback): number {\n return _raf(callback) as number;\n}\n\n/**\n * cancelAnimationFrame cross-platform wrapper\n */\nexport function caf(id: number): void {\n _caf(id);\n}\n\n/**\n * Wait for the next animation frame\n */\nexport function nextFrame(): Promise<void> {\n return new Promise<void>((resolve) => {\n raf(() => resolve());\n });\n}\n\n/**\n * Throttle a function to run at most once per animation frame\n */\nexport function rafThrottle<T extends (...args: unknown[]) => unknown>(fn: T): T {\n let pending = false;\n let latestArgs: unknown[] | null = null;\n\n const throttled = (...args: unknown[]) => {\n latestArgs = args;\n if (!pending) {\n pending = true;\n raf(() => {\n pending = false;\n if (latestArgs) {\n fn(...latestArgs);\n latestArgs = null;\n }\n });\n }\n };\n\n return throttled as T;\n}\n\n/**\n * Debounce a function to run after a specified number of frames (default: 1)\n */\nexport function rafDebounce<T extends (...args: unknown[]) => unknown>(fn: T, delay?: number): T {\n let id: number | null = null;\n let latestArgs: unknown[] | null = null;\n let remaining = delay ?? 1;\n\n const debounced = (...args: unknown[]) => {\n latestArgs = args;\n remaining = delay ?? 1;\n\n if (id !== null) {\n caf(id);\n }\n\n const tick = () => {\n remaining--;\n if (remaining <= 0) {\n id = null;\n if (latestArgs) {\n fn(...latestArgs);\n latestArgs = null;\n }\n } else {\n id = raf(tick);\n }\n };\n\n id = raf(tick);\n };\n\n return debounced as T;\n}\n"]}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @lytjs/common-raf
|
|
3
|
-
* Cross-platform requestAnimationFrame utilities
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const _raf =
|
|
7
|
-
typeof requestAnimationFrame !== 'undefined'
|
|
8
|
-
? requestAnimationFrame
|
|
9
|
-
: (cb: FrameRequestCallback): ReturnType<typeof setTimeout> =>
|
|
10
|
-
setTimeout(() => cb(performance.now()), 16);
|
|
11
|
-
|
|
12
|
-
const _caf =
|
|
13
|
-
typeof cancelAnimationFrame !== 'undefined'
|
|
14
|
-
? cancelAnimationFrame
|
|
15
|
-
: (id: number): void => clearTimeout(id);
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* requestAnimationFrame cross-platform wrapper
|
|
19
|
-
*/
|
|
20
|
-
export function raf(callback: FrameRequestCallback): number {
|
|
21
|
-
return _raf(callback) as number;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* cancelAnimationFrame cross-platform wrapper
|
|
26
|
-
*/
|
|
27
|
-
export function caf(id: number): void {
|
|
28
|
-
_caf(id);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Wait for the next animation frame
|
|
33
|
-
*/
|
|
34
|
-
export function nextFrame(): Promise<void> {
|
|
35
|
-
return new Promise<void>((resolve) => {
|
|
36
|
-
raf(() => resolve());
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Throttle a function to run at most once per animation frame
|
|
42
|
-
*/
|
|
43
|
-
export function rafThrottle<T extends (...args: unknown[]) => unknown>(fn: T): T {
|
|
44
|
-
let pending = false;
|
|
45
|
-
let latestArgs: unknown[] | null = null;
|
|
46
|
-
|
|
47
|
-
const throttled = (...args: unknown[]) => {
|
|
48
|
-
latestArgs = args;
|
|
49
|
-
if (!pending) {
|
|
50
|
-
pending = true;
|
|
51
|
-
raf(() => {
|
|
52
|
-
pending = false;
|
|
53
|
-
if (latestArgs) {
|
|
54
|
-
fn(...latestArgs);
|
|
55
|
-
latestArgs = null;
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
return throttled as T;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Debounce a function to run after a specified number of frames (default: 1)
|
|
66
|
-
*/
|
|
67
|
-
export function rafDebounce<T extends (...args: unknown[]) => unknown>(fn: T, delay?: number): T {
|
|
68
|
-
let id: number | null = null;
|
|
69
|
-
let latestArgs: unknown[] | null = null;
|
|
70
|
-
let remaining = delay ?? 1;
|
|
71
|
-
|
|
72
|
-
const debounced = (...args: unknown[]) => {
|
|
73
|
-
latestArgs = args;
|
|
74
|
-
remaining = delay ?? 1;
|
|
75
|
-
|
|
76
|
-
if (id !== null) {
|
|
77
|
-
caf(id);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const tick = () => {
|
|
81
|
-
remaining--;
|
|
82
|
-
if (remaining <= 0) {
|
|
83
|
-
id = null;
|
|
84
|
-
if (latestArgs) {
|
|
85
|
-
fn(...latestArgs);
|
|
86
|
-
latestArgs = null;
|
|
87
|
-
}
|
|
88
|
-
} else {
|
|
89
|
-
id = raf(tick);
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
id = raf(tick);
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
return debounced as T;
|
|
97
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @lytjs/common-raf
|
|
3
|
+
* Cross-platform requestAnimationFrame utilities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const _raf =
|
|
7
|
+
typeof requestAnimationFrame !== 'undefined'
|
|
8
|
+
? requestAnimationFrame
|
|
9
|
+
: (cb: FrameRequestCallback): ReturnType<typeof setTimeout> =>
|
|
10
|
+
setTimeout(() => cb(performance.now()), 16);
|
|
11
|
+
|
|
12
|
+
const _caf =
|
|
13
|
+
typeof cancelAnimationFrame !== 'undefined'
|
|
14
|
+
? cancelAnimationFrame
|
|
15
|
+
: (id: number): void => clearTimeout(id);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* requestAnimationFrame cross-platform wrapper
|
|
19
|
+
*/
|
|
20
|
+
export function raf(callback: FrameRequestCallback): number {
|
|
21
|
+
return _raf(callback) as number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* cancelAnimationFrame cross-platform wrapper
|
|
26
|
+
*/
|
|
27
|
+
export function caf(id: number): void {
|
|
28
|
+
_caf(id);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Wait for the next animation frame
|
|
33
|
+
*/
|
|
34
|
+
export function nextFrame(): Promise<void> {
|
|
35
|
+
return new Promise<void>((resolve) => {
|
|
36
|
+
raf(() => resolve());
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Throttle a function to run at most once per animation frame
|
|
42
|
+
*/
|
|
43
|
+
export function rafThrottle<T extends (...args: unknown[]) => unknown>(fn: T): T {
|
|
44
|
+
let pending = false;
|
|
45
|
+
let latestArgs: unknown[] | null = null;
|
|
46
|
+
|
|
47
|
+
const throttled = (...args: unknown[]) => {
|
|
48
|
+
latestArgs = args;
|
|
49
|
+
if (!pending) {
|
|
50
|
+
pending = true;
|
|
51
|
+
raf(() => {
|
|
52
|
+
pending = false;
|
|
53
|
+
if (latestArgs) {
|
|
54
|
+
fn(...latestArgs);
|
|
55
|
+
latestArgs = null;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return throttled as T;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Debounce a function to run after a specified number of frames (default: 1)
|
|
66
|
+
*/
|
|
67
|
+
export function rafDebounce<T extends (...args: unknown[]) => unknown>(fn: T, delay?: number): T {
|
|
68
|
+
let id: number | null = null;
|
|
69
|
+
let latestArgs: unknown[] | null = null;
|
|
70
|
+
let remaining = delay ?? 1;
|
|
71
|
+
|
|
72
|
+
const debounced = (...args: unknown[]) => {
|
|
73
|
+
latestArgs = args;
|
|
74
|
+
remaining = delay ?? 1;
|
|
75
|
+
|
|
76
|
+
if (id !== null) {
|
|
77
|
+
caf(id);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const tick = () => {
|
|
81
|
+
remaining--;
|
|
82
|
+
if (remaining <= 0) {
|
|
83
|
+
id = null;
|
|
84
|
+
if (latestArgs) {
|
|
85
|
+
fn(...latestArgs);
|
|
86
|
+
latestArgs = null;
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
id = raf(tick);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
id = raf(tick);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return debounced as T;
|
|
97
|
+
}
|