npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mingto/type-writer

v1.0.6

Published

流式打字机效果组件,提供逐字符显示文本的打字机效果

Readme

@mingto/type-writer

TypeScript 打字机效果工具库,支持逐字输出文本,模拟打字机般的视觉效果。轻量级、高性能、零依赖。

特性

  • ⌨️ 打字机效果:逐字输出文本,模拟真实打字机体验
  • 自定义速度:灵活配置打字速度,毫秒级精确控制
  • 🎯 事件驱动:支持 changecomplete 两种事件回调
  • 📦 TypeScript 支持:完整的类型定义和类型推导,IDE 智能提示
  • 🔄 队列机制:支持连续发送文本,自动排队处理,无需手动管理
  • 🚫 状态管理:完整的生命周期管理(PENDING/EXECUTING/COMPLETED)
  • 💎 链式调用:流畅的 API 链式调用设计,代码更优雅
  • 🚀 零依赖:无任何外部依赖,体积小巧,易于集成
  • 🎨 框架无关:不绑定任何框架,支持 Vue、React、Angular 等所有主流框架

安装

# npm
npm install @mingto/type-writer

# yarn
yarn add @mingto/type-writer

# pnpm (推荐)
pnpm add @mingto/type-writer

快速开始

三行代码实现打字机效果:

import { createTypeWriter } from '@mingto/type-writer'

// 1. 创建打字机实例
const typeWriter = createTypeWriter({ speed: 100 })

// 2. 监听事件
typeWriter.on('change', (text) => {
  document.getElementById('typing-text').innerText = text
})

// 3. 发送文本开始打字
typeWriter.send('Hello, World! 你好,世界!')

API 文档

创建实例

createTypeWriter(options)

创建打字机实例。

import { createTypeWriter } from '@mingto/type-writer'

const typeWriter = createTypeWriter({
  speed: 100,  // 每字间隔 100ms
})

配置参数 options:

| 参数 | 类型 | 必填 | 默认值 | 说明 | |------|------|------|--------|------| | speed | number | ❌ | 100 | 打字速度,单位为毫秒/每字 |

实例方法

typeWriter.send(text)

发送文本进行打字机输出,支持链式调用。

typeWriter.send('这是第一段文本。')

// 可连续调用,文本会排队处理
typeWriter.send('这是第二段文本。')

| 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | text | string | ✅ | 要输出的文本 |

typeWriter.end()

手动结束打字机,完成剩余字符输出。

typeWriter.end()

typeWriter.finish()

销毁打字机实例,清除定时器和队列,释放资源。

typeWriter.finish()

typeWriter.getText()

获取当前已输出的完整文本。

const currentText = typeWriter.getText()
console.log(currentText)

typeWriter.on(eventName, callback)

监听事件,支持链式调用。

typeWriter
  .on('change', (text) => {
    console.log('输出变更:', text)
  })
  .on('complete', () => {
    console.log('全部完成')
  })

事件说明

| 事件名 | 触发时机 | 回调参数 | 说明 | |--------|----------|----------|------| | change | 每次有新字符输出时 | string | 返回当前已输出的完整文本 | | complete | 所有字符输出完成时 | - | 标志打字过程结束 |

使用示例

基础用法

import { createTypeWriter } from '@mingto/type-writer'

const tw = createTypeWriter({ speed: 150 })

tw
  .on('change', (text) => {
    document.getElementById('output').textContent = text
  })
  .on('complete', () => {
    console.log('打字完成!')
  })

tw.send('欢迎使用 type-writer 打字机效果库!')

快速打字效果

import { createTypeWriter } from '@mingto/type-writer'

const fastTw = createTypeWriter({ speed: 50 })

fastTw
  .on('change', (text) => {
    console.log(text)
  })
  .on('complete', () => {
    console.log('快速打字完成')
  })

fastTw.send('这是快速打字效果的演示文本。')

慢速打字效果

import { createTypeWriter } from '@mingto/type-writer'

const slowTw = createTypeWriter({ speed: 300 })

slowTw
  .on('change', (text) => {
    console.log(text)
  })

slowTw.send('这是慢速打字效果,每个字间隔 300ms,适合营造悬念氛围。')

在 React 中使用

import { useState, useEffect, useRef } from 'react'
import { createTypeWriter } from '@mingto/type-writer'

const TypeWriterComponent = () => {
  const [text, setText] = useState('')
  const [isComplete, setIsComplete] = useState(false)
  const typeWriterRef = useRef(null)

  useEffect(() => {
    typeWriterRef.current = createTypeWriter({
      speed: 100,
    })

    typeWriterRef.current
      .on('change', (currentText) => {
        setText(currentText)
      })
      .on('complete', () => {
        setIsComplete(true)
      })
      .send('欢迎来到我们的网站!这是一段打字机效果演示文本。')

    return () => {
      typeWriterRef.current?.finish()
    }
  }, [])

  return (
    <div>
      <span>{text}</span>
      {!isComplete && <span className="cursor">|</span>}
    </div>
  )
}

export default TypeWriterComponent

在 Vue 3 中使用

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { createTypeWriter } from '@mingto/type-writer'

const displayText = ref('')
const isComplete = ref(false)
let typeWriter = null

onMounted(() => {
  typeWriter = createTypeWriter({ speed: 80 })

  typeWriter
    .on('change', (text) => {
      displayText.value = text
    })
    .on('complete', () => {
      isComplete.value = true
    })
    .send('Vue 3 打字机效果演示。优雅的逐字输出体验。')
})

