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

我知道HTML5提供了三个元素,可以实现这一点:div8/embedded-content-0.html#svg" rel="noreferrer">svg、div8/scripting-1.html#the-canvas-element" rel="noreferrer">canvas和div.对于我想做的事情,这些元素中哪一个将提供最好的性能?

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

推荐答案

简而言之:

SVG对于您来说应该是easier,因为已经内置了 Select 和移动它.SVG对象是DOM对象,因此它们有"单击"处理程序等.

DIV还可以,但笨重,有awful个性能负载.

Canvas具有最好的性能,但您必须自己实现托管状态(对象 Select 等)的所有概念,或者使用库.


长长的答案是:

HTML5画布只是一个位图的绘图表面.你设置好画图(比如用 colored颜色 和线条粗细),画那个东西,然后画布对那个东西一无所知:它不知道它在哪里,或者你刚刚画的是什么,它只是像素.如果你想画矩形,让它们四处移动或是可 Select 的,那么你必须从头开始编写所有的代码,including个代码来记住你画了它们.

另一方面,SVG必须维护对其渲染的每个对象的引用.您创建的每个SVG/VML元素都是DOM中的真实元素.默认情况下,这允许您更好地跟踪所创建的元素,并在默认情况下使处理鼠标事件之类的事情变得更容易,但当存在大量对象时,速度会显著降低

这些SVG DOM引用意味着处理您绘制的东西的一些步骤是为您完成的.SVG在渲染really large个对象时速度更快,但在渲染many个对象时速度较慢.

在画布上玩游戏可能会更快.在SVG中,大型 map 程序可能会更快.如果你真的想使用Canvas,我有一些教程介绍如何启动和运行here个可移动对象.

Canvas会更好地处理更快的事情和繁重的位图操作(比如动画),但如果你想要更多的交互性,它会占用更多的代码.

我在HTML DIV制作的绘图和画布制作的绘图上运行了一大堆数字.我可以用很长的篇幅来说明每种测试的好处,但我会给出一些相关的测试结果,供您考虑具体的应用:

我制作了Canvas和HTMLDiv测试页面,它们都有可移动的" node "画布 node 是我在Javascript中创建并跟踪的对象.HTML node 是可移动的div.

我在两个测试中都添加了100000个 node .他们的表现截然不同:

加载HTML测试选项卡花费了很长时间(时间略低于5分钟,Chrome第一次要求终止页面).Chrome的任务管理器说标签页占用了168MB.当我看着它的时候,它占用了12-13%的CPU时间,当我不看的时候,占用了0%的CPU时间.

画布选项卡在一秒内加载,占用30MB.无论用户是否正在查看它,它都会一直占用CPU时间的13%.(2013 edit: They've mostly fixed that)

在HTML页面上拖动会更平滑,这是设计所期望的,因为当前的设置是在画布测试中每隔30毫秒重新绘制所有内容.为此,Canvas有很多优化.(画布失效是最简单的,也包括裁剪区域、 Select 性重画等.这取决于您想要实现的程度)

毫无疑问,在这个简单的测试中,您可以让Canvas在对象操作方面比Div更快,当然在加载时间方面也要快得多.在画布中绘制/加载速度更快,并且有更大的优化空间(即,排除屏幕外的内容非常容易).

结论:

  • SVG可能更适合应用程序和项目较少(少于1000?)的应用程序.真的要看情况了)
  • Canvas更适合于成千上万的对象和仔细的操作,但需要更多的代码(或库)才能将其启动.
  • HTML div笨重且不可zoom ,只能用圆角绘制圆,制作复杂形状是可能的,但涉及数百个小像素宽的div.疯狂随之而来.

Javascript相关问答推荐

事件错误:类型错误:无法读取未定义的属性(读取stopPropagation)

如何使用CSS和JavaScript创建粘性、凝聚力的形状到形状(容器)变形?

我不明白这个react 组件有什么问题

如何编辑代码FlipDown.js倒计时?

在JavaScript中对大型级联数组进行切片的最有效方法?

Vega中的模运算符

在贝塞尔曲线的直线上找不到交叉点:(使用@Pomax的bezier.js)

我在这个黑暗模式按钮上做错了什么?

使用i18next在React中不重新加载翻译动态数据的问题

jQuery s data()[storage object]在vanilla JavaScript中?'

扩展类型的联合被解析为基类型

类构造函数忽略Reaction Native中的可选字段,但在浏览器中按预期工作

在使用REACT更改了CSS类之后,无法更改CSS样式

将Node.js包发布到GitHub包-错误ENEEDAUTH

如何在 Select 文本时停止Click事件?

将异步回调转换为异步生成器模式

Google脚本数组映射函数横向输出

使用自动识别发出信号(&Q)

Node.js错误: node 不可单击或不是元素

将延迟加载的模块转换为Eager 加载的模块