如何实现Canvas中心逐字符生成对称文本(仿ULTRAKILL效果)
解决方案:Canvas逐字符居中绘制文本
核心思路是每次添加字符后,重新计算当前文本的总宽度,让文本块的中心与画布中心对齐,而非单一方向偏移。以下是修改后的完整代码:
const font = new FontFace('ULTRAKILL', 'url(VCR_OSD.ttf)'); // 存储定时器ID,用于清理重复触发 let textTimer = null; font.load().then((font) => { document.fonts.add(font); console.log('字体加载完成,可生成文本'); }); function genText(interval, startAt) { // 先清除之前的定时器,避免多个定时器同时运行 if (textTimer) { clearInterval(textTimer); textTimer = null; } const ctx = document.getElementById("canvas").getContext("2d"); const canvas = document.getElementById("canvas"); const fullText = document.getElementById('input').value; // 累积当前已显示的文本 let currentText = ''; let charIndex = 0; // 初始化清空画布 ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.font = '30px ULTRAKILL'; ctx.textBaseline = 'middle'; // 让文本垂直居中于y坐标 setTimeout(() => { textTimer = setInterval(() => { if (charIndex < fullText.length) { // 添加下一个字符到当前文本 currentText += fullText[charIndex]; charIndex++; // 清空画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 计算当前文本的总宽度 const textWidth = ctx.measureText(currentText).width; // 计算文本起始x坐标:画布中心 - 文本宽度的一半 const startX = canvas.width / 2 - textWidth / 2; // y坐标保持画布中心,配合textBaseline实现垂直居中 const startY = canvas.height / 2; // 绘制完整的当前文本 ctx.fillText(currentText, startX, startY); } else { // 所有字符绘制完成后清除定时器 clearInterval(textTimer); textTimer = null; } }, interval); }, startAt); }
关键改动说明:
- 累积文本重绘:用
currentText存储已显示的所有字符,每次添加新字符后重绘全部内容,确保位置统一调整。 - 精准宽度计算:使用
ctx.measureText()获取实际文本宽度,替代原代码硬编码的偏移量,避免因字体字符宽度不一致导致的错位。 - 垂直居中优化:设置
ctx.textBaseline = 'middle',让文本垂直中心对齐画布中心,实现真正的上下居中。 - 定时器管理:添加
textTimer变量存储定时器ID,每次调用genText时清除旧定时器,防止多次触发导致的文本重复绘制。 - 字体加载保障:等待字体加载完成后再进行绘制,避免因字体未加载导致的宽度计算错误和显示异常。
内容的提问来源于stack exchange,提问作者user23770759
相关产品推荐
相关产品推荐

