Animate Digits
unlumen-ui/animate-digitsFreeComponent
Per-digit blur-slide animation — only the digits that change animate.
Live preview
live · rendered by the registry
Rendered by Unlumen Ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.unlumen.com/r/animate-digits.jsonSource
1"use client";23import { useEffect, useRef, useState } from "react";4import { AnimatePresence, motion, useSpring, useTransform } from "motion/react";56import { cn } from "@/lib/utils";78interface AnimateDigitsProps {9 value: string;10 gap?: number;11 className?: string;12 digitClassName?: string;13 enterStiffness?: number;14 enterDamping?: number;15 exitStiffness?: number;16 exitDamping?: number;17 direction?: "dynamic" | "up" | "down";18 enterY?: number;19 enterBlur?: number;20 enterScale?: number;21 animationDelay?: number;22}2324interface ExitItem {25 id: number;26 char: string;27 exitY: number;28}2930let _id = 0;3132function DigitCell({33 char,34 isDigit,35 className,36 enterStiffness = 170,37 enterDamping = 10,38 exitStiffness = 170,39 exitDamping = 15,40 direction = "dynamic",41 enterY = 32,42 enterBlur = 52,43 enterScale = 0.7,44}: {45 char: string;46 isDigit: boolean;47 className?: string;48 enterStiffness?: number;49 enterDamping?: number;50 exitStiffness?: number;51 exitDamping?: number;52 direction?: "dynamic" | "up" | "down";53 enterY?: number;54 enterBlur?: number;55 enterScale?: number;56}) {57 const [exitQueue, setExitQueue] = useState<ExitItem[]>([]);5859 const prevCharRef = useRef(char);60 const isFirstRender = useRef(true);6162 // Springs — jump() snaps the spring itself (position + velocity reset)63 const springConfig = { stiffness: enterStiffness, damping: enterDamping };64 const y = useSpring(0, springConfig);65 const opacity = useSpring(1, springConfig);66 const scale = useSpring(1, springConfig);67 const blur = useSpring(0, springConfig);68 const filter = useTransform(blur, (v) => `blur(${v}px)`);6970 useEffect(() => {71 if (!isDigit) return;7273 const prev = prevCharRef.current;74 prevCharRef.current = char;7576 if (isFirstRender.current) {77 isFirstRender.current = false;78 return;79 }8081 if (char === prev || !/\d/.test(prev)) return;8283 const up =84 direction === "dynamic"85 ? Number(char) > Number(prev)86 : direction === "up";8788 const id = _id++;89 setExitQueue((q) => {90 const next = [...q, { id, char: prev, exitY: up ? -enterY : enterY }];91 return next.length > 3 ? next.slice(-3) : next;92 });9394 y.jump(up ? enterY : -enterY);95 opacity.jump(0);96 scale.jump(enterScale);97 blur.jump(enterBlur);9899 y.set(0);100 opacity.set(1);101 scale.set(1);102 blur.set(0);103 }, [104 char,105 isDigit,106 direction,107 enterY,108 enterBlur,109 enterScale,110 y,111 opacity,112// … truncated
What it pulls in
npm packages
Files it writes
More from Unlumen Ui
All 233 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| AI Chatai-chat | Unlumen Ui | Components | Paid | 2 deps | |
| Vercel Animate Countanimate-count | Unlumen Ui | Components | Free | 1 dep | |
| Animated Inputanimate-text-input-typing | Unlumen Ui | Components | Paid | 1 dep | |
| Animated Listanimated-list | Unlumen Ui | Components | Free | 1 dep | |
| Apple Switchapple-switch | Unlumen Ui | Components | Free | 1 dep | |
| Aurora Barsaurora-bars | Unlumen Ui | Components | Free | 1 dep | |
| Aurora Bluraurora-blur | Unlumen Ui | Components | Free | 2 deps | |
| Aurora Cardaurora-card | Unlumen Ui | Components | Paid | 2 deps |
