HTML 5画布剪辑非常昂贵

时间:2014-01-16 11:25:49

标签: javascript html5 performance canvas clip

我使用带有chrome的canvas clip()会出现严重的性能问题。

I have made a test case to illustrate

即使在这样的简单情况下,红色矩形也会闪烁,好像需要花费太多时间来重绘,并且CPU分析显示clip()方法占用了大约10%的CPU。

在我的真实程序中,它达到16%并继续增加每一帧,直到画布几乎冻结浏览器..

我使用剪辑有什么问题吗?

感谢您提出任何建议,

问候。

1 个答案:

答案 0 :(得分:12)

原因

beginPath()添加rect()作为fillRect()添加到与strokeRect() / setInterval不同的路径。这里发生的是矩形正在累积,最终会减慢削减速度。

这与使用无法与监视器/屏幕刷新同步的setInterval()相结合,会使问题恶化。

详细说明后者:

使用setTimeout() / setInterval会导致撕裂,当绘图处于其操作的“中间”未完全完成且屏幕刷新时,会发生撕裂。

setInterval只能取整数值,你需要16.67 ms来逐帧同步(@ 60Hz)。即使requestAnimationFrame 可以采用浮动,它也不会将时间与监视器时序同步,因为计时器机制根本不受监视。

要解决此问题,请始终使用function draw() { context.fillStyle = '#000'; context.fillRect(0, 0, width, height); context.save(); context.beginPath(); /// add a beginPath here context.rect(0, 0, 100, 100); context.clip(); context.fillStyle = '#ff0000'; context.fillRect(0, 0, 200, 200); context.restore(); requestAnimationFrame(draw); /// use rAF here } canvas.width = width; canvas.height = height; canvas.style.width = width+'px'; canvas.style.height = height+'px'; requestAnimationFrame(draw); /// start loop 将图纸与屏幕更新同步。这与监视器刷新直接相关,并且是一个比另一个更低级别和更高效的实现,并且是为此目的而制作的,因此得名。

解决方案嵌入

上方的两个修复程序

请参阅 modified bin here

未来访客的代码:

if (isPlaying) requestAnimationFrame(draw);

PS:如果你需要停止循环注入条件以在循环内运行rAF,即:

closePath()

BTW不需要clip(),因为这将由the specs为您隐式完成。如果需要,您可以添加它,但是调用fill()(或{{1}}等)将为 执行此操作(规范正在解决浏览器实施者):

  

计算剪裁区域时必须隐式关闭打开的子路径