'use client'; import { useState, useEffect, useRef } from 'react'; interface UseCountUpOptions { end: number; duration?: number; start?: number; decimals?: number; easing?: (t: number) => number; enabled?: boolean; } const easeOutCubic = (t: number) => 1 - Math.pow(1 - t, 3); export function useCountUp({ end, duration = 1800, start = 0, decimals = 0, easing = easeOutCubic, enabled = true, }: UseCountUpOptions) { const [value, setValue] = useState(start); const startTimeRef = useRef(null); const frameRef = useRef(0); useEffect(() => { if (!enabled) { setValue(end); return; } setValue(start); startTimeRef.current = null; const animate = (now: number) => { if (startTimeRef.current === null) { startTimeRef.current = now; } const progress = Math.min((now - startTimeRef.current) / duration, 1); const eased = easing(progress); const current = start + (end - start) * eased; setValue(Number(current.toFixed(decimals))); if (progress < 1) { frameRef.current = requestAnimationFrame(animate); } else { setValue(end); } }; frameRef.current = requestAnimationFrame(animate); return () => { cancelAnimationFrame(frameRef.current); }; }, [end, duration, start, decimals, easing, enabled]); return value; }