使用requestAnimationFrame的Canvas大炮移动动画无显示问题求助
解决Canvas大炮不显示的问题
我帮你排查出了代码里的几个关键问题,正是它们导致画布上看不到大炮:
问题1:绘制与清画布的顺序搞反了
你在draw函数里先调用drawCanon画大炮,紧接着就用clearRect清空了整个画布——这就相当于刚画好的内容立刻被擦掉了,自然啥也看不到。正确的顺序应该是先清空画布,再绘制内容。
问题2:requestAnimationFrame调用与变量作用域错误
- 首先,
requestAnimationFrame不需要第二个参数(你写的30是多余的,浏览器会自动按照屏幕刷新率调度帧); - 其次,你的
draw函数把x作为参数传入,导致函数内部的x++修改的是局部参数,而不是外部的全局x变量。这样每次递归调用时,x的值一直停留在初始的185+1=186,大炮根本不会移动,再加上之前的清画布顺序错误,就彻底看不到内容了。
问题3:路径绘制的小疏漏
在drawCanon里,你先调用了moveTo再启动新路径beginPath,这可能导致路径和之前的绘制残留混淆,正确的流程应该是先启动新路径,再设置起点。
修正后的完整代码
window.addEventListener('load', function(){ var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); // 把x作为全局状态变量,不在draw函数里重复传参 var x = 185; var y = 320; var W = 30; function drawCanon(x, y, W){ //CANON ctx.fillStyle = "rgb(0, 0, 0)"; ctx.beginPath(); // 先启动新路径,再设置起点 ctx.moveTo(x, y); ctx.lineTo(x + W/5 * 3, y); ctx.lineTo(x + W/5 * 4, y + W * 2); ctx.lineTo(x - W/5, y + W * 2); ctx.lineTo(x, y); ctx.closePath(); ctx.fill(); ctx.arc(x + W/10 * 3, y + 2 * W, W/2, 0, Math.PI); ctx.fill(); //ROUES ctx.fillStyle = "rgb(156, 92, 23)"; ctx.beginPath(); ctx.arc(x - W/50 * 12, y + W/50 * 102, W/5 * 2, 0, Math.PI * 2); ctx.closePath(); ctx.fill(); ctx.beginPath(); ctx.arc(x + W/50 * 42, y + W/50 * 102, W/5 * 2, 0, Math.PI * 2); ctx.closePath(); ctx.fill(); } function draw(){ // 先清空画布 ctx.clearRect(0, 0, 400, 400); // 再绘制大炮,使用全局的x变量 drawCanon(x, y, W); // 修改全局x变量,实现持续右移 x++; // 递归调用requestAnimationFrame,无需额外参数 window.requestAnimationFrame(draw); } draw(); });
修改后,你就能看到大炮从初始位置开始持续向右移动了!
内容的提问来源于stack exchange,提问作者Andréa
相关产品推荐
相关产品推荐

