Animated Counter
Smooth number counting animation with spring physics
animationcounternumberspring
Install dependencies
$npm install framer-motionPreview
Source Code
"use client";
import { useEffect, useRef } from "react";
import { useInView, useMotionValue, useSpring, motion } from "framer-motion";
interface AnimatedCounterProps {
value: number;
duration?: number;
className?: string;
}
export default function AnimatedCounter({
value,
duration = 2,
className = "",
}: AnimatedCounterProps) {
const ref = useRef<HTMLSpanElement>(null);
const motionValue = useMotionValue(0);
const springValue = useSpring(motionValue, {
damping: 40,
stiffness: 100,
duration: duration * 1000,
});
const isInView = useInView(ref, { once: true, margin: "0px" });
useEffect(() => {
if (isInView) {
motionValue.set(value);
}
}, [motionValue, isInView, value]);
useEffect(() => {
const unsubscribe = springValue.on("change", (latest) => {
if (ref.current) {
ref.current.textContent = Math.round(latest).toLocaleString();
}
});
return unsubscribe;
}, [springValue]);
return (
<motion.span ref={ref} className={className}>
0
</motion.span>
);
}