在 Canvas HTML 上重绘大量对象
有没有一种快速有效的方法来移动 canvas
中的大量对象?基本上,如果有大约 1000 个对象,并且我想一次移动所有对象来模拟滚动,则通过调用 drawImage()
1000 多次来重绘每个对象会非常慢。
有什么办法可以优化这个吗?我有一个问题的示例链接(仅包含 100 个对象): http://craftyjs.com/isometric/< /a>
Is there a quick and efficient way to move lots of objects in canvas
? Basically if there are around 1000 objects and I want to move all of them at once to emulate scrolling, it is very slow to redraw every single object by calling drawImage()
1000+ times.
Is there anyway to optimize this? I have an example link of the problem (and that's only with 100 objects): http://craftyjs.com/isometric/
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
由于画布不提供快速低级位图复制,因此很难在多个图层中执行操作并滚动,例如一次滚动整个背景,然后仅渲染边缘。
那么你能做什么呢?简而言之,什么都没有。尤其是在滚动时,当您有或多或少的静态背景时,当然您可以使用多个画布进行技巧,但对于移动对象,几乎没有任何性能改进技巧。
所以,你必须等待所有主要浏览器中的硬件加速,我知道这听起来很荒谬,但我太等待了:/
问题是
canvas
从来都不是为游戏设计的东西。它被设计为,嗯,基本上是某种即时绘图的东西,我猜设计师想到的是 Photoshop 克隆,但绝对不是游戏,更不用说没有快速清晰的操作这一事实证明了这一点,当用相同的颜色清除整个画布时,甚至没有进行优化。Since canvas doesn't provide fast low level bitmap copying it's hard to do stuff in multiple layers and scroll for example the whole background at once and then only render the edges.
So what can you do? In short, nothing. Especially not when scrolling, sure you can do tricks with multiple canvases when you have a more or less static background but for moving objects there are hardly any performance improving tricks.
So, you've go to wait for Hardware Acceleration shipping in all majors browsers, I know this sounds ridiculous but I'm too waiting for that :/
The problem is that the
canvas
was never designed for game stuff. It was designed as, well, basically some kind of on the fly drawing thing, guess the designers had Photoshop clones in mind, but definitely not games, let alone the fact that there's no fast clear operation proves that, there's not even optimization in place when clearing the whole canvas with the same color.如果图像已经合成,没有相对于彼此移动,并且由矩形区域定义,则使用
canvas.drawImage()
以画布作为第一个参数并绘制到子对象-region 应该比重新绘制所有对象要快得多。您还可以将多个画布分层,然后用 HTML 中的对象滑动顶部画布来滚动它们。
编辑:真正查看了您的示例后,在我看来,它的实现方式应该类似于 Google 地图:创建画布图块并在 HTML 页面上向左/向右滑动它们;一旦画布完全滑出屏幕(例如,滑出左边缘),请将其移动到另一侧(右边缘)并重新使用它进行绘图。这样,您只需要重新绘制与边缘移动的画布重叠的任何对象。
If the images are already composited, not moving relative to one another, and defined by a rectangular region, then using
canvas.drawImage()
with a canvas as the first parameter and drawing to a sub-region should be significantly faster than re-drawing all the objects.You could also just layer multiple canvases and slide the top canvas with the objects in HTML to scroll them.
Edit: Having really looked at your example, it seems to me that it should be implemented similar to Google Maps: create tiles of canvases and slide them left/right on the HTML page; once a canvas has been slid off the screen entirely (for example, off the left edge), move it to the other side (to the right edge) and re-use it for drawing. With this you will only need to re-draw whatever objects overlap the canvases that are moving on the edges.
您可以在第二个离屏画布上绘制所有对象,然后仅位图传输整个画布(
drawImage()
接受 canvas 元素)。但是,如果您的目标是桌面浏览器,则不需要这样做。我已经实现了图块引擎 (源),简单地重绘整个场景,并且简单的实现速度非常快。
You can draw all objects on a second, off-screen canvas and then only blit the whole canvas (
drawImage()
accepts canvas element).However, if you're targeting desktop browsers, then this shouldn't be necessary. I've implemented tile engine (source) that simply redraws whole scene and naive implementation turned out to be pretty fast.
为了解决这个问题,我所做的就是我的屏幕上有 10 个方块,我想在白色背景上为它们设置动画。因此,我在画布上画了一个白色矩形以清除画布,以便动画可以正常工作。这有道理吗?
@Ivo顺便说一句,我在 http://www.w3.org 上读到/TR/html5/the-canvas-element.html canvas 是为游戏等应用程序制作的,因为它是摆脱对外部引擎依赖的解决方案。 Canvas 是内置的,因此它有点像浏览器中内置的由 JavaScript 驱动的 Flash 播放器。我认为这很有趣。
What I did to solve this problem was I had 10 squares on my screen and I wanted to animate them on a white background. So I drew a white rectangle over the canvas to clear the canvas so the animation would work. Does that make sense?
@Ivo By the way I read on http://www.w3.org/TR/html5/the-canvas-element.html that canvas was made for applications like games because it was a solution to get rid of the dependency on a external engine. Canvas is built in so it's kind of like a flash player built into your browser powered by JavaScript. I think it's fascinating.
您可以使用平铺渲染。
http://www.gamesfrommars.fr/demojsv2/(使用 Chrome 浏览效果更佳)
You can use tiled rendering.
http://www.gamesfrommars.fr/demojsv2/ (better viewed with Chrome)