Randomized Text Unveil

A randomized text effect component that creates dynamic and unpredictable animations for text elements before displaying the user-provided text.

Installation

npm install framer-motion @motionone/utils
text-randomized.tsx
1
'use client';
2
3
import React, { useEffect, useState, useCallback } from 'react';
4
5
const lettersAndSymbols = 'abcdefghijklmnopqrstuvwxyz!@#$%^&*-_+=;:<>,';
6
7
interface AnimatedTextProps {
8
text: string;
9
}
10
11
export function RandomizedTextEffect({ text }: AnimatedTextProps) {
12
const [animatedText, setAnimatedText] = useState('');
13
14
const getRandomChar = useCallback(
15
() =>
16
lettersAndSymbols[Math.floor(Math.random() * lettersAndSymbols.length)],
17
[]
18
);
19
20
const animateText = useCallback(async () => {
21
const duration = 50;
22
const revealDuration = 80;
23
const initialRandomDuration = 300;
24
25
const generateRandomText = () =>
26
text
27
.split('')
28
.map(() => getRandomChar())
29
.join('');
30
31
setAnimatedText(generateRandomText());
32
33
const endTime = Date.now() + initialRandomDuration;
34
while (Date.now() < endTime) {
35
await new Promise((resolve) => setTimeout(resolve, duration));
36
setAnimatedText(generateRandomText());
37
}
38
39
for (let i = 0; i < text.length; i++) {
40
await new Promise((resolve) => setTimeout(resolve, revealDuration));
41
setAnimatedText(
42
(prevText) =>
43
text.slice(0, i + 1) +
44
prevText
45
.slice(i + 1)
46
.split('')
47
.map(() => getRandomChar())
48
.join('')
49
);
50
}
51
}, [text, getRandomChar]);
52
53
useEffect(() => {
54
animateText();
55
}, [text, animateText]);
56
57
return <div className='relative inline-block'>{animatedText}</div>;
58
}