对于你来说,SVG会更加容易,因为它已经内置了选择和移动对象功能。SVG对象是DOM对象,因此它们具有“click”处理程序等功能。
DIV可以使用,但是当加载大量时性能较差且不太灵活。
Canvas的性能最佳,但您必须自己实现所有受控状态的概念(例如对象选择),或使用库。
HTML5 Canvas仅是一个位图绘图表面。您设置要绘制的东西(例如颜色和线条粗细),然后将其绘制出来,然后Canvas不知道绘制的内容在哪里或是什么,它仅仅是像素。如果您想绘制矩形并使其移动或可选择,则必须从头开始编写所有代码,包括记住您绘制的内容的代码。
另一方面,SVG必须保持对其呈现的每个对象的引用。您创建的每个SVG / VML元素都是DOM中的一个真实元素。默认情况下,这允许您更好地跟踪创建的元素,并通过默认方式更轻松地处理诸如鼠标事件之类的事情,但是当存在大量对象时,速度会显着降低。
那些SVG DOM引用意味着处理您绘制的内容的某些工作已经为您完成了。当渲染非常大的对象时,SVG更快,但是在渲染许多对象时较慢。
对于游戏,Canvas可能会更快。对于大型地图程序,则使用SVG可能会更快。如果您确实想使用Canvas,则我有一些关于如何启用可移动对象的教程在这里。
如果要进行更快的事情和重度位图操作(例如动画),则Canvas更好,但如果要进行大量互动,则需要编写更多代码。
我对基于HTML DIV和Canvas的绘图做了一些比较测试。虽然我可以写一篇关于二者优缺点的巨型文章,但是以下是我测试的一些相关结果,供您考虑特定应用:
我创建了Canvas和HTML DIV测试页面,两个页面都有可移动的"节点”。Canvas节点是我在Javascript中创建并跟踪的对象。HTML节点则是可移动的Divs。
我在这两个测试页面中均添加了10万个节点。它们的性能表现截然不同:
HTML测试标签页需要很长时间才能加载(计时略小于5分钟,Chrome第一次打开时询问是否关闭该页面)。Chrome任务管理器显示该标签页占用了168MB。当我观看该页面时,CPU时间占用率为12-13%,当我没有观看时,CPU时间占用率为0%。
Canvas标签页1秒钟即可加载,并且只占用30MB。它也一直占用13%的CPU时间,无论是否正在查看它。(2013年的编辑:他们大多已经修复了这个问题)
在HTML页面上拖动更加平滑,这是设计所预期的,因为当前设置是每30毫秒重新绘制Canvas测试中的所有内容。Canvas还有很多优化空间(例如canvas失效、欧拉剪辑、选择性重绘等等,这取决于您想要实现多少)。
毫无疑问,您可以让Canvas在对象操作方面比简单测试中的div更快,并且在加载时间上当然也更快。Canvas的绘制/加载速度更快,而且还有更多优化空间(例如,排除屏幕外的元素非常容易)。
此外,我一直在做一个图表应用程序,并最初使用了canvas。该图表包含许多节点,它们可能相当大。用户可以在图表中拖动元素。
我发现,在我的Mac上,对于非常大的图像,SVG更加优越。我有一台2013年的MacBook Pro 13英寸Retina,当用户在图表中拖动对象时,它可以很好地运行下面的示例。该图像为6000x6000像素,并且有1000个对象。在canvas中进行类似的构建对于我来说是不可能进行动画的。
在现代显示器上,您还必须考虑不同的分辨率,而SVG为您提供了所有这些免费功能。
示例:http://jsfiddle.net/knutsi/PUcr8/16/
全屏:http://jsfiddle.net/knutsi/PUcr8/16/embedded/result/
var wiggle_factor = 0.0;
nodes = [];
// create svg:
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('style', 'border: 1px solid black');
svg.setAttribute('width', '6000');
svg.setAttribute('height', '6000');
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink",
"http://www.w3.org/1999/xlink");
document.body.appendChild(svg);
function makeNode(wiggle) {
var node = document.createElementNS("http://www.w3.org/2000/svg", "g");
var node_x = (Math.random() * 6000);
var node_y = (Math.random() * 6000);
node.setAttribute("transform", "translate(" + node_x + ", " + node_y +")");
// circle:
var circ = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circ.setAttribute( "id","cir")
circ.setAttribute( "cx", 0 + "px")
circ.setAttribute( "cy", 0 + "px")
circ.setAttribute( "r","100px");
circ.setAttribute('fill', 'red');
circ.setAttribute('pointer-events', 'inherit')
// text:
var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
text.textContent = "This is a test! ÅÆØ";
node.appendChild(circ);
node.appendChild(text);
node.x = node_x;
node.y = node_y;
if(wiggle)
nodes.push(node)
return node;
}
// populate with 1000 nodes:
for(var i = 0; i < 1000; i++) {
var node = makeNode(true);
svg.appendChild(node);
}
// make one mapped to mouse:
var bnode = makeNode(false);
svg.appendChild(bnode);
document.body.onmousemove=function(event){
bnode.setAttribute("transform","translate(" +
(event.clientX + window.pageXOffset) + ", " +
(event.clientY + window.pageYOffset) +")");
};
setInterval(function() {
wiggle_factor += 1/60;
nodes.forEach(function(node) {
node.setAttribute("transform", "translate("
+ (Math.sin(wiggle_factor) * 200 + node.x)
+ ", "
+ (Math.sin(wiggle_factor) * 200 + node.y)
+ ")");
})
},1000/60);
了解SVG和Canvas之间的区别有助于选择合适的技术。
Canvas
SVG
虽然以上回答大多数仍然有一定的真实性,但我认为它们需要更新:
多年来,SVG的性能有了很大的提升,现在有支持硬件加速的CSS转换和动画功能,不需要依赖于JavaScript性能。当然,JavaScript的性能也有所改善,Canvas的性能也随之提高,但是SVG得到的改进远远超过了这些。此外,现在几乎所有浏览器都支持一个“新生代”技术WebGL。用Simon上面的话来说:WebGL毫无疑问胜过Canvas和SVG。不过这并不意味着它应该成为首选技术,因为使用它需要付出更多的努力,而且它只在非常特定的用例中才更快。
我认为,在大多数用例中,SVG给出了最佳的性能/易用性比。视觉化必须非常复杂(就元素数量而言),同时每个元素非常简单,这样Canvas甚至WebGL才能真正发挥优势。
在类似问题的回答中,我提供了更多细节,说明为什么三种技术相结合有时是您最好的选择。
where only simple... ...the performance of Canvas is actually better if you have lots and lots of elements on the screen at the same time.
这是我见过的最好的研究,交互式演示非常棒!尽管通过我的自己的测试,我没有能够看到svg/canvas在复杂情况下有多大差异,所以我仍然想知道SVG是否能够胜过Canvas? - ecoe我同意Simon Sarris的结论:
我比较了一些Protovis(SVG)和Processingjs(Canvas)中显示超过2000个点的可视化效果,processingjs比protovis快得多。
使用SVG处理事件当然更容易,因为你可以将它们附加到对象上。在Canvas中,您必须手动执行此操作(检查鼠标位置等),但对于简单的交互,这应该不难。
还有dojo工具包的dojo.gfx库。它提供了一个抽象层,您可以指定渲染器(SVG、Canvas、Silverlight)。这也可能是一个可行的选择,尽管我不知道额外的抽象层会增加多少开销,但它使编写交互和动画变得容易,并且与渲染器无关。
以下是一些有趣的基准测试:
关于使用div选项,这是我的两分钱。
Famous/Infamous和SamsaraJS(可能还有其他库)使用非嵌套的绝对定位的div(包含较复杂的HTML/CSS内容),结合matrix2d/matrix3d进行定位和2D/3D变换,在中等移动设备上实现了稳定的60FPS,因此我认为div并不是一个慢选项。
在YouTube和其他地方有许多屏幕录像,高性能的2D/3D内容在浏览器中运行,其中所有元素都是DOM元素,您可以在其上“检查元素”,实现了60FPS的流畅演示(与WebGL混合使用以实现某些效果,但并非主要渲染部分)。
针对您的需求,我建议使用SVG。因为它包含DOM事件(如鼠标处理、拖放等),无需实现自己的重绘,并且无需跟踪对象状态。当您需要进行位图图像操作时,请使用Canvas。当您想要操作在HTML中创建的内容时,请使用普通的div。关于性能,您会发现现代浏览器都在加速这三种技术,但是Canvas目前得到了最多的关注。另一方面,良好编写的JavaScript对于使用Canvas获取最佳性能至关重要,因此我仍然建议使用SVG。
所有技术都有优点和缺点,下面我们来比较一下。
Canvas在总体性能方面表现最佳,但前提是使用正确。
性能测试: https://kajam.hg0428.repl.co/pref/
性能测试: https://js-game-engine.hg0428.repl.co/canvasTest/preform.html
我还没有为它做过性能测试,但基于其他测试结果,它的表现不好。
Canvas可以具有非常动态的性能,因此让我们回顾一些技巧。
避免使用 ctx.rect
和 ctx.fill
,改用 ctx.fillRect
,这是最重要的一点,它甚至可以破坏最简单的游戏。
使用形状的 fill
和 stroke
,而是使用 fill[Shape]
。
如果你忘记了在Canvas中使用这些技巧,你的游戏会很慢。我通过经验得出了这个结论。
preform.js:36 未捕获的类型错误:无法设置未定义的属性(设置“type”) 在OnDocumentClick(preform.js:36:15)
- Jason S在谷歌搜索时,我发现了一篇关于使用和压缩SVG和Canvas的好解释,链接为http://teropa.info/blog/2016/12/12/graphics-in-angular-2.html
希望对你有所帮助:
- SVG和HTML一样,使用保留渲染:当我们想在屏幕上绘制一个矩形时,在DOM中我们声明使用一个
<rect>
元素。浏览器会绘制一个矩形,但同时也会创建一个代表该矩形的内存中的SVGRectElement对象。这个对象将一直存在,供我们操作-它是被保留的。我们可以随时间分配不同的位置和大小给它。我们还可以附加事件监听器使其交互。- Canvas使用即时渲染:当我们绘制一个矩形时,浏览器立即在屏幕上呈现一个矩形,但永远不会有任何代表它的“矩形对象”。只有画布缓冲区中的一堆像素。我们无法移动矩形。我们只能绘制另一个矩形。我们无法响应单击或其他事件,只能响应整个画布上的事件。
因此,Canvas比SVG更低级别、限制性的API。但是,这也有一个反面,就是使用相同数量的资源,你可以做更多的事情。因为浏览器不必创建和维护我们绘制的所有东西的内存中对象图,所以在绘制相同的视觉场景时,需要更少的内存和计算资源。如果你有一个非常大而复杂的可视化要绘制,Canvas可能是你的选择。
该工具输出HTML/CSS常规多边形,而不是canvas或SVG(声明,我编写了它)https://html-polygon.com
这可能更容易用于交互性,因为结果是真正存在于HTML DOM中的HTML元素。
目前只有React和Vue包,但网站上的试玩工具可以在您不使用这些包且不需要动态生成的多边形形状时暴露出生成的HTML。
div
即可。我更喜欢SVG,因为它简单明了,坐标明确(免受CSS更改的影响),而且比div更好用。当然,使用HTML可以更轻松地进行复杂文本渲染。如果只是矩形(但有成千上万个),则WebGL值得一看,但否则过度设计。 - Sebastian