Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript HTML5画布vs.SVG vs.div_Javascript_Html_Svg_Html5 Canvas - Fatal编程技术网

Javascript HTML5画布vs.SVG vs.div

Javascript HTML5画布vs.SVG vs.div,javascript,html,svg,html5-canvas,Javascript,Html,Svg,Html5 Canvas,动态创建元素并能够移动它们的最佳方法是什么?例如,假设我想创建一个矩形、圆形和多边形,然后选择这些对象并移动它们 我知道HTML5提供了三个元素使之成为可能:,和。对于我想做的事情,这些元素中的哪一个将提供最好的性能 为了比较这些方法,我考虑创建三个视觉上完全相同的网页,每个网页都有页眉、页脚、小部件和文本内容。第一页中的小部件将完全使用canvas元素创建,第二页完全使用svg元素创建,第三页使用普通的div元素、HTML和CSS创建。出于您的目的,我建议使用svg,因为您可以获得DOM事件,

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

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


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

出于您的目的,我建议使用svg,因为您可以获得DOM事件,比如鼠标处理,包括拖放,您不必实现自己的重画,也不必跟踪对象的状态。当您必须进行位图图像操作时,请使用画布;当您想要操作在HTML中创建的内容时,请使用常规div。至于性能,您会发现现代浏览器现在正在加速这三个方面的速度,但到目前为止,画布受到了最多的关注。另一方面,如何编写javascript对于使用canvas获得最佳性能至关重要,因此我仍然建议使用SVG。

简短回答: SVG对您来说会更容易,因为选择和移动SVG已经内置。SVG对象是DOM对象,因此它们具有“单击”处理程序等

div还可以,但是笨重,而且在大量加载时性能很差

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


答案很长: HTML5画布只是位图的绘图表面。你设置好画图(比如用颜色和线条粗细),画那个东西,然后画布就不知道那个东西了:它不知道它在哪里,也不知道你刚才画的是什么,只是像素。如果要绘制矩形并使其四处移动或可选择,则必须从头开始编写所有代码,包括要记住绘制矩形的代码

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

这些SVG DOM引用意味着处理您绘制的东西的一些步骤是为您完成的。SVG在渲染非常大的对象时速度更快,但在渲染许多对象时速度较慢

在画布上玩游戏可能会更快。在SVG中,大型地图程序可能会更快。如果你真的想使用画布,我有一些关于启动和运行可移动对象的教程

画布对于更快的事情和繁重的位图操作(比如动画)来说会更好,但是如果你想要更多的交互性,它需要更多的代码

我在HTMLDIV制作的图形和画布制作的图形上运行了一系列数字。我可以做一个关于每个好处的大文章,但是我会给出我的测试的一些相关的结果来考虑你的具体应用:

我制作了Canvas和htmldiv测试页面,它们都有可移动的“节点”。Canvas节点是我用Javascript创建并跟踪的对象。HTML节点是可移动的div

我在两个测试中都添加了100000个节点。他们的表现完全不同:

加载HTML测试标签花了很长时间(时间略低于5分钟,chrome第一次要求关闭页面)。Chrome的任务管理器表示,该选项卡占用了168MB。当我看它时,它占用12-13%的CPU时间,当我不看时,它占用0%

画布选项卡在1秒内加载,占用30MB的空间。它也占据了13%的CPU时间的所有时间,无论是否有人在看它。(2013年编辑:他们基本上解决了这个问题)

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

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

结论:
  • SVG可能更适合于项目较少的应用程序和应用程序(少于1000个?视情况而定)
  • 画布对于成千上万的对象和仔细的操作来说是更好的,但是需要更多的代码(或者一个库)才能让它启动
  • HTML div笨重且不可缩放,只有圆角才能生成圆,生成复杂形状是可能的,但涉及数百个像素宽的微小div。疯狂随之而来

我同意西蒙·萨里斯的结论:

我将Protovis(SVG)中的一些可视化与Processingjs(Canvas)进行了比较,后者显示>2000个点,Processingjs比Protovis快得多

使用SVG处理事件当然更容易,因为您可以将它们附加到对象。在画布中,您必须手动执行(检查鼠标位置等),但对于简单的交互来说,这并不难

还有DojoToolkit的库。它提供了一个抽象层,您可以指定渲染器(SVG、画布、Silverlight)。那个
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);