animated-number
vengenceui/animated-numberFreeComponent
vengenceui publishes no description for this item.
Live preview
live · rendered by the registry
Rendered by vengenceui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://www.vengenceui.com/r/animated-number.jsonSource
1"use client"23import React, { useEffect, useRef, useState } from 'react'4import { motion, AnimatePresence } from "framer-motion"5import { cn } from "@/lib/utils"67function AnimatedNumber({ value, className }: { value: number, className?: string }) {8 return (9 <div className={cn("flex items-center", className)}>10 <div className="flex relative items-center">11 {value.toString().split("").map((digit, index) => (12 <SingleNumberHolder key={index} value={digit} index={index} />13 ))}14 </div>15 </div>16 )17}1819function SingleNumberHolder({ value, index }: { value: string, index: number }) {20 const [height, setHeight] = useState<string | null>(null)21 const containerRef = useRef<HTMLDivElement>(null)22 let notANumber = false2324 useEffect(() => {25 if (containerRef.current) {26 setHeight(getComputedStyle(containerRef.current).height)27 }28 }, [])2930 if (index === 0) {31 notANumber = isNaN(Number.parseInt(value))32 }3334 const vars = {35 init: { opacity: 0 },36 animate: { opacity: 1 },37 exit: { opacity: 0 },38 }3940 return (41 <div42 className="relative"43 style={{ height: height || "auto", overflowY: "hidden", overflowX: "clip" }}44 ref={containerRef}45 >46 {notANumber && (47 <motion.span48 initial="init"49 animate="animate"50 exit="exit"51 variants={vars}52 key={value}53 layout="size"54 >55 {value}56 </motion.span>57 )}58 {!notANumber && <RenderStrip value={value} eleHeight={height} />}59 </div>60 )61}6263const zeroToNine = Array.from({ length: 10 }, (_, k) => k)6465function RenderStrip({ eleHeight, value }: { eleHeight: string | null, value: string }) {66 const heightInNumber = Number.parseInt(eleHeight?.replace("px", "") || "48")67 const negative = heightInNumber * -168 const pos = heightInNumber69 const prev = useRef(value)7071 // Convert string values to numbers for comparison72 const currentVal = parseInt(value)73 const prevVal = parseInt(prev.current)7475 // Calculate direction based on value change76 const diff = prevVal - currentVal77 const dir = currentVal > prevVal ? pos * diff * -1 : negative * diff7879 // Update ref after calculation80// … truncated
What it pulls in
npm packages
Files it writes
More from vengenceui
All 128 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| accordionaccordion | vengenceui | Components | Free | 2 deps | |
| agent-bento-gridagent-bento-grid | vengenceui | Components | Free | 1 dep | |
| alertalert | vengenceui | Components | Free | no deps | |
| animated-buttonanimated-button | vengenceui | Components | Free | 1 dep | |
| animated-footeranimated-footer | vengenceui | Components | Free | 2 deps | |
| animated-raysanimated-rays | vengenceui | Components | Free | no deps | |
| animated-tooltipanimated-tooltip | vengenceui | Components | Free | 1 dep | |
| ascii-glitch-rippleascii-glitch-ripple | vengenceui | Components | Free | no deps |
