首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >HTML5画布重绘周期性能优化

HTML5画布重绘周期性能优化
EN

Stack Overflow用户
提问于 2014-05-27 16:03:55
回答 2查看 8.8K关注 0票数 16

我们正在构建一个在浏览器中运行的CAD应用程序。

  • C.A.D代表.
  • Illustrator、CorelDraw、AutoCAD等都是一些应用程序的例子。

它基于Paper.js,这是一个非常简洁的画布库,允许您以编程方式操作向量。

问题所在

我目前遇到的主要问题是重绘周期性能。

重绘算法是“哑巴”(就提高性能的巧妙技巧而言),因此效率低下且渲染缓慢的场景图项目依赖于逐渐变慢的重绘周期。

随着绘制点数的累积,每个重绘周期都会变得越来越慢。

重绘方案非常简单:

  • clear the take
  • take all Items from the Scene Graph
  • redraw Items。

问题是

在这种情况下,有没有任何渲染优化的课堂例子-假设我想停止实现脏矩形算法(只绘制发生变化的区域)

编辑:我已经尝试了手动现场光栅化,效果很好,我已经在下面发布了一个答案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-29 18:18:10

这可以通过类似于Bitmap Caching的过程/技术中的光栅化来完成。

高节点数场景图的问题是渲染它们会导致渲染引擎发出叹息。浏览器必须遍历它们的节点并在画布上渲染它们的像素。

所以这里有一个很好的解决方案:

1.渲染位图,但隐藏下面的原始形状

解决方案是将矢量替换为图像,将其栅格化-仅在渲染时,但仍将原始形状保留在其图像副本之下,只有在不活动时(当前未被操纵)才处于隐藏状态。

在单击图像时-我们删除它们并切换原始形状的可见性。通过这种方式,不活动的形状被渲染为图像,活动的形状从它们的位图表示中释放出来,并充当矢量,可以自由地进行操作。当不活动时,他们只是坐在那里,他们的光栅副本在他们的顶部。

这允许引擎保留形状的矢量表示,但避免将它们渲染为矢量-相反,看起来与它们相似的图像会层叠在它们上面。

数以千计的路径命令本质上是由单个图像替换的-但只有在渲染时-原始路径实际上作为对象存在于场景图中,或者您正在使用的任何类型的DOM

2.分组栅格化

诀窍是在组中执行光栅化-将10-15个形状组合在一起,并将它们光栅化为单个图像。这将使栅格计数保持较低。在点击图像时-我们可以释放整个组,或者只释放被点击的项目。

3.在组上附加单击处理程序,以便在重新激活时恢复矢量副本

当光栅化一个组时,我们可以简单地在它上面附加一个click处理程序,所以当单击它时,我们可以用矢量切换位图。在命中测试时,图像的行为与向量不同-图像本质上是squares的,不能进行非对称的命中测试。当一个向量认为它的边在它的路径边界上时,一个图像认为它的边界是它的整个边界框。解决方案是,当点击图片时,用图片下方的向量路径测试点击点,如果返回true,则执行释放。

票数 9
EN

Stack Overflow用户

发布于 2014-05-29 21:46:12

有用的工具

My branch of paper.js可以提供帮助,但它可能不是最适合您的。

它使您能够防止paper.js每帧重绘所有内容(使用paper.view.persistence = 1;)。

这样,您可以更好地控制要清除和应该重绘的内容:例如,当您移动形状时,可以清除该形状所在的区域(例如,使用本地canvas drawRect ),并在移动该区域后对其进行更新(使用path.needsUpdate();)。

缺点

当形状相交时,问题就来了。如果要修改一个与另一个形状相交的形状,则必须同时更新这两个形状。如果第二个形状与第三个形状相交,则情况相同,依此类推。

所以你需要一个递归函数,并不难编码,但是如果有许多复杂的形状相交,那么它可能会很昂贵,所以在这种情况下你可能得不到性能。

(更新)位图缓存

正如Nicholas Kyriakidesfollowing answer中所建议的,位图缓存是一个非常好的解决方案。

每个形状一个画布

另一种方法是在单独的画布上绘制每个形状(作为层工作)。这样,您就可以自由地分别清除和重新绘制每个形状。您可以分离未更改的视图(除用户正在处理的画布之外的所有画布)的onFrame事件。这应该更容易,但它会导致其他小问题,比如共享相同的项目视图参数(在缩放的情况下),而且对于许多形状(这意味着许多画布),它可能会很昂贵。

静态和动态画布

一种(可能)更好的方法是只有两个画布,一个用于静态形状,另一个用于活动形状。静态形状画布将包含所有形状(除了正在编辑的形状),并将在用户开始和停止编辑活动形状时重新绘制。当用户开始编辑形状时,它将从静态画布传输到动态画布,当用户停止编辑时,将以另一种方式传输。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23884074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档