Kros的博客 Kros的博客
首页
  • CSS
  • 工具
  • Vue
  • js
  • Vue3
  • 算法
  • 折腾笔记
一言
  • 分类
  • 标签
  • 归档
码云

Kros

凡心所向,素履以往,生如逆旅,一苇以航
首页
  • CSS
  • 工具
  • Vue
  • js
  • Vue3
  • 算法
  • 折腾笔记
一言
  • 分类
  • 标签
  • 归档
码云
  • CSS

  • JavaScript

    • 兼容ie7的水平无限滚动
    • 节流防抖
    • 数组乱序
    • 开启全屏
    • 数据类型
    • 变量提升
    • this调用指向
    • 原型及原型扩展
    • js获取元素属性精度问题
    • setTimeout和setInterval
    • 数组判断
    • dom节点添加或插入元素
    • var、let和const的区别
    • 判断ellipsis是否省略生效
    • 使用ResizeObserver监听元素size变化
    • js自定义事件
    • use strict详解
    • 私有属性
    • js实现类的方式
    • call和apply的理解和使用
    • js失焦和点击事件顺序冲突
    • js中不常见但非常实用的运算符
    • for of和for in的区别
    • defer和async的区别
    • promise值穿透
    • js为什么会出现数字精确度丢失
    • js禁用F12开发者模式
    • 使用scrollTop和scrollTo滚动到目标位置
    • js实现打字机效果
    • 多种方式实现数组去重
    • 替换使用setTimeout
    • encodeURI和encodeURIComponent的区别
    • canvas实现弹跳小球
    • js实现跨标签页通信
    • 事件循环与微任务、宏任务
    • 浏览器存储数据方式
    • 常见的meta元数据使用
    • 使用InterSectionObserver判断元素区域(chatGPT)
  • 工具

  • Vue

  • antdv踩坑记录

  • Vue3

  • 前端
  • JavaScript
kros
2025-08-01

js实现打字机效果

先看效果:

typewriter-all

思路:使用canvas.measureText计算单个字符宽度,使用定时器根据每个字符宽度动态设置元素宽度

实现代码如下:

<div>
  <h1 id="typewriter"></h1>
</div>

<script>
function getTextWidth(text, font = 'bold 36px Consolas, Monaco, monospace') {
  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d');
  context.font = font; // 设置字体样式
  return context.measureText(text).width;
}

function calcTextWidth(text) {
  const lenArr = []
  for(let i = 0; i < text.length; i++) {
    lenArr.push(getTextWidth(text[i]))
  }
  return lenArr
}
const textStr = 'this is a 中英文测试 paragraph'
const lenArr = calcTextWidth(textStr)
const lenNum = lenArr.reduce((r, v) => r += v, 0)

const typeWriter = document.getElementById('typewriter');
typeWriter.style.width = lenNum + 'px'
typeWriter.innerText = textStr

let idx = 1;
function stepWidth() {
  if (idx <= lenArr.length) {
    typeWriter.style.width = lenArr.slice(0, idx).reduce((r, v) => r += v, 0) + 'px'
    console.log(idx)
    setTimeout(() => {
      idx ++ 
      stepWidth()
    }, 100)
  }
}

stepWidth()

</script>

<style>
h1 {
	font: bold 36px Consolas, Monaco, monospace;
	border-right: 0.1em solid;
	margin: 2em 1em;
	white-space: nowrap;
	overflow: hidden;
	animation: cursor-blink 0.3s step-end infinite alternate;
}

@keyframes typing {
	from {
		width: 0;
	}
}

@keyframes cursor-blink {
	50% {
		border-color: transparent;
	}
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
上次更新: 2025/09/05, 8:09:00
使用scrollTop和scrollTo滚动到目标位置
多种方式实现数组去重

← 使用scrollTop和scrollTo滚动到目标位置 多种方式实现数组去重→

最近更新
01
Find the next perfect square
09-05
02
Regex validate PIN code
09-05
03
Find the odd int
09-05
更多文章>
Theme by Vdoing | Copyright © 2020-2025 kros king
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
icon-heart-o icon-heart icon-infinity icon-pause icon-play link next prev