Skip to content

Commit 7f2cea6

Browse files
committed
Added typewritter effect hook
1 parent cda635f commit 7f2cea6

1 file changed

Lines changed: 49 additions & 0 deletions

File tree

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { useState, useEffect } from "react";
2+
3+
export function useTypewriter(
4+
text,
5+
speed = 150,
6+
eraseSpeed = 75,
7+
delay = 1000
8+
) {
9+
const [displayText, setDisplayText] = useState("");
10+
const [index, setIndex] = useState(0);
11+
const [isDeleting, setIsDeleting] = useState(false);
12+
const [cursorVisible, setCursorVisible] = useState(true);
13+
14+
useEffect(() => {
15+
let timeout;
16+
17+
if (!isDeleting && index < text.length) {
18+
// Typing effect
19+
timeout = setTimeout(() => {
20+
setDisplayText((prev) => prev + text[index]);
21+
setIndex(index + 1);
22+
}, speed);
23+
} else if (isDeleting && index > 0) {
24+
// Erasing effect
25+
timeout = setTimeout(() => {
26+
setDisplayText((prev) => prev.slice(0, -1));
27+
setIndex(index - 1);
28+
}, eraseSpeed);
29+
} else {
30+
// Pause before deleting or restarting
31+
timeout = setTimeout(() => {
32+
setIsDeleting((prev) => !prev);
33+
}, delay);
34+
}
35+
36+
return () => clearTimeout(timeout);
37+
}, [index, isDeleting, text, speed, eraseSpeed, delay]);
38+
39+
// Cursor blinking effect
40+
useEffect(() => {
41+
const cursorInterval = setInterval(() => {
42+
setCursorVisible((prev) => !prev);
43+
}, 500);
44+
45+
return () => clearInterval(cursorInterval);
46+
}, []);
47+
48+
return `${displayText}${cursorVisible ? "|" : ""}`;
49+
}

0 commit comments

Comments
 (0)