使用 > 缩放和平移 HTML5 画布的最佳实践10k 个对象

2022-01-17 00:00:00 canvas javascript html5-canvas

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

I need to build kind of a map in canvas which displays over 10.000 elements (circles) and needs to be zoom- and panable. I described my approach here Android significantly slower in resizing and moving multiple canvas elements and changed my implementation on suggestions made in the comments.

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

To pan the map setTransform is now used on the canvas context and then all elements that are in the viewport are redrawn after the canvas was erased. (I get them out of an R-Tree). This happens on every mousemove event.

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

While this is really fast when I have a zoomed map with ~200 objects to draw, the panning is really slow when zoomed out and over 10k objects need to be drawn. I obviously need it to be fast, too.

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

  • 在画布上设置一个视口 div 并使画布更大(例如每边 50%)
  • 使用 topleft样式在 div 中移动画布并减少重绘频率(当画布靠近视口边界时)
  • Have a viewport div over the canvas and make the canvas bigger (like 50% to each side)
  • Move the canvas in the div with topand leftstyling and redraw less frequently (when the canvas gets close to the viewport border)

推荐答案

我的做法可能是:

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

  • Create an on-screen canvas the size of the "viewport" (the size of the browser window for instance)

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

Store the objects to draw in a data structure that lets you quickly determine which objects are visible at any given time (given the current viewport position and zoom).

然后在每次渲染时:

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

相关文章