1import { useEffect, useRef } from 'react'; 2 3function useFrame(callback, autostart = false) { 4 const requestRef = useRef(); 5 const previousTimeRef = useRef(); 6 7 const animate = (time) => { 8 if (previousTimeRef.current !== undefined) { 9 const deltaTime = time - previousTimeRef.current; 10 callback(time, deltaTime); 11 } 12 previousTimeRef.current = time; 13 requestRef.current = requestAnimationFrame(animate); 14 }; 15 16 const start = () => { 17 requestRef.current = requestAnimationFrame(animate); 18 }; 19 const stop = () => { 20 requestRef.current && cancelAnimationFrame(requestRef.current); 21 delete requestRef.current; 22 }; 23 useEffect(() => { 24 if (requestRef.current) { 25 stop(); 26 start(); 27 } 28 }, [callback]); 29 30 useEffect(() => { 31 if (autostart) { 32 start(); 33 } 34 return stop; 35 }, []); // Make sure the effect only runs once 36 37 return { 38 start, 39 stop, 40 }; 41} 42 43export default useFrame;