judge4c/src/components/typing-effect.tsx

53 lines
1.5 KiB
TypeScript

"use client";
import { motion } from "framer-motion";
import { useTranslations } from "next-intl";
import { useEffect, useState, useMemo } from "react";
export function TypingEffect() {
const t = useTranslations("HomePage.MainView.features");
const texts = useMemo(
() => [t("feature1"), t("feature2"), t("feature3")],
[t]
);
const [index, setIndex] = useState(0);
const [displayText, setDisplayText] = useState("");
const [isDeleting, setIsDeleting] = useState(false);
useEffect(() => {
const handleTyping = () => {
const currentText = texts[index];
if (isDeleting) {
setDisplayText(currentText.substring(0, displayText.length - 1));
} else {
setDisplayText(currentText.substring(0, displayText.length + 1));
}
if (!isDeleting && displayText === currentText) {
setTimeout(() => setIsDeleting(true), 1000);
} else if (isDeleting && displayText === "") {
setIsDeleting(false);
setIndex((prevIndex) => (prevIndex + 1) % texts.length);
}
};
const typingSpeed = isDeleting ? 50 : 100;
const timer = setTimeout(handleTyping, typingSpeed);
return () => clearTimeout(timer);
}, [displayText, isDeleting, index, texts]);
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="inline-block"
>
{displayText}
<span className="blinking-cursor">|</span>
</motion.div>
);
}