"use client"; import { useEffect, useRef, useState } from "react"; interface AnimatedCounterProps { value: number; className?: string; duration?: number; } export function AnimatedCounter({ value, className, duration = 1800, }: AnimatedCounterProps) { const [displayValue, setDisplayValue] = useState(0); const [isVisible, setIsVisible] = useState(false); const [hasAnimated, setHasAnimated] = useState(false); const ref = useRef(null); useEffect(() => { if (hasAnimated) return; const element = ref.current; if (!element) return; const observer = new IntersectionObserver( (entries) => { if (entries[0].isIntersecting) { setIsVisible(true); setHasAnimated(true); observer.disconnect(); const startTime = performance.now(); function animate(currentTime: number) { const elapsed = currentTime - startTime; const progress = Math.min(elapsed / duration, 1); // Ease-out cubic for smooth deceleration const eased = 1 - Math.pow(1 - progress, 3); setDisplayValue(Math.floor(eased * value)); if (progress < 1) { requestAnimationFrame(animate); } else { setDisplayValue(value); } } requestAnimationFrame(animate); } }, { threshold: 0.1 } ); observer.observe(element); return () => observer.disconnect(); }, [value, duration, hasAnimated]); return (

{displayValue.toLocaleString("en-US")}

); }