我使用带有chrome的canvas clip()会出现严重的性能问题。
I have made a test case to illustrate。
即使在这样的简单情况下,红色矩形也会闪烁,好像需要花费太多时间来重绘,并且CPU分析显示clip()方法占用了大约10%的CPU。
在我的真实程序中,它达到16%并继续增加每一帧,直到画布几乎冻结浏览器..
我使用剪辑有什么问题吗?
感谢您提出任何建议,
问候。
答案 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}}等)将为 执行此操作(规范正在解决浏览器实施者):
计算剪裁区域时必须隐式关闭打开的子路径