当 canvas 的元素超过 100 个时滞后于 view.update

Lag on view.update when canvas has more than 100 elements

我目前正在使用 Paper.js 开发一个个人项目,我注意到添加超过 100 个元素会在每次尝试更新视图时产生巨大的滞后使用 project.view.update().

添加

我创建了一个简单的例子来证明这种行为。此示例自动创建 200 个元素(每 10 毫秒一个),每个元素有 5 个随机段。

你可以试试here.

看看控制台。一开始一切都很好,但在第 100 个元素(或多或少)时,事情开始变得迟钝。

对于这个问题,Paper.js 库有什么解决方案或改进吗?对于需要在用户绘制元素时不断更新的绘图应用程序来说,这是一个大问题。

提前致谢!

PS:我也将此报告为 an issue on Github,但没有人回答我。

PS:我创建了这个 fiddle 并将最大元素从 100 更改为 2000。如果您看到计数消息是如何显示的,您就会注意到这个问题在 200 或 350 个元素后更新

Paper.js(即使不是全部,也是大部分)Canvas 包装器库 当某些东西改变时重绘整个场景。换句话说,即使是最微小的变化也会触发全场景更新。

重绘周期是所有矢量图形库中固有的,即使 SVG 图形也会这样做,但浏览器会抽象出重绘周期(加上一些其他重绘优化)。

所以在每一帧上你基本上都在重新绘制整个场景。每次重绘都需要在 canvas 上 blit 100 个矢量项或更多。这是放缓的主要原因。

由于每个矢量项都由线段、填充等组成 - 速度会变慢。


1。暂时将项目显示为 Raster

您可以通过这样做来解决这个问题:

var tempRaster = myItem.rasterize();
myItem.visible = false; 
  • 我在这里所做的是暂时栅格化项目。
  • 除了位置之外不改变任何东西的项目可以是 栅格化。
  • 将它们栅格化有效地把它变成一个单一的图像 项,因此在每个渲染周期中渲染速度 更快。

我在这里使用 item.visible = false; 而不是 item.remove() 是为了在场景图中保留矢量项目,以防你想在某个时候将它带回来(改变它的属性或使用它作为矢量 - 无论如何你都不会丢失矢量项本身)。

上述技术类似于Bitmap Caching

如果您打算只使用线条(如上面的示例),这可能没有任何实际好处。当您有包含许多段的复杂矢量路径时,这通常是一个不错的解决方案。


2。使用 Symbols

如果您的项目除了位置不同外都一样,您可能还想看看 Using Symbols in Paper.js


3。使用 Plain HTML5 canvas 绘图命令并放弃 Canvas 包装库

如果您只是在 canvas 上绘制您不想在之后操作的形状,只需使用普通的 HTML 例如 ctx.lineTo(300,150);

'Regular' Canvas,没有 Vector 包装器库(如 Paper.js)更快,因为它是即发即弃。您只需在 canvas 上 blit 形状,仅此而已 - 形状在绘制后会被遗忘,不涉及重绘周期(除非您自己创建一个)所以一切都快得多。