// FREE TOOLSView all →
◈Keyword ResearchFreeReal Google + Bing suggestions, grouped by intent.◆Image MakerNewBlog thumbnails, OG images & social cards in seconds.
▣Meta & SERP PreviewsoonSee how your page looks in Google, fix title & description.
◐AI Visibility ChecksoonWhat AI assistants say about your brand.
❖Schema GeneratorsoonCopy-paste JSON-LD for FAQ, Article, Product & more.
← all components
#09
Decrypt text reveal
Text that 'decrypts' itself: each character locks into place one by one while the unresolved characters flicker through random glyphs, like a terminal decoding a message. It runs on mount and again on hover. Pure JavaScript, no dependencies.
ReactJSText
// LIVE DEMO
// HOVER TO DECRYPT
DECRYPTING SIGNALaccess grantedHover any line to run it again.
// THE CODE
React
"use client";
import { useEffect, useRef, useState } from "react";
const GLYPHS = "!<>-_\\/[]{}=+*^?#0123456789ABCDEF";
export function Scramble({ text, className }) {
const [out, setOut] = useState(text);
const raf = useRef(0);
const run = () => {
const start = performance.now(), dur = 900;
const per = text.split("").map(() => ({ delay: Math.random()*400, settle: 200 + Math.random()*300 }));
const tick = (now) => {
const t = now - start; let done = true;
const chars = text.split("").map((ch, i) => {
if (ch === " ") return " ";
const c = per[i];
if (t < c.delay) { done = false; return GLYPHS[(Math.floor(t/40)+i) % GLYPHS.length]; }
if (t < c.delay + c.settle) { done = false; return GLYPHS[Math.floor(Math.random()*GLYPHS.length)]; }
return ch;
});
setOut(chars.join(""));
(!done && t < dur + 500) ? raf.current = requestAnimationFrame(tick) : setOut(text);
};
cancelAnimationFrame(raf.current); raf.current = requestAnimationFrame(tick);
};
useEffect(() => { run(); return () => cancelAnimationFrame(raf.current); }, [text]);
return <span onMouseEnter={run} className={`font-mono cursor-pointer whitespace-pre ${className||""}`}>{out}</span>;
}// HOW IT WORKS
- 01Each character gets a random delay and a random settle time, so they resolve at staggered moments instead of all at once.
- 02Before a character resolves it shows random glyphs from a set; after its settle window it snaps to the real letter.
- 03A single requestAnimationFrame loop rebuilds the string each frame until every character is locked, then stops.
- 04Spaces are preserved, and hovering re-triggers the whole decode.
Want a custom component for your product?
Let's build it →