Scramble Text
wise-ui/scramble-textFreeComponent
Text that scrambles through random characters before resolving.
Live preview
live · rendered by the registry
Rendered by wise-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://wise-ui.com/r/scramble-text.jsonSource
1"use client"23import * as React from "react"4import { cn } from "@/registry/wise-ui/lib/utils"56interface ScrambleTextProps {7 text: string8 trigger?: "mount" | "hover"9 speed?: number10 characterSet?: string11 sequential?: boolean12 className?: string13}1415const DEFAULT_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%&*"1617function ScrambleText({18 text,19 trigger = "mount",20 speed = 50,21 characterSet = DEFAULT_CHARS,22 sequential = true,23 className,24}: ScrambleTextProps) {25 const [display, setDisplay] = React.useState(trigger === "mount" ? "" : text)26 const rafRef = React.useRef<number>(0)27 const startTimeRef = React.useRef<number>(0)2829 const scramble = React.useCallback(() => {30 cancelAnimationFrame(rafRef.current)31 startTimeRef.current = 03233 const chars = text.split("")34 const totalDuration = sequential35 ? chars.length * speed + speed * 336 : speed * 83738 const step = (timestamp: number) => {39 if (!startTimeRef.current) startTimeRef.current = timestamp40 const elapsed = timestamp - startTimeRef.current4142 let result = ""43 let allResolved = true4445 for (let i = 0; i < chars.length; i++) {46 if (chars[i] === " ") {47 result += " "48 continue49 }5051 const resolveAt = sequential ? i * speed + speed * 2 : speed * 452 if (elapsed >= resolveAt) {53 result += chars[i]54 } else {55 allResolved = false56 result += characterSet[Math.floor(Math.random() * characterSet.length)]57 }58 }5960 setDisplay(result)6162 if (!allResolved && elapsed < totalDuration) {63 rafRef.current = requestAnimationFrame(step)64 } else {65 setDisplay(text)66 }67 }6869 rafRef.current = requestAnimationFrame(step)70 }, [text, speed, characterSet, sequential])7172 React.useEffect(() => {73 if (trigger === "mount") {74 scramble()75 }76 return () => cancelAnimationFrame(rafRef.current)77 }, [trigger, scramble])7879 const handleMouseEnter = () => {80 if (trigger === "hover") {81 scramble()82 }83 }8485 return (86 <span87 className={cn("inline-block whitespace-pre", className)}88 onMouseEnter={handleMouseEnter}89 >90 {display || "\u00A0"}91 </span>92 )93}94ScrambleText.displayName = "ScrambleText"9596export { ScrambleText }97export type { ScrambleTextProps }
What it pulls in
npm packages
Files it writes
More from wise-ui
All 20 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Tabsanimated-tabs | wise-ui | Components | Free | 3 deps | |
| Border Beamborder-beam | wise-ui | Components | Free | 3 deps | |
| Data Tabledata-table | wise-ui | Components | Free | 3 deps | |
| Dockdock | wise-ui | Components | Free | 3 deps | |
| Dot Matrixdot-matrix | wise-ui | Components | Free | 2 deps | |
| Editable Texteditable-text | wise-ui | Components | Free | 4 deps | |
| Gradient Sidebargradient-sidebar | wise-ui | Components | Free | 3 deps | |
| Kanban Boardkanban-board | wise-ui | Components | Free | 6 deps |
