Files
dashboard/frontend/src/hooks/useCountUp.ts
2026-03-12 08:16:34 +01:00

43 lines
1.1 KiB
TypeScript

import { useState, useEffect, useRef } from 'react';
export function useCountUp(target: number, duration: number = 1000): number {
const [current, setCurrent] = useState(0);
const rafRef = useRef<number>(0);
const currentRef = useRef<number>(0);
useEffect(() => {
if (target === 0) {
setCurrent(0);
currentRef.current = 0;
return;
}
const startTime = performance.now();
const startValue = currentRef.current;
const animate = (now: number) => {
const elapsed = now - startTime;
const t = Math.min(elapsed / duration, 1);
// ease-out cubic: 1 - (1-t)^3
const eased = 1 - Math.pow(1 - t, 3);
const value = Math.round(startValue + (target - startValue) * eased);
setCurrent(value);
currentRef.current = value;
if (t < 1) {
rafRef.current = requestAnimationFrame(animate);
}
};
rafRef.current = requestAnimationFrame(animate);
return () => {
if (rafRef.current) {
cancelAnimationFrame(rafRef.current);
}
};
}, [target, duration]);
return current;
}