使用JavaScript和HTML5 canvas时动画无法正确循环且闪烁怎么办
Canvas加载条动画填满后闪烁无法重置循环的排查与修复
问题表现
实现加载条动画时,矩形从0宽度开始逐步扩展,预期填满整个300px宽画布后自动重置宽度为0、循环播放动画;实际运行时矩形填满画布后持续闪烁,无法正常进入下一轮扩展动画。
原始实现代码:
window.onload = function() { var wipeWidth = 0 var canvas = document.getElementById('canvas'); var context = canvas.getContext("2d"); console.log(context); function drawRect() { context.clearRect(0,0,300,150) context.fillStyle = "#305ef2"; context.rect(0, 0, wipeWidth, 150); context.fill() wipeWidth += 10 if(wipeWidth > 300) { wipeWidth = 0; } } setInterval(drawRect,50) }
排查方向
- 核对Canvas 2D上下文的绘制API差异:区分路径类绘制方法、直接绘制方法的行为区别,检查是否存在绘制状态残留
- 单步调试重置触发时的上下文状态:在
wipeWidth被赋值为0的逻辑处打断点,确认当前帧执行填充操作后的画布像素结果是否符合预期 - 验证清屏操作的生效范围:确认
clearRect仅清空画布像素,不会重置上下文的路径、样式等状态
问题根因
代码中使用的context.rect()是路径添加方法,每次调用都会将新的矩形路径追加到上下文的当前路径列表中,不会自动清除上一帧生成的路径。
当wipeWidth增长到超过300被重置为0时,之前逐帧累计的从0到300宽度的所有矩形路径仍然存在,执行context.fill()时会把路径列表中所有矩形统一填充,导致画布始终被蓝色填满;叠加wipeWidth在0、10两个值间快速跳变,就会出现持续闪烁的现象。
修复方案
二选一即可:
- 每次绘制矩形前调用
context.beginPath()清空上一帧残留的路径,保证每次填充仅针对当前帧定义的矩形 - 直接使用
context.fillRect()方法绘制填充矩形,该方法是直接绘制API,不会向路径列表追加内容,不存在路径残留问题
修复后的完整代码:
window.onload = function() { var wipeWidth = 0 var canvas = document.getElementById('canvas'); var context = canvas.getContext("2d"); function drawRect() { context.clearRect(0,0,300,150) context.fillStyle = "#305ef2"; // 修复:每次绘制前重置路径 context.beginPath(); context.rect(0, 0, wipeWidth, 150); context.fill() // 也可以替换为下面这行直接绘制,不需要beginPath和单独fill // context.fillRect(0, 0, wipeWidth, 150); wipeWidth += 10 if(wipeWidth > 300) { wipeWidth = 0; } } setInterval(drawRect,50) }
内容的提问来源于stack exchange,提问作者Bob Gabbitas
相关产品推荐
相关产品推荐

