vue实现打字效果
html:
<div class="home-main-dictum-info"> <span>{{ dictumInfo }}</span> <span class="home-main-typed-cursor" :class="{ 'is-typed-cursor-anmation': watingTyped }">|</span> </div>
js:
const dictums = ref([ ['没有任何动物比蚂蚁更勤奋,然而它却最沉默寡言。', '出自:富兰克林'], ['勤劳一日,可得一夜安眠;勤劳一生,可得幸福长眠。', '出自:达芬奇'], ['学会学习的人,是非常幸福的人。', '出自:米南德'], ['我们自动的读书,即嗜好的读书,请教别人是大抵无用,只好先行泛览,然后决择而入于自己所爱的较专的一门或几门;但专读书也有弊病,所以必须和现实社会接触,使所读的书活起来。', '出自:鲁迅'], ['各种蠢事,在每天阅读书的影响下,仿佛在火上一样,渐渐溶化。', '出自:雨果'], ]); // 打字文本 const dictumInfo = ref(''); const timer = ref(null); const watingTyped = ref(false); const backTimer = ref(null); async function startPlay() { const newDictums = dictums.value.flat(); const tasks = newDictums.map((dictum) => { return createTask(async (resolve) => { let i = 0; timer.value = setInterval(async () => { dictumInfo.value = dictum.substring(0, i + 1); i++; if (i >= dictum.length) { if (timer.value) { clearInterval(timer.value); watingTyped.value = true; await sleep(800); watingTyped.value = false; backTimer.value = setInterval(async () => { dictumInfo.value = dictum.substring(0, i); i--; if (i < 0) { watingTyped.value = true; await sleep(200); watingTyped.value = false; resolve(); if (backTimer.value) clearInterval(backTimer.value); } }, 100); } } }, 250); }); }); await tasks.reduce((pre, next) => pre.then((ret) => next(ret)), Promise.resolve()); startPlay(); } function createTask(cb) { return () => new Promise((resolve) => { cb(resolve); }); } function sleep(delay = 500) { return new Promise((resolve) => { setTimeout(resolve, delay); }); } startPlay()
scss:
.home-main-dictum-info { font-size: 24px; height: 200px; display: flex; flex-direction: row; align-items: center; justify-content: center; line-height: 40px; } .home-main-typed-cursor { margin-left: 4px; font-size: 28px; } .is-typed-cursor-anmation { animation: typed 0.5s ease infinite alternate; }
效果(无法发动图,只截了个图):
希望大佬看到有不对的地方,提出博主予以改正!