Canvas卡拉OK文字渲染效果调用后延迟3-4秒,如何实现即时运行?
解决Canvas卡拉OK文字动画延迟启动问题
你的动画延迟3-4秒才生效,核心原因是裁剪区域的起始位置和文字实际位置不匹配:代码里文字是居中绘制的(x = canvas.width/2),但裁剪区域的起始X坐标clearX固定为8,导致w需要增长到280左右(画布中心到8的距离),裁剪区域才会覆盖到文字,这段时间里动画看不到任何变化,看起来就像延迟启动。
修改后的代码
const canvas = document.querySelector("#draw-pad"); const ctx = canvas.getContext("2d"); // 保存动画ID,防止重复调用时多个动画冲突 let animationId = null; function runTextAnimation(text) { // 先取消之前的动画 if (animationId) { cancelAnimationFrame(animationId); } const txt = text; // 先设置字体,才能计算文字实际宽度 ctx.font = 'bold 17px Arial'; const textWidth = ctx.measureText(txt).width; // 文字居中参数 const x = canvas.width / 2; const y = canvas.height / 2; // 裁剪区域从文字左侧开始,而非固定的8 const clearX = x - textWidth / 2; const clearY = 5; const clearH = 40; let w = 0; ctx.lineWidth = 2; ctx.strokeStyle = 'black'; function runText() { // 清空整个画布,避免残留绘制内容 ctx.clearRect(0, 0, canvas.width, canvas.height); // 绘制底层浅蓝色文字 ctx.fillStyle = 'lightblue'; ctx.strokeText(txt, x, y); ctx.fillText(txt, x, y); // 裁剪区域内绘制红色覆盖层 ctx.save(); ctx.beginPath(); ctx.rect(clearX, clearY, w, clearH); ctx.clip(); ctx.fillStyle = 'red'; ctx.strokeStyle = 'white'; ctx.strokeText(txt, x, y); ctx.fillText(txt, x, y); ctx.restore(); // 动画进度控制:覆盖完整个文字后重置 if (w >= textWidth) { w = 0; } else { w += 1.92; } animationId = requestAnimationFrame(runText); } // 立即执行第一帧动画 runText(); } runTextAnimation("chắc không phải một người như anh");
关键修改点
- 匹配裁剪区域与文字位置:通过
measureText计算文字实际宽度,让裁剪区域从文字左侧开始,动画启动后立即能看到红色覆盖效果。 - 管理动画生命周期:新增
animationId,重复调用函数时会先取消之前的动画,避免多个动画叠加导致的混乱。 - 简化绘制逻辑:每次帧绘制前清空整个画布,移除原代码中冗余的
clearRect调用,让动画逻辑更清晰。
内容的提问来源于stack exchange,提问作者Hieu_Tran
相关产品推荐
相关产品推荐

