- Gallery
- Dashboard & Analytics
- LiveCounter
New
LiveCounter
Animated counting component with easing animation and formatting
Dashboard & Analyticscounteranimationlivenumber
Dependencies
shadcn/ui components needed:
npx shadcn@latest add cardHow to use this component
Copy the code below into your project. Make sure you have the required shadcn/ui dependencies installed. Then import and use the component in your pages or layouts.
Code
1"use client"23import * as React from "react"4import { Card, CardContent } from "@/components/ui/card"5import { Badge } from "@/components/ui/badge"6import { cn } from "@/lib/utils"78interface LiveCounterProps {9 target: number10 label: string11 prefix?: string12 duration?: number13 className?: string14}1516export function LiveCounter({ target, label, prefix = "", duration = 2000, className }: LiveCounterProps) {17 const [count, setCount] = React.useState(0)18 const [isAnimating, setIsAnimating] = React.useState(true)1920 React.useEffect(() => {21 let startTime: number | null = null22 const animate = (currentTime: number) => {23 if (!startTime) startTime = currentTime24 const elapsed = currentTime - startTime25 const progress = Math.min(elapsed / duration, 1)26 27 const easeOutExpo = (t: number) => {28 return t === 1 ? 1 : 1 - Math.pow(2, -10 * t)29 }30 31 setCount(Math.floor(easeOutExpo(progress) * target))32 33 if (progress < 1) {34 requestAnimationFrame(animate)35 } else {36 setIsAnimating(false)37 }38 }39 40 requestAnimationFrame(animate)41 }, [target, duration])4243 return (44 <Card className={cn("w-full", className)}>45 <CardContent className="p-6 flex flex-col items-center justify-center">46 <div className="flex items-center gap-2 mb-2">47 <Badge variant="outline" className="text-xs gap-1.5">48 <span className={cn("w-2 h-2 rounded-full bg-emerald-500", isAnimating ? "animate-pulse" : "")} />49 Live50 </Badge>51 </div>52 <p className={cn(53 "text-5xl font-bold tracking-tight tabular-nums",54 isAnimating && "animate-pulse"55 )}>56 {prefix}{count.toLocaleString()}57 </p>58 <p className="text-sm text-muted-foreground mt-2">{label}</p>59 </CardContent>60 </Card>61 )62}