如何在HTML5 Canvas中实现图像的平滑移动动画?
实现Canvas图像平滑移动的解决方案
这个问题很常见——你当前的实现是点击后直接一次性修改位置并触发单次重绘,所以图像看起来是跳跃式移动的。要实现平滑的动画效果,我们需要利用浏览器原生的 requestAnimationFrame API 创建持续的帧更新循环,让图像在每一帧中移动一小段距离,逐步接近目标位置。
具体修改步骤:
重构状态变量
我们需要区分「当前位置」和「目标位置」,同时定义移动速度(控制平滑度):// 初始位置(和你原来的默认值一致) let currentLeft = 100; // 目标位置,初始和当前位置相同 let targetLeft = currentLeft; // 每帧移动的像素数,值越小越平滑,越大移动越快 const moveSpeed = 2;修改点击事件逻辑
点击时不再直接修改位置,而是更新目标位置:$("#left").on("click", function(){ // 每次点击,目标位置向右移动10像素(如果要左移就改成 -=10) targetLeft += 10; });创建动画循环
用requestAnimationFrame实现持续的帧更新,在每一帧中逐步调整当前位置并重新绘制图像:function animate() { // 先清除画布,避免图像留下轨迹 ctx.clearRect(0, 0, canvas.width, canvas.height); // 逐步接近目标位置 if (currentLeft < targetLeft) { currentLeft += moveSpeed; // 防止超过目标位置 if (currentLeft > targetLeft) currentLeft = targetLeft; } else if (currentLeft > targetLeft) { currentLeft -= moveSpeed; if (currentLeft < targetLeft) currentLeft = targetLeft; } // 绘制图像(用currentLeft作为当前位置) ctx.drawImage(img, 0, 0, imgW, imgH, currentLeft, 0, imgW, imgH); // 循环调用,保持动画持续运行 requestAnimationFrame(animate); } // 启动动画循环 animate();
为什么这样能实现平滑效果?
requestAnimationFrame 会按照浏览器的刷新频率(通常60帧/秒)调用动画函数,每帧只移动几个像素,视觉上就会呈现出连续平滑的移动效果,而不是一次性跳跃10像素。
关于你提到的GlassesUp逻辑
你提到的眼镜移动(GlassesUp)也可以用完全相同的思路:定义currentUp、targetUp和移动速度,点击时更新targetUp,然后在同一个animate函数中处理垂直方向的位置更新即可。
内容的提问来源于stack exchange,提问作者joe
相关产品推荐
相关产品推荐

