WebberUI

Scramble Text

Decryption-style text animation — characters churn through random glyphs and lock in from left to right, triggered by viewport or hover.

Loading preview…
npx shadcn@latest add https://webberui.com/r/scramble-text.json

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

0.05
<ScrambleText />

Installation

npx shadcn@latest add https://webberui.com/r/scramble-text.json

Or, once registries are configured in components.json, install it as @webberui/scramble-text.

Usage

import { ScrambleText } from "@/components/ui/scramble-text";

<ScrambleText
  text="WEBBERUI DECRYPTED"
  className="font-mono text-4xl font-bold"
/>

Hover-to-replay mode, and mixed Chinese/English is no problem:

<ScrambleText text="Hover me: decryption animation" trigger="hover" duration={0.04} />

A custom scramble character set (for example a hacker-style 0 and 1):

<ScrambleText text="BINARY MODE" charset="01" className="font-mono" />

Props

PropTypeDefaultDescription
textstringThe target text; Chinese and emoji are both fine
durationnumber0.05Interval at which each character locks in (seconds); smaller decrypts faster
charsetstringalphanumerics + symbolsThe character set used for the scramble churn
trigger"view" | "hover""view"Play automatically on entering the viewport, or replay on mouse hover
oncebooleantrueWith trigger="view", plays only the first time the element enters the viewport

How it works

  • At its core is a single requestAnimationFrame loop: it computes how many characters have locked in from the elapsed time (one more character locks from the left every duration seconds), and every 2 frames the unlocked positions draw a new random glyph from charset, so the per-frame flicker is not too harsh. The animation writes straight into the DOM text node and does not trigger a React re-render; the previous rAF is cancelled on unmount and on replay
  • Grapheme splitting uses Intl.Segmenter, so Chinese characters, emoji, and combining characters each count as one unit. Locking in restores the original character directly, so Chinese target text works exactly the same, while the scramble churn always uses charset
  • Whitespace does not scramble, keeping line width and line breaking stable throughout the animation
  • Character width jitter: scrambled glyphs have different widths, so the layout jumps sideways. Pairing with font-mono (a monospaced font) is recommended, or at least tabular-nums in mostly numeric scenarios. When the target text contains Chinese, the width difference between Chinese and Latin makes the jitter more obvious, and a monospaced font works best
  • Accessibility: the complete text lives in an sr-only element and the animation layer is marked aria-hidden, so the screen reader always reads a complete sentence instead of scrambled glyphs; when the user has "reduce motion" enabled at the system level, the final text is shown directly with no animation
  • With once={false} and trigger="view", leaving and re-entering the viewport replays the animation; with trigger="hover" the text is shown statically and decrypts again on every mouse enter

On this page