onUnmounted(() => {
  typeWriter?.finish()
})
</script>

<template>
  <div class="type-writer">
    <span>{{ displayText }}</span>
    <span v-if="!isComplete" class="cursor">_</span>
  </div>
</template>

连续发送多段文本

import { createTypeWriter } from '@mingto/type-writer'

const tw = createTypeWriter({ speed: 100 })

tw
  .on('change', (text) => {
    process.stdout.write(`\r${text}`)
  })
  .on('complete', () => {
    console.log('\n全部完成!')
  })

// 第一段
tw.send('第一段文本。')

// 1 秒后发送第二段
setTimeout(() => {
  tw.send('第二段文本,排队输出。')
}, 1000)

// 2 秒后发送第三段
setTimeout(() => {
  tw.send('第三段文本,继续输出。')
}, 2000)

结合语音识别显示实时结果

import { createTypeWriter } from '@mingto/type-writer'
import huoshanLAT from '@mingto/huoshan-lat'

// 创建打字机实例
const tw = createTypeWriter({ speed: 30 })

tw.on('change', (text) => {
  document.getElementById('asr-result').innerText = text
})

// 配置语音识别
huoshanLAT.config()

const lat = huoshanLAT.create({}, {
  autoControl: true,
  initialDelay: 3500,
  subsequentDelay: 3000,
})

lat.on('appResultText', (text) => {
  // 用打字机效果显示语音识别结果
  tw.send(text + ' ')
})

lat.watch()

最佳实践

1. 速度配置建议

| 使用场景 | 推荐速度 | 说明 | |----------|----------|------| | 标题展示 | 80-150ms | 吸引用户注意力 | | 正文内容 | 50-100ms | 平衡阅读体验和效率 | | 强调文本 | 150-300ms | 突出重点,营造悬念 | | 快速提示 | 20-50ms | 追求效率,不影响阅读 |

2. 文本分段建议

  • 长文本:建议按句子或段落分段发送,每段 50-100 字
  • 对话内容:按角色发言分段,增强对话感
  • 列表内容:按条目逐个发送,增强层次感
// ❌ 不推荐:一次性发送超长文本
tw.send('非常长的一段文本,可能导致用户阅读压力...')

// ✅ 推荐:分段发送
tw.send('第一段内容。')
setTimeout(() => tw.send('第二段内容。'), 3000)

3. 性能优化

// ✅ 推荐:在组件卸载时清理资源
useEffect(() => {
  const tw = createTypeWriter({ speed: 100 })
  return () => tw.finish()
}, [])

// ❌ 避免:创建多个实例而不清理
const tw1 = createTypeWriter({ speed: 100 })
const tw2 = createTypeWriter({ speed: 100 }) // 不必要

状态说明

| 状态 | 值 | 说明 | |------|----|------| | PENDING | 'pending' | 待执行状态,等待输入文本 | | EXECUTING | 'executing' | 执行中状态,正在进行打字输出 | | COMPLETED | 'completed' | 已完成状态,所有文本输出完毕 |

状态流转:

PENDING → EXECUTING → COMPLETED

内部工作流程

  1. 初始化阶段:创建实例,设置默认参数
  2. 接收文本:调用 send() 方法,将文本加入队列
  3. 逐字输出:按设定速度逐字输出文本,触发 change 事件
  4. 完成回调:所有字符输出完成后,触发 complete 事件
  5. 资源释放:调用 finish() 清除定时器和队列

注意事项

  1. ⚠️ 组件卸载清理:在页面卸载或组件销毁时,务必调用 finish() 方法释放资源,避免内存泄漏
  2. ⚠️ 速度设置:建议速度值在 30-300ms 之间,太快可能看不清,太慢影响体验
  3. ⚠️ 文本长度:过长文本建议分段发送,可获得更好的用户体验
  4. ⚠️ 事件回调change 事件会频繁触发,避免在回调中执行耗时操作
  5. ⚠️ 链式调用onsend 方法支持链式调用,让代码更简洁优雅
  6. ⚠️ 手动结束:调用 end() 会立即完成所有剩余字符的输出

常见问题

Q: 如何实现光标闪烁效果? A: 可以使用 CSS 动画实现:

.cursor {
  animation: blink 1s infinite;
}

@keyframes blink {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}

Q: 如何实现打字暂停和恢复? A: 可以通过自定义逻辑实现:

let paused = false
const originalText = '要输出的文本'
let currentIndex = 0

const tw = createTypeWriter({ speed: 100 })

function pause() {
  paused = true
  // 保存当前状态
}

function resume() {
  paused = false
  // 继续输出剩余文本
  tw.send(originalText.slice(currentIndex))
}

Q: 打字速度可以动态调整吗? A: 目前不支持动态调整,需要重新创建实例。建议根据场景预设不同的速度配置。

Q: 支持输出 HTML 内容吗? A: 目前只支持纯文本输出。如果需要 HTML,可以在回调中手动处理富文本渲染。

浏览器兼容性

| Chrome | Firefox | Safari | Edge | IE | |--------|---------|--------|------|----| | 60+ | 55+ | 12+ | 79+ | ❌ 不支持 |

需要支持 requestAnimationFramesetTimeout API

性能指标

| 指标 | 数值 | 说明 | |------|------|------| | 打包后大小 | ~2KB | gzip 压缩后 | | 内存占用 | <1MB | 正常使用场景 | | CPU 使用率 | <1% | 打字过程中 | | 初始化耗时 | <1ms | 几乎瞬时 |

相关链接

许可证

MIT