49 lines
1.5 KiB
TypeScript
49 lines
1.5 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import { Text } from 'react-native';
|
|
|
|
interface TypewriterTextProps {
|
|
text: string;
|
|
speed?: number; // 打字速度(毫秒)
|
|
loop?: boolean; // 是否循环播放
|
|
delay?: number; // 每轮之间的延迟时间
|
|
}
|
|
|
|
const TypewriterText: React.FC<TypewriterTextProps> = ({
|
|
text,
|
|
speed = 100,
|
|
loop = false,
|
|
delay = 2000,
|
|
}) => {
|
|
const [displayedText, setDisplayedText] = useState<string>(text[0] || ''); // 初始为第一个字符
|
|
const [currentIndex, setCurrentIndex] = useState<number>(1); // 从第2个字符开始
|
|
|
|
useEffect(() => {
|
|
let typingTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
let resetTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
|
|
if (currentIndex < text.length) {
|
|
// 正常打字过程
|
|
typingTimeout = setTimeout(() => {
|
|
setDisplayedText(text.slice(0, currentIndex + 1));
|
|
setCurrentIndex((prev) => prev + 1);
|
|
}, speed);
|
|
} else if (loop) {
|
|
// 当前一轮完成,等待 delay 后重新开始
|
|
resetTimeout = setTimeout(() => {
|
|
setCurrentIndex(1); // 从第2个字符重新开始
|
|
setDisplayedText(text[0] || ''); // 重置显示文本
|
|
}, delay);
|
|
}
|
|
|
|
return () => {
|
|
if (typingTimeout) clearTimeout(typingTimeout);
|
|
if (resetTimeout) clearTimeout(resetTimeout);
|
|
};
|
|
}, [currentIndex, text, speed, loop, delay]);
|
|
|
|
return (
|
|
<Text>{displayedText}</Text>
|
|
);
|
|
};
|
|
|
|
export default TypewriterText; |