Text Scramble
Text animation that transforms text by randomly cycling through characters before settling on the final content, creating an engaging cryptographic effect.
Examples
Text Scramble Basic
Text Scramble
Text Scramble with custom trigger
Text Scramble with custom character and duration
Generating the interface...
Code
'use client';
import { type JSX, useEffect, useState } from 'react';
import { motion, MotionProps } from 'framer-motion';
type TextScrambleProps = {
children: string;
duration?: number;
speed?: number;
characterSet?: string;
as?: React.ElementType;
className?: string;
trigger?: boolean;
onScrambleComplete?: () => void;
} & MotionProps;
const defaultChars =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
export function TextScramble({
children,
duration = 0.8,
speed = 0.04,
characterSet = defaultChars,
className,
as: Component = 'p',
trigger = true,
onScrambleComplete,
...props
}: TextScrambleProps) {
const MotionComponent = motion.create(
Component as keyof JSX.IntrinsicElements
);
const [displayText, setDisplayText] = useState(children);
const [isAnimating, setIsAnimating] = useState(false);
const text = children;
const scramble = async () => {
if (isAnimating) return;
setIsAnimating(true);
const steps = duration / speed;
let step = 0;
const interval = setInterval(() => {
let scrambled = '';
const progress = step / steps;
for (let i = 0; i < text.length; i++) {
if (text[i] === ' ') {
scrambled += ' ';
continue;
}
if (progress * text.length > i) {
scrambled += text[i];
} else {
scrambled +=
characterSet[Math.floor(Math.random() * characterSet.length)];
}
}
setDisplayText(scrambled);
step++;
if (step > steps) {
clearInterval(interval);
setDisplayText(text);
setIsAnimating(false);
onScrambleComplete?.();
}
}, speed * 1000);
};
useEffect(() => {
if (!trigger) return;
scramble();
}, [trigger]);
return (
<MotionComponent className={className} {...props}>
{displayText}
</MotionComponent>
);
}
Component API
TextScramble
Prop | Type | Default | Description |
---|---|---|---|
children | string | The text content to be animated. | |
as | keyof JSX.IntrinsicElements | 'p' | The HTML tag to render, defaults to paragraph. |
duration | number | 0.8 | Duration of the effect. |
speed | number | 0.04 | Speed of the effect. |
characterSet | string | ABCDEF...z0123456789 | Set of characters for the scramble effect |
className | string | undefined | Optional CSS class for styling the component. |
trigger | boolean | undefined | Controls whether the animation should be triggered. |
onScrambleComplete | () => void | undefined | Callback function when the animation completes. |