动态创建元素并能够移动它们的最佳方法是什么?例如,假设我想创建一个矩形、圆和多边形,然后选择这些对象并移动它们。

我知道HTML5提供了三个元素,可以使这成为可能:svg, canvas和div。对于我想做的事情,这些元素中哪一个将提供最佳性能?

为了比较这些方法,我想创建三个视觉上相同的网页,每个网页都有一个页眉、页脚、小部件和文本内容。第一个页面中的小部件将完全使用canvas元素创建,第二个页面完全使用svg元素创建,第三个页面使用普通div元素、HTML和CSS创建。


当前回答

它们都有好的方面和坏的方面,下面我们来比较一下。

Canvas将具有最佳的整体性能,但前提是您正确使用它。

Divs:

良好的性能 您可以使用DOM操作它 您可以访问DOM事件 CSS支持 很难做出复杂的形状

性能测试:https://kajam.hg0428.repl.co/pref/

帆布:

更好的形状支撑 伟大的成就 强大的浏览器支持 没有CSS

性能测试:https://js-game-engine.hg0428.repl.co/canvasTest/preform.html

svg:

更好的形状支撑 更难使用 良好的浏览器支持 没有CSS,但有很多不同的SVG 糟糕的性能

我还没有对此进行性能测试,但根据其他测试,它并不好。

要使Canvas快速:

Canvas可以具有非常动态的性能,因此让我们回顾一些技巧。 避免使用ctx。Rect和ctx。填充,使用ctx。fillRect代替,这是最大的一个,它可以毁掉即使是最简单的游戏。 不要使用填充和描边的形状,而是使用填充[形状]。

如果你不记得在使用canvas时,你的游戏将会非常慢。这是我从经验中学到的。

其他回答

只是我对divs选项的意见。

《Famous/Infamous》和《samyazare》(可能还有其他游戏)使用绝对定位的非嵌套divs(带有非繁琐的HTML/CSS内容),结合matrix2d/matrix3d进行定位和2D/3D转换,并在中等移动硬件上实现了稳定的60FPS,所以我不认为divs是一个缓慢的选择。

Youtube和其他地方有大量的屏幕记录,高性能的2D/3D东西运行在浏览器中,所有东西都是一个DOM元素,你可以在上面检查元素,60FPS(混合WebGL用于某些效果,但不适用于渲染的主要部分)。

For your purposes, I recommend using SVG, since you get DOM events, like mouse handling, including drag and drop, included, you don't have to implement your own redraw, and you don't have to keep track of the state of your objects. Use Canvas when you have to do bitmap image manipulation and use a regular div when you want to manipulate stuff created in HTML. As to performance, you'll find that modern browsers are now accelerating all three, but that canvas has received the most attention so far. On the other hand, how well you write your javascript is critical to getting the most performance with canvas, so I'd still recommend using SVG.

虽然上面的大多数答案仍然有一定的道理,但我认为它们值得更新:

Over the years the performance of SVG has improved a lot and now there is hardware-accelerated CSS transitions and animations for SVG that do not depend on JavaScript performance at all. Of course JavaScript performance has improved, too and with it the performance of Canvas, but not as much as SVG got improved. Also there is a "new kid" on the block that is available in almost all browsers today and that is WebGL. To use the same words that Simon used above: It beats both Canvas and SVG hands down. This doesn't mean it should be the go-to technology, though, since it's a beast to work with and it is only faster in very specific use-cases.

恕我直言,对于今天的大多数用例,SVG提供了最好的性能/可用性比率。可视化需要非常复杂(就元素数量而言),同时又非常简单(每个元素),这样Canvas和WebGL才能真正发挥作用。

在这个类似问题的答案中,我提供了更多的细节,为什么我认为这三种技术的组合有时是最好的选择。

在谷歌上搜索时,我在http://teropa.info/blog/2016/12/12/graphics-in-angular-2.html上找到了关于SVG和Canvas的使用和压缩的很好的解释

希望能有所帮助:

SVG, like HTML, uses retained rendering: When we want to draw a rectangle on the screen, we declaratively use a element in our DOM. The browser will then draw a rectangle, but it will also create an in-memory SVGRectElement object that represents the rectangle. This object is something that sticks around for us to manipulate – it is retained. We can assign different positions and sizes to it over time. We can also attach event listeners to make it interactive. Canvas uses immediate rendering: When we draw a rectangle, the browser immediately renders a rectangle on the screen, but there is never going to be any "rectangle object" that represents it. There's just a bunch of pixels in the canvas buffer. We can't move the rectangle. We can only draw another rectangle. We can't respond to clicks or other events on the rectangle. We can only respond to events on the whole canvas. So canvas is a more low-level, restrictive API than SVG. But there's a flipside to that, which is that with canvas you can do more with the same amount of resources. Because the browser does not have to create and maintain the in-memory object graph of all the things we have drawn, it needs less memory and computation resources to draw the same visual scene. If you have a very large and complex visualization to draw, Canvas may be your ticket.

了解SVG和Canvas之间的区别将有助于选择正确的格式。

帆布

分辨率的依赖 不支持事件处理程序 糟糕的文本渲染能力 您可以将生成的图像保存为.png或.jpg 非常适合图像密集型游戏

SVG

分辨率独立 支持事件处理程序 最适合具有大渲染区域的应用程序(谷歌Maps) 如果复杂,呈现速度会很慢(任何大量使用DOM的东西都会如此) 慢) 不适合游戏应用