-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Expand file tree
/
Copy pathuseRaf.ts
More file actions
46 lines (39 loc) · 1.16 KB
/
useRaf.ts
File metadata and controls
46 lines (39 loc) · 1.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { useState } from 'react';
import useIsomorphicLayoutEffect from './useIsomorphicLayoutEffect';
// setTimeout max delay is a 32-bit signed int (2147483647ms ~24.8 days).
// Values above this overflow and fire immediately. See: https://github.com/streamich/react-use/issues/779
const MAX_SAFE_TIMEOUT = 2147483647;
const useRaf = (ms: number = 1e12, delay: number = 0): number => {
const [elapsed, set] = useState<number>(0);
useIsomorphicLayoutEffect(() => {
let raf;
let timerStop;
let start;
const onFrame = () => {
const time = Math.min(1, (Date.now() - start) / ms);
set(time);
loop();
};
const loop = () => {
raf = requestAnimationFrame(onFrame);
};
const onStart = () => {
if (ms <= MAX_SAFE_TIMEOUT) {
timerStop = setTimeout(() => {
cancelAnimationFrame(raf);
set(1);
}, ms);
}
start = Date.now();
loop();
};
const timerDelay = setTimeout(onStart, delay);
return () => {
clearTimeout(timerStop);
clearTimeout(timerDelay);
cancelAnimationFrame(raf);
};
}, [ms, delay]);
return elapsed;
};
export default useRaf;