缩放和平移包含超过 10k 个对象的 HTML5 画布的最佳实践

2023-11-27

我需要在画布中构建一种地图,它显示超过 10.000 个元素(圆圈),并且需要缩放和平移。我在这里描述了我的方法Android 在调整多个画布元素大小和移动多个画布元素时速度显着变慢并改变了我对评论中提出的建议的实施。

平移地图setTransform现在在画布上下文中使用,然后在擦除画布后重新绘制视口中的所有元素。 (我从 R 树中取出它们)。这发生在每个mousemove event.

虽然当我有一张需要绘制大约 200 个对象的缩放地图时,这确实很快,但当缩小并且需要绘制超过 10k 个对象时,平移非常慢。我显然也需要它快点。

满足此要求的最佳实践是什么?我的方法如下:

  • 在画布上放置一个视口 div 并使画布更大(比如每边 50%)
  • 在 div 中移动画布topand left样式设置和重绘频率降低(当画布接近视口边框时)

我的方法可能是:

  • 创建一个“视口”大小的屏幕画布(例如浏览器窗口的大小)

  • 将要绘制的对象存储在数据结构中,使您可以快速确定哪些对象在任何给定时间(给定当前视口位置和缩放)可见。

  • 确保要绘制的对象(圆形)可用作位图(从图像文件加载或预渲染到画布(如果您使用画布绘制它们))。
  • 给定缩放级别时,圆圈的位图应具有正确的大小,因此当缩放级别更改时,将图像预渲染到具有正确大小的离屏画布。我假设并非所有 10 000 个点都有独特的图像,它们看起来都一样,或者只有少数变化。

然后在每个渲染上:

  • 清除画布
  • 为视口中可见的每个圆圈调用drawImage(),但仅指定位置,而不指定宽度/高度或使用任何变换。重点是图像只能“复制”到视口画布 1-1。这真的很快。
  • 我建议不要在每个鼠标移动事件(或窗口调整大小等)上重绘。相反,使用 window.requestAnimationFrame() 来安排重绘。这样,您的重绘就不会超过浏览器的“刷新”速率(通常为 60 fps)。
  • 在视口中平移应该非常快,因为您只是调用drawImage(),而不对每个可见圆圈进行任何转换。当渲染并且缩放级别发生变化时,会产生重新绘制用作drawImage源的预渲染图像的成本。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

缩放和平移包含超过 10k 个对象的 HTML5 画布的最佳实践 的相关文章

随机推荐