前言
随着2024年国内业务需求的持续发展,前端领域打字机效果组件已广泛应用于多种网站和应用程序中,有效增强了网站的动态性与交互性。本文旨在深入探讨如何从基础开始,逐步开发实现简易版的一个打字机效果的流式组件,包括示例代码及其详细解释。
效果
一、初始准备
开始开发前,我们首先需要准备一些基础内容。本次示例中,我们将以一个Markdown文本数据作为打字机效果的内容来源。这不仅能够模拟实际开发中的场景,也便于我们展示如何处理和展示复杂文本。
示例Markdown文本
我们的Markdown文本包含了标题、文本格式(如粗体、斜体)、图片和表格等元素,这些都是Markdown常用的标记元素。通过对这些不同类型的内容进行逐字展示,我们可以演示打字机效果处理复杂文本的能力。
export const mockMarkdownStr = `
# Markdown 流式文章示例
Markdown是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档。Markdown编写的文档后缀为 \`.md\`。在这篇文章中,我将向您展示如何使用Markdown创建一篇包含标题、文本、图片和表格的文章。
## 标题
在Markdown中,标题是通过在文字前面加上 \`#\` 来表示的。\`#\` 的数量代表标题的级别。例如,一个 \`#\` 代表一级标题,两个 \`##\` 代表二级标题,以此类推。
## 文本
Markdown支持普通的文本格式,如粗体、斜体、删除线和下划线。您可以使用以下方式创建这些文本格式:
- **粗体**:使用两个 \`\*\` 或 \`_\` 包围文本,例如 \`\*\*粗体\*\*\` 或 \`__粗体__\`
- *斜体*:使用一个 \`\*\` 或 \`_\` 包围文本,例如 \`\*斜体\*\` 或 \`_斜体_\`
- ~~删除线~~:使用两个 \`~\` 包围文本,例如 \`~~删除线~~\`
- <u>下划线</u>:使用HTML标签 \`<u>\` 和 \`</u>\` 包围文本,例如 \`<u>下划线</u>\`
## 图片
在Markdown中,您可以使用以下语法插入图片:
\`\`\`
![图片描述](图片地址 "可选的标题")
\`\`\`
例如:
\`\`\`
![这是一张小米SU7图片](https://s1.xiaomiev.com/activity-outer-assets/0328/images/su7/su7_1.jpg)
\`\`\`
## 表格
Markdown支持简单的表格创建。您可以使用以下语法创建表格:
\`\`\`
| 标题1 | 标题2 | 标题3 |
|-------|-------|-------|
| 单元格1 | 单元格2 | 单元格3 |
| 单元格4 | 单元格5 | 单元格6 |
\`\`\`
例如:
\`\`\`
| 姓名 | 年龄 | 性别 |
|------|------|------|
| 张三 | 25 | 男 |
| 李四 | 22 | 女 |
\`\`\`
## 结束语
以上是Markdown的基本用法,通过这些简单的标记,您可以创建一篇包含标题、文本、图片和表格的文章。Markdown的语法简单易懂,适合快速排版和分享文档。希望这篇文章对您有所帮助!
`;
二、代码实现
实现打字机效果涉及三个部分:
- 核心逻辑
TypeWriterCore
- Hook封装
useTypeWriter
- React组件实现
TypeWriter Components
三个部分业务侧可按需取用,以下部分将详细介绍每一部分的实现逻辑及关键代码。
1. TypeWriterCore.ts
- 打字机核心逻辑
TypeWriterCore.ts
文件中定义了TypeWriterCore
类,这个类封装了打字机效果的核心逻辑。通过构造函数,我们可以传入不同的配置选项,如打字速度、暂停时间等,以适应不同的使用场景。
interface TypeWriterCoreOptions {
onConsume: (str: string) => void; // 定义一个回调函数,用于消费(处理)字符
maxStepSeconds?: number; // 可选属性,定义最大步进间隔(毫秒)
}
export default class TypeWriterCore {
onConsume: (str: string) => void; // 消费(处理)字符的回调函数
queueList: string[] = []; // 存储待消费字符的队列
maxStepSeconds: number = 50; // 默认最大步进间隔为50毫秒
maxQueueNum: number = 2000; // 队列中最大字符数
timer: number | undefined; // 用于控制下一次消费的定时器
constructor({
onConsume, maxStepSeconds}: TypeWriterCoreOptions) {
this.onConsume = onConsume; // 初始化消费字符的回调
if (maxStepSeconds !== undefined) {
this.maxStepSeconds = maxStepSeconds; // 如果提供了最大步进间隔,则使用提供的值
}
}
// 动态计算消费字符的速度
dynamicSpeed() {