使用>缩放和平移HTML5画布的最佳做法10k物件 [英] Best practice for zooming and panning HTML5 canvas with > 10k objects

查看:111
本文介绍了使用>缩放和平移HTML5画布的最佳做法10k物件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在画布中构建一种显示超过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树中取出来)。每次 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.

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

What would be the best practice to fulfil this requirement? My approach would be the following:


  • 在画布上设置一个视口div并使画布更大(每边50%)

  • 在div中移动画布,使用 top 样式并重画次数较少(当画布接近视口边框)

  • 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)

推荐答案

我的方法可能是:


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

  • 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源的预渲染图像的成本。

  • Clear the canvas
  • Call drawImage() for each circle being visible within the viewport, but only specify position, not width/height or use any transforms. The point being is that the image should only be "copied" to the viewport canvas 1-1. This is really fast.
  • I would suggest to not redraw on every mousemove event (or window resize etc.). Instead, use window.requestAnimationFrame() to schedule a redraw. That way you're not redrawing more than the browser's "refresh" rate, typically 60fps.
  • Panning in the viewport should be really fast since you're just calling drawImage() without any transformations for each visible circle. When you render and the zoom level has changed, there will be the cost of redrawing the pre-rendered images used as source for drawImage.

这篇关于使用>缩放和平移HTML5画布的最佳做法10k物件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