Javascript HTML5画布重画周期性能优化
我们正在构建一个在浏览器中运行的CAD应用程序Javascript HTML5画布重画周期性能优化,javascript,optimization,paperjs,Javascript,Optimization,Paperjs,我们正在构建一个在浏览器中运行的CAD应用程序 C.A.D代表 Illustrator、CorelDraw、AutoCAD等都是CAD应用程序的一些示例 它基于一个非常整洁的画布库,允许您以编程方式操作向量 问题 目前我面临的主要问题是重新绘制循环性能 重画算法是“愚蠢的”(就提高性能的巧妙技巧而言),因此效率低下且渲染速度慢-场景图项目取决于逐渐较慢的重画周期 随着绘制点的累积,每个重绘周期都会变得越来越慢 重画方案非常简单: 清理整个区域 从场景图中获取所有项目 重新绘制所有项目
- C.A.D代表
- Illustrator、CorelDraw、AutoCAD等都是CAD应用程序的一些示例
问题 目前我面临的主要问题是重新绘制循环性能 重画算法是“愚蠢的”(就提高性能的巧妙技巧而言),因此效率低下且渲染速度慢-场景图项目取决于逐渐较慢的重画周期 随着绘制点的累积,每个重绘周期都会变得越来越慢 重画方案非常简单:
- 清理整个区域
- 从场景图中获取所有项目
- 重新绘制所有项目
paper.view.persistence=1;
)
通过这种方式,您可以更好地控制要清除的内容和应该重新绘制的内容:例如,当您移动形状时,可以清除它所在的区域(例如,使用本机canvas drawRect),
并在移动后进行更新(使用path.needsUpdate();
)
缺点
当形状相交时,问题就出现了。如果要修改与另一个形状相交的形状,则必须同时更新这两个形状。如果第二个形状与第三个形状相交,则情况相同,依此类推
因此,您需要一个递归函数,不难编码,但如果有许多复杂形状相交,那么它的成本可能会很高,因此在这种情况下,您可能无法获得性能
(更新)位图缓存
正如中所建议的,位图缓存是一个非常好的解决方案
每个形状一块帆布
另一种方法是在单独的画布上绘制每个形状(作为层)。通过这种方式,您可以独立地自由清除和重新绘制每个形状。可以分离未更改视图的onFrame事件(除用户正在工作的画布外的所有画布)。这应该更容易,但它会导致其他小问题,例如共享相同的项目视图参数(在缩放的情况下),并且对于许多形状(这意味着许多画布)来说可能代价高昂
静态和动态画布
一个(可能)更好的方法是只有两个画布,一个用于静态形状,一个用于活动形状。静态形状画布将包含所有形状(正在编辑的形状除外),并将在用户开始和停止编辑活动形状时重新绘制。当用户开始编辑一个形状时,它将从静态画布转移到动态画布,当用户停止编辑时,它将从静态画布转移到动态画布。这可以通过类似于的过程/技术中的光栅化来完成 高节点数场景图的问题是渲染它们会导致渲染引擎发出呻吟声。浏览器必须遍历它们的节点并在画布上渲染它们的像素 因此,这里有一个很好的解决方案:
1.渲染位图,但保持下面的原始形状处于隐藏状态 解决方案是用图像替换矢量,将其光栅化- 仅在渲染时,但仍将原始形状保持在其下方 图像复制,仅当处于非活动状态(当前未处于活动状态)时处于隐藏状态 操纵的) 单击图像-我们将其删除并切换原始形状的可见性。通过这种方式,非活动形状被渲染为图像,活动形状从位图表示中释放,并作为向量,可以自由地进行操作。当它们不处于活动状态时,它们只是坐在那里,上面放着光栅副本,不受攻击 这允许引擎保留形状的矢量表示,但避免将其渲染为矢量-相反,看起来与形状相似的图像将分层在形状之上 1000个路径命令基本上由单个图像替换(但仅在渲染时),原始路径实际上作为对象存在于场景图中,或者使用任何类型的DOM 2.成组光栅化 诀窍是成组执行光栅化-将10-15个形状组合在一起,并将它们作为单个图像进行光栅化。这将使光栅计数保持较低。点击一个图片-我们可以释放整个组或者仅仅是点击的项目 3.在组上附加单击处理程序,以在重新激活时恢复向量副本
当光栅化一个组时,我们只需在其上附加一个
click
处理程序,所以当单击时,我们可以使用向量切换位图。命中测试时,图像的行为与向量不同-图像本质上是正方形
,无法进行非对称命中测试。当一个向量认为它的边在它的路径边界上时,一个图像认为它的边界就是它的整个边界框。解决方案是单击图像以实际点击图像下方的向量路径测试点击点-如果返回true,则执行发布。为什么您认为paper.js是高度优化的,甚至是优化的?绝大多数库的运行时性能都非常差:好的性能需要大量的代码,这与尽可能小的大小相冲突。我只是相信创作者说的。再加上它是面向动画的,我得出结论,他们说的是真的。即使不是,在我的应用程序所需的功能方面,也没有一个库可以与我竞争。这是API让我至少涵盖了80%的内容