35 lines
896 B
TypeScript
35 lines
896 B
TypeScript
"use client";
|
|
import { useEffect, useRef, useState } from "react";
|
|
import { useInView } from "framer-motion";
|
|
|
|
export default function AnimatedCounter({ target, suffix = "" }: { target: number; suffix?: string }) {
|
|
const [count, setCount] = useState(0);
|
|
const ref = useRef(null);
|
|
const inView = useInView(ref, { once: true });
|
|
|
|
useEffect(() => {
|
|
if (!inView) return;
|
|
const duration = 1800;
|
|
const steps = 60;
|
|
const increment = target / steps;
|
|
let current = 0;
|
|
const timer = setInterval(() => {
|
|
current += increment;
|
|
if (current >= target) {
|
|
setCount(target);
|
|
clearInterval(timer);
|
|
} else {
|
|
setCount(Math.floor(current));
|
|
}
|
|
}, duration / steps);
|
|
return () => clearInterval(timer);
|
|
}, [inView, target]);
|
|
|
|
return (
|
|
<span ref={ref}>
|
|
{count.toLocaleString("tr-TR")}
|
|
{suffix}
|
|
</span>
|
|
);
|
|
}
|