掘金 人工智能 17小时前
前端web用一个函数实现打字机效果
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

文章分享了如何在前端实现打字机效果,特别是在后端接口不支持流式输出的情况下。作者通过一个简洁的函数`printMessageTimer`,成功模拟了流式输出,并提供了React组件的实现示例。这不仅简化了代码,也提高了用户体验。文章强调了代码的简洁性和实用性,展示了如何用较少的代码实现复杂的功能。

⌨️ 文章的核心在于`printMessageTimer`函数,该函数接受文本信息、回调函数以及控制打字速度和每次显示字符数量的参数。它使用`requestAnimationFrame`实现动画效果,模拟了流式输出。

⚙️ `printMessageTimer`函数内部通过`_index`变量跟踪当前显示的字符位置,`lastTime`变量记录上次更新时间,`deltaTime`计算时间间隔,以控制打字速度。当`_index`超过文本长度时,停止动画。

⚛️ 文章提供了React组件的示例,展示了如何使用`printMessageTimer`函数。组件通过`useEffect`钩子在组件挂载时调用该函数,并将结果传递给`MarkdownRenderer`组件进行渲染,实现了打字机效果。

前言

核心代码看这里!!!

/*** web模拟流式输出效果* @params {string} msg 文本信息* @params callback 定时返回追加信息* @params {{ speedMs: number, indexSpan: number }} speedMs=打字间隔时间(毫秒);indexSpan=每一轮打字的数量*/function printMessageTimer(msg: string, callback: (text: string) => void, { speedMs, indexSpan }: { speedMs: number, indexSpan: number } = { speedMs: 100, indexSpan: 20 }) {  const _msg = msg;  let _index = 0;  let lastTime: number | null = null;    function animate(currentTime: number) {    if (!lastTime) lastTime = currentTime;    const deltaTime = currentTime - lastTime;        // Update every ~100ms (adjustable)    if (deltaTime >= speedMs) {      if (_index >= _msg.length) {        callback(_msg);        lastTime = null;        _index = 0;        return;      }            callback(_msg.substring(0, _index)  + " [[CURSOR]]");      _index += indexSpan;      lastTime = currentTime;    }        requestAnimationFrame(animate);  }    return function() {    requestAnimationFrame(animate);  };}

组件使用案例

import { useEffect, useState } from 'react'import MarkdownRenderer from '../components/MarkdownRenderer'function printMessageTimer(msg: string, callback: (text: string) => void, { speedMs, indexSpan }: { speedMs: number, indexSpan: number } = { speedMs: 100, indexSpan: 20 }) {  const _msg = msg;  let _index = 0;  let lastTime: number | null = null;    function animate(currentTime: number) {    if (!lastTime) lastTime = currentTime;    const deltaTime = currentTime - lastTime;        // Update every ~100ms (adjustable)    if (deltaTime >= speedMs) {      if (_index >= _msg.length) {        callback(_msg);        lastTime = null;        _index = 0;        return;      }            callback(_msg.substring(0, _index)  + " [[CURSOR]]");      _index += indexSpan;      lastTime = currentTime;    }        requestAnimationFrame(animate);  }    return function() {    requestAnimationFrame(animate);  };}export default function AiChatMarkdownCard({ message, animationEnabled=true }: { message: string, animationEnabled?: boolean }) {  const [printMessage, setPrintMessage] = useState('')  useEffect(() => {    if (animationEnabled) {      printMessageTimer(message, setPrintMessage)()    } else {      setPrintMessage(message)    }  }, [])  return <MarkdownRenderer    content={printMessage}  />}

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

前端 打字机效果 React 流式输出 printMessageTimer
相关文章