All files / src/hooks useAnimationFrame.js

100% Statements 17/17
85.71% Branches 6/7
100% Functions 5/5
100% Lines 17/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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                    13x 13x 13x     13x 9x     13x 5x 2x 2x   5x 5x     13x 12x 8x     12x 12x 11x              
import { useRef, useEffect, useCallback } from 'react';
 
/**
 * Custom hook for animation frame loop
 * Provides a smooth animation loop using requestAnimationFrame
 * 
 * @param {Function} callback - Function to call on each frame
 * @param {boolean} isActive - Whether the animation should be running
 */
export function useAnimationFrame(callback, isActive = true) {
  const requestRef = useRef(null);
  const previousTimeRef = useRef(null);
  const callbackRef = useRef(callback);
 
  // Update callback ref when it changes
  useEffect(() => {
    callbackRef.current = callback;
  }, [callback]);
 
  const animate = useCallback((time) => {
    if (previousTimeRef.current !== null) {
      const deltaTime = time - previousTimeRef.current;
      callbackRef.current(deltaTime);
    }
    previousTimeRef.current = time;
    requestRef.current = window.requestAnimationFrame(animate);
  }, []);
 
  useEffect(() => {
    if (isActive) {
      requestRef.current = window.requestAnimationFrame(animate);
    }
    
    return () => {
      if (requestRef.current) {
        window.cancelAnimationFrame(requestRef.current);
      }
    };
  }, [isActive, animate]);
}
 
export default useAnimationFrame;