38 lines
815 B
TypeScript
38 lines
815 B
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
export function useCountUp(
|
|
target: number,
|
|
isActive: boolean,
|
|
duration = 2000,
|
|
decimals = 0
|
|
) {
|
|
const [count, setCount] = useState(0);
|
|
|
|
useEffect(() => {
|
|
if (!isActive) return;
|
|
|
|
const startTime = Date.now();
|
|
const startValue = 0;
|
|
|
|
const tick = () => {
|
|
const elapsed = Date.now() - startTime;
|
|
const progress = Math.min(elapsed / duration, 1);
|
|
// Ease out cubic
|
|
const eased = 1 - Math.pow(1 - progress, 3);
|
|
const current = startValue + (target - startValue) * eased;
|
|
|
|
setCount(Number(current.toFixed(decimals)));
|
|
|
|
if (progress < 1) {
|
|
requestAnimationFrame(tick);
|
|
}
|
|
};
|
|
|
|
requestAnimationFrame(tick);
|
|
}, [isActive, target, duration, decimals]);
|
|
|
|
return count;
|
|
}
|