title: typeWriter slug: typeWriter date: 2024-8-16 id: 8 tags: - js 打字机首页上的slogan打字机效果,是从别的blog中借鉴,并加以思考码出来的。效果实现不难,在开始之前,先分析需求。首先是循环出现的slogans,因此一个slogans数组肯定是需要的const slogans = []考虑到组件复用,我们需要传递该attr,因此定义组件const TypeWriter = ({texts}) = >{return //...}同样的,响应式需求肯定需要useState和监听钩子useEffect根据需求来看,当前正在展示的文本需要进行状态管理,当前文本的索引index(slogans的索引)和文本内索引index也需要进行管理(逐字打印,对应index)再根据效果来看,打字和打完字也需要进行管理,因为该slogan打完之后会进行回退删除由以上需求来看,代码其实已经显而易见component/TypeWriter/TypeWriter.js"use client" import {useState,useEffect} from 'react'; import styles from './TypeWriter.module.css' const TypeWriter = ({texts, typingSpeed = 150, deletedSpeed = 75, pauseDuration = 2000})=>{ const [dispayText,setDisplayText] = useState(''); const [isTyping,setIsTyping] = useState(true); const [currentIndex,setCurrentIndex] = useState(0); const [currentTextIndex,setCurrentTextIndex] = useState(0); useEffect(()=>{ let timer; if(isTyping){ if(currentIndex<texts[currentTextIndex].length){ timer = setTimeout(()=>{ setDisplayText(prev=>prev+texts[currentTextIndex][currentIndex]); setCurrentIndex(prev=>prev+1); },typingSpeed); } else{ setIsTyping(false); timer = setTimeout(() => { setIsTyping(true); setCurrentIndex(texts[currentTextIndex].length - 1); }, pauseDuration); } } else{ if (currentIndex >= 0) { timer = setTimeout(() => { setDisplayText(prev => prev.slice(0, -1)); setCurrentIndex(prev => prev - 1); }, deletingSpeed); } else { setIsTyping(true); setCurrentIndex(0); setCurrentTextIndex((prev) => (prev + 1) % texts.length); } } return ()=>clearTimeout(timer); },[currentIndex, isTyping, texts, currentTextIndex, typingSpeed, deletingSpeed, pauseDuration]); return <div>{displayText}<span className={styles.animation}>|</span></div>; }; export default TypeWriter;component/TypeWriter/TypeWriter.module.css@keyframes blink { 0% { opacity: 0; } 50% { opacity: 1; } 100% { opacity: 0; } } .animation{ animation: blink 1s infinite; }