javascript - 缩放和平移具有 > 10k 对象的 HTML5 Canvas 的最佳实践

标签 javascript canvas html5-canvas

我需要在 Canvas 中构建一种显示超过 10.000 个元素(圆圈)并且需要缩放和平移的 map 。我在这里描述了我的方法 Android significantly slower in resizing and moving multiple canvas elements并改变了我对评论中提出的建议的实现。

要平移 map setTransform 现在用于 Canvas 上下文,然后在删除 Canvas 后重新绘制视口(viewport)中的所有元素。 (我从 R 树中取出它们)。这发生在每个 mousemove 事件上。

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

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

  • 在 Canvas 上设置一个视口(viewport) div 并使 Canvas 变大(比如每边 50%)
  • 在带有topleft样式的div中移动 Canvas 并减少重绘的频率(当 Canvas 靠近视口(viewport)边界时)

最佳答案

我的方法可能是:

  • 创建“视口(viewport)”大小(例如浏览器窗口的大小)的屏幕 Canvas

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

  • 确保要绘制的对象(圆圈)可用作位图(如果您使用 Canvas 绘制它们,则可以从图像文件加载或预渲染到 Canvas )。
  • 在给定缩放级别的情况下,圆圈的位图应具有正确的大小,因此当缩放级别发生变化时,将图像预渲染到具有正确大小的屏幕外 Canvas 。我假设并非所有 10000 个点都具有独特的图像,它们看起来都一样或者只有少数变化。

然后在每个渲染上:

  • 清除 Canvas
  • 为视口(viewport)中可见的每个圆调用 drawImage(),但仅指定位置,不指定宽度/高度或使用任何变换。关键是图像应该只“复制”到视口(viewport) Canvas 1-1。这真的很快。
  • 我建议不要在每次鼠标移动事件(或窗口调整大小等)时重绘。相反,使用 window.requestAnimationFrame() 来安排重绘。这样你就不会重绘超过浏览器的“刷新”率,通常是 60fps。
  • 在视口(viewport)中平移应该非常快,因为您只是调用 drawImage() 而不对每个可见圆圈进行任何转换。当您渲染并且缩放级别发生变化时,将产生重新绘制用作 drawImage 源的预渲染图像的成本。

关于javascript - 缩放和平移具有 > 10k 对象的 HTML5 Canvas 的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43543679/

相关文章:

canvas - 如何避免 Canvas 中填充区域之间的接缝?

javascript - 用图片填充 HTML5 arc - HTML5 Canvas

javascript - HTML5 Canvas ,多边形上/多边形中的图像可能吗?

javascript - javascript中的search()方法无法在包含 "\\ch"的字符串中搜索它

javascript - 如何使用JS代码读取文本文件?

javascript - jQuery 函数在第一次单击时部分触发,在第二次单击时起作用

HTML5 网络摄像头提要,试图在计时器上将图像绘制到 Canvas 上

javascript - 在 Blade foreach 循环中使用 JS 动态更改 div CSS 背景

Javascript block 脚本执行

javascript - Canvas - 获取多个 Canvas 叠加中的像素颜色