While building the landing page of Mindsaha, I needed a way to show a text using typewriter effect. Here is the final outcome.
Here's how I approached the problem and implemented a solution.
Designing a React Typewriter component
If you think about what a Typewriter component should do, it comes down to these points.
- The component accepts a
text
prop. - It then displays the characters in the given
text
one by one in certain duration (i.e. 500ms). This simulates the typing effect. - Once the full text has been displayed, it waits for some time.
- Finally, it clears the whole text, again one by one.
Once the text is cleared, the effect is done. The component then may switch to the next text or just repeat the whole process again.
With this initial design, let's get into the coding.
Coding the Typewriter component in React
import React, { useEffect, useState } from "react";
const TYPING_SPEED = 100;
const SHOW_TIME = 2000;
const DEL_SPEED = 25;
function TypeWriter({ text }) {
const [display, setDisplay] = useState(" ");
const [typing, setTyping] = useState(true);
// type the characters one by one
useEffect(() => {
if (!text || !text.trim().length) return;
let typingTimer;
if (typing) {
let idx = 0;
typingTimer = setInterval(() => {
if (idx <= text.length) {
setDisplay(text.substring(0, idx));
idx++;
} else {
// when all characters are typed, after SHOW_TIME set clear flag
clearInterval(typingTimer);
setTimeout(() => {
setTyping(false);
setClearing(true);
}, SHOW_TIME);
}
}, TYPING_SPEED);
}
return () => {
clearInterval(typingTimer);
};
}, [text, typing]);
// clear the characters one by one
const [clearing, setClearing] = useState(false);
useEffect(() => {
let clearTimer;
if (clearing) {
let idx = text.length - 1;
clearTimer = setInterval(() => {
if (idx >= 0) {
setDisplay(text.substring(0, idx));
idx--;
} else {
// when all characters cleared, reset and invoke the callback
clearInterval(clearTimer);
setClearing(false);
setTyping(true);
}
}, DEL_SPEED);
}
return () => {
if (clearTimer) {
clearInterval(clearTimer);
}
};
}, [clearing, text]);
return <span>{display || text[0]}</span>;
}
export default TypeWriter;
Typewriter text effect - Demo
Here is the demo of the above component. Feel free type in new text and animate.
React Typewriter Effect - Demo
Question to you?
What do you think about this implementation? If it is up to you, how would you go about it? Also, can you think of how the blinking cursor has been done, as seen in the Mindsaha landing page?