+
diff --git a/src/components/TypingEffect.tsx b/src/components/TypingEffect.tsx
index 1a04628..86e78c1 100644
--- a/src/components/TypingEffect.tsx
+++ b/src/components/TypingEffect.tsx
@@ -1,48 +1,47 @@
import { useInView } from "motion/react";
import { useRef, useEffect, useState } from "react";
-export default function TypingEffect({ text = 'Typing Effect', speed = 0.1 }: { text: string, speed?: number }) {
+export default function TypingEffect({
+ text = "Typing Effect",
+ speed = 0.05,
+}: {
+ text: string;
+ speed?: number;
+}) {
const ref = useRef
(null);
const isInView = useInView(ref, { once: true });
+
const [visibleChars, setVisibleChars] = useState(0);
-
- // Split text into lines
- const lines = text.split('\n');
-
+
+ const lines = text.split("\n");
+ const totalChars = text.replace(/\n/g, "").length;
+
useEffect(() => {
if (!isInView) return;
-
- let currentIndex = 0;
- const totalChars = text.replace(/\n/g, '').length;
-
+
const interval = setInterval(() => {
- if (currentIndex < totalChars) {
- currentIndex++;
- setVisibleChars(currentIndex);
- } else {
- clearInterval(interval);
- }
+ setVisibleChars((prev) => {
+ if (prev >= totalChars) return 0; // loop
+ return prev + 1;
+ });
}, speed * 1000);
-
+
return () => clearInterval(interval);
- }, [isInView, text, speed]);
-
- // Build visible text based on visible characters
+ }, [isInView, totalChars, speed]);
+
+ // Build visible overlay text
let charsProcessed = 0;
const visibleLines: string[] = [];
-
+
for (const line of lines) {
const lineLength = line.length;
+
if (charsProcessed + lineLength <= visibleChars) {
- // Full line is visible
visibleLines.push(line);
charsProcessed += lineLength;
} else {
- // Partial line
- const remainingChars = visibleChars - charsProcessed;
- if (remainingChars > 0) {
- visibleLines.push(line.slice(0, remainingChars));
- }
+ const remaining = visibleChars - charsProcessed;
+ if (remaining > 0) visibleLines.push(line.slice(0, remaining));
break;
}
}
@@ -53,11 +52,11 @@ export default function TypingEffect({ text = 'Typing Effect', speed = 0.1 }: {
ref={ref}
className="text-sm text-left font-mono text-base-content/70 tracking-tighter absolute bottom-0"
>
+ {lines.map((line, i) => (
+ {line}
+ ))}
{visibleLines.map((line, index) => (
-
- {line}
- {index < visibleLines.length - 1 &&
}
-
+ {line}
))}