如何强制在画布中更新显示

19
如果我在画布上快速连续地绘制很多东西,比如在一个循环中使用context.fillRect,浏览器似乎会等到循环完成后才显示任何绘制内容(可能是通过双缓冲实现的)。
有没有办法在每次绘制操作之后明确或隐式地强制浏览器更新显示?
2个回答

19
不是因为双缓冲,而是因为Web浏览器中的JavaScript是单线程的,所以你看不到结果。如果你在JavaScript中创建一个类似于myDiv.style.top = parseInt(myDiv.style.top) + 1 +"px";的单一循环,即使经过多秒钟,直到JavaScript执行完毕,浏览器上也不会有任何可见变化。
要在屏幕上绘制更改并查看结果,需要使用setIntervalsetTimeout将控制权交还给浏览器,但要求在将来某个时间运行代码。
例如,要在画布上每秒15次绘制新的随机颜色矩形:
var canvas = document.getElementsByTagName('canvas')[0];
var ctx = canvas.getContext('2d');
setInterval(function(){
  ctx.clearRect(0,0,canvas.width,canvas.height);
  var r=Math.random()*255, g=Math.random()*255, b=Math.random()*255;
  ctx.fillStyle = 'rgb('+r+','+g+','+b+')';
  var w=Math.random()*canvas.width,     h=Math.random()*canvas.height;
  var x=Math.random()*(canvas.width-w), y=Math.random()*(canvas.height-h);
  ctx.fillRect(x,y,w,h);
},1000/15);

0

为了获得更好的浏览器行为,最好使用{{link1:window.requestAnimationFrame()}}。


2
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community
嗨@jjff55,你的回答很好,但请注意这个问题是10年前提出的,当时requestAnimationFrame几乎不存在。你的回答有点过时了,可以这么说。 - DDomen
1
回答旧问题是可以的,甚至是鼓励的。我来到这里是因为虽然已经过去了十年,但我仍然遇到了同样的问题,而这是最受欢迎的结果之一。拥有所有新旧解决方案都很有用! - Martin Tournoij
@MartinTournoij 谢谢你的建议,它让我再次仔细检查了SO政策。尽管答案并没有回答问题,只是一个小部分,但扩展它可能会更好(也许用户无法评论旧答案,因此扩展这个答案是有意义的)。 - DDomen
哦,是的,这个回答太短/模糊了,无法成为一个好的答案@DDomen; 我实际上无法从MDN页面中找出如何使其工作,所以只好使用setTimeout()方法。 - Martin Tournoij

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接