什么是动态创建元素并能够移动它们的最佳方法?例如,假设我想创建一个矩形,圆形和多边形,然后选择这些对象并移动它们 .
我知道HTML5提供了三个可以实现此目标的元素:svg,canvas和div . 对于我想要做的,哪些元素将提供最佳性能?
为了比较这些方法,我考虑创建三个视觉上相同的网页,每个网页都有页眉,页脚,小部件和文本内容 . 第一页中的小部件将完全使用 canvas 元素创建,第二个完全使用 svg 元素创建,第三个使用普通 div 元素,HTML和CSS创建 .
canvas
svg
div
我同意Simon Sarris的结论:
我将Protovis(SVG)中的一些可视化与Processingjs(Canvas)进行了比较,后者显示> 2000点,处理js比protovis快得多 .
使用SVG处理事件当然要容易得多,因为您可以将它们附加到对象上 . 在Canvas中你必须手动完成(检查鼠标位置等),但是为了简单的交互,它应该不难 .
还有dojo工具包的dojo.gfx库 . 它提供了一个抽象层,您可以指定渲染器(SVG,Canvas,Silverlight) . 这可能也是一个可行的选择,虽然我不知道额外的抽象层增加多少开销,但它使编码交互和动画变得容易,并且与渲染器无关 .
以下是一些有趣的基准测试:
http://svbreakaway.info/tp.php#jan21a
http://www.eleqtriq.com/2010/02/canvas-svg-flash/
http://smus.com/canvas-vs-svg-performance/
了解SVG和Canvas之间的差异将有助于选择正确的 .
帆布
取决于分辨率
不支持事件处理程序
文本渲染能力差
您可以将生成的图像另存为.png或.jpg
非常适合图形密集型游戏
SVG
独立分辨率
支持事件处理程序
最适合具有大渲染区域的应用程序(谷歌 Map )
缓慢渲染,如果复杂(任何使用DOM的东西都会很慢)
不适合游戏应用
出于您的目的,我建议使用SVG,因为您获得了DOM事件,如鼠标处理,包括拖放,包括,您不必实现自己的重绘,并且您不必跟踪状态你的对象 . 当你想要操作在HTML中创建的东西时,必须使用Canvas进行位图图像处理并使用常规div . 至于性能,你会发现现代浏览器现在正在加速这三种,但到目前为止,该画布受到了最多的关注 . 另一方面,你编写javascript的程度对于使用canvas获得最佳性能至关重要,所以我仍然建议使用SVG .
谷歌搜索时,我发现有关 SVG 和 Canvas 的使用和压缩的良好解释http://teropa.info/blog/2016/12/12/graphics-in-angular-2.html
希望能帮助到你:
与HTML一样,SVG使用保留渲染:当我们想在屏幕上绘制一个矩形时,我们声明性地在DOM中使用一个元素 . 然后浏览器将绘制一个矩形,但它也将创建一个表示矩形的内存中SVGRectElement对象 . 这个对象是我们操纵的东西 - 它被保留下来 . 我们可以随着时间的推移分配不同的位置和大小 . 我们还可以附加事件监听器以使其具有交互性 . Canvas使用立即渲染:当我们绘制一个矩形时,浏览器立即在屏幕上呈现一个矩形,但是永远不会有任何代表它的“矩形对象” . 画布缓冲区中只有一堆像素 . 我们无法移动矩形 . 我们只能绘制另一个矩形 . 我们无法响应矩形上的点击或其他事件 . 我们只能回应整个画布上的事件 . 因此,canvas是一种比SVG更低级,限制性更强的API . 但是有一个反面,那就是使用画布,你可以用相同数量的资源做更多事情 . 因为浏览器不必创建和维护我们绘制的所有内容的内存中对象图,所以它需要较少的内存和计算资源来绘制相同的可视场景 . 如果您要绘制非常大且复杂的可视化,Canvas可能是您的票证 .
为了补充这一点,我一直在做一个图表应用程序,最初开始使用canvas . 该图由许多节点组成,它们可以变得非常大 . 用户可以拖动图表中的元素 .
我发现在我的Mac上,对于非常大的图像,SVG是优越的 . 我有一个MacBook Pro 2013 13“Retina,它在下面运行得很好 . 图像是6000x6000像素,有1000个物体 . 当用户拖动物体时,画布中的类似结构不可能为我设置动画 . 图 .
在现代显示器上,您还必须考虑到不同的分辨率,这里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 100 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的性能得到了很大改善,现在有 hardware-accelerated CSS transitions and animations for SVG 完全不依赖于JavaScript性能 . 当然,JavaScript性能也得到了提升,Canvas的性能也得到了提升,但没有SVG得到改进的那么多 . 此外,该块上的"new kid"几乎在所有浏览器中都可用,这是 WebGL . 要使用Simon上面使用的相同单词:它是 beats both Canvas and SVG . 这不是一个可以使用的野兽,它只在非常具体的用例中更快 .
对于大多数用例来说,恕我直言,SVG提供了最佳的性能/可用性比率 . 可视化需要非常复杂(关于元素数量)并且同时非常简单(每个元素),因此Canvas甚至更加如此WebGL真正闪耀 .
在this answer to a similar question我提供了更多细节,为什么我认为所有这三种技术中的_163400有时候是你最好的选择 .
SVG对你来说会更容易,因为已经内置了选择和移动它.SVG对象是DOM对象,所以它们有"click"处理程序等 .
DIV很好,但很笨重,而且大量的性能负载很差 .
Canvas具有最佳性能,但您必须自己实现托管状态(对象选择等)的所有概念,或使用库 .
HTML5 Canvas只是位图的绘图表面 . 你设置绘制(用颜色和线条粗细说),绘制那个东西,然后画布不知道那个东西:它不是刚绘制的,它只是像素 . 如果你想绘制矩形并让它们四处移动或者可以选择,那么你必须从头开始编写所有这些代码, including 代码记住你画了它们 .
另一方面,SVG必须维护对它呈现的每个对象的引用 . 您创建的每个SVG / VML元素都是DOM中的真实元素 . 默认情况下,这允许您更好地跟踪您创建的元素,并且默认情况下更容易处理鼠标事件等事情,但是当存在大量对象时,它会显着减慢速度
那些SVG DOM引用意味着处理你绘制的东西的一些步法是为你完成的 . 渲染非常大的对象时SVG速度更快,渲染许多对象时速度更慢 .
Canvas中的游戏可能会更快 . 在SVG中,一个巨大的 Map 程序可能会更快 . 如果你想使用Canvas,我有一些关于使可移动对象运行here的教程 .
Canvas对于更快的事物和繁重的位图操作(如动画)会更好,但如果你想要很多交互性,它会占用更多的代码 .
我在HTML DIV制作的绘图和Canvas制作的绘图上运行了一堆数字 . 我可以发表一篇关于每项优势的重要文章,但我会根据您的具体应用考虑我的测试的一些相关结果:
我制作了Canvas和HTML DIV测试页面,两者都有可移动的“节点” . Canvas节点是我创建的对象,并在Javascript中跟踪 . HTML节点是可移动的Div .
我在两次测试中都添加了100,000个节点 . 他们表现完全不同:
HTML测试选项卡需要永久加载(时间略短于5分钟,chrome要求第一次终止页面) . Chrome的任务经理表示该标签占用了168MB . 当我看着它时占用12-13%的CPU时间,当我不看时它占用0% .
“画布”选项卡在一秒钟内加载,占用30MB . 它总是占用CPU时间的13%,无论是否正在查看它 . (2013年编辑:他们大多修复了)
在HTML页面上拖动更平滑,这是设计所期望的,因为当前设置是在Canvas测试中每30毫秒重绘一次 . Canvas有很多优化可供选择 . (画布失效是最简单的,也是裁剪区域,选择性重绘等等 . 只取决于你实现的感觉)
毫无疑问,你可以让Canvas在对象操作中更快地成为那个简单测试中的div,当然加载时间要快得多 . Canvas中的绘图/加载速度更快,并且具有更多的优化空间(即,排除屏幕外的内容非常容易) .
SVG可能更适用于项目很少的应用程序和应用程序(少于1000个?真的取决于)
Canvas对于成千上万的对象和谨慎的操作更好,但需要更多的代码(或库)来实现它 .
HTML Divs很笨重而且没有缩放,只有圆角才能形成圆形,使复杂的形状成为可能,但涉及数百个微小的微小像素范围的div . 疯狂随之而来 .
关于divs选项只需2美分 .
Famous / Infamous和SamsaraJS(可能还有其他人)使用绝对定位的非嵌套div(具有非平凡的HTML / CSS内容),结合matrix2d / matrix3d进行定位和2D / 3D转换,并在中等移动硬件上实现稳定的60FPS所以我认为反对div是一个缓慢的选择 .
在Youtube和其他地方有大量的屏幕录制,在浏览器中运行的高性能2D / 3D内容,所有内容都是一个DOM元素,你可以在60FPS上检查元素(与WebGL混合用于某些效果,但不适用于渲染的主要部分) .
8 回答
我同意Simon Sarris的结论:
我将Protovis(SVG)中的一些可视化与Processingjs(Canvas)进行了比较,后者显示> 2000点,处理js比protovis快得多 .
使用SVG处理事件当然要容易得多,因为您可以将它们附加到对象上 . 在Canvas中你必须手动完成(检查鼠标位置等),但是为了简单的交互,它应该不难 .
还有dojo工具包的dojo.gfx库 . 它提供了一个抽象层,您可以指定渲染器(SVG,Canvas,Silverlight) . 这可能也是一个可行的选择,虽然我不知道额外的抽象层增加多少开销,但它使编码交互和动画变得容易,并且与渲染器无关 .
以下是一些有趣的基准测试:
http://svbreakaway.info/tp.php#jan21a
http://www.eleqtriq.com/2010/02/canvas-svg-flash/
http://smus.com/canvas-vs-svg-performance/
了解SVG和Canvas之间的差异将有助于选择正确的 .
帆布
取决于分辨率
不支持事件处理程序
文本渲染能力差
您可以将生成的图像另存为.png或.jpg
非常适合图形密集型游戏
SVG
独立分辨率
支持事件处理程序
最适合具有大渲染区域的应用程序(谷歌 Map )
缓慢渲染,如果复杂(任何使用DOM的东西都会很慢)
不适合游戏应用
出于您的目的,我建议使用SVG,因为您获得了DOM事件,如鼠标处理,包括拖放,包括,您不必实现自己的重绘,并且您不必跟踪状态你的对象 . 当你想要操作在HTML中创建的东西时,必须使用Canvas进行位图图像处理并使用常规div . 至于性能,你会发现现代浏览器现在正在加速这三种,但到目前为止,该画布受到了最多的关注 . 另一方面,你编写javascript的程度对于使用canvas获得最佳性能至关重要,所以我仍然建议使用SVG .
谷歌搜索时,我发现有关 SVG 和 Canvas 的使用和压缩的良好解释http://teropa.info/blog/2016/12/12/graphics-in-angular-2.html
希望能帮助到你:
为了补充这一点,我一直在做一个图表应用程序,最初开始使用canvas . 该图由许多节点组成,它们可以变得非常大 . 用户可以拖动图表中的元素 .
我发现在我的Mac上,对于非常大的图像,SVG是优越的 . 我有一个MacBook Pro 2013 13“Retina,它在下面运行得很好 . 图像是6000x6000像素,有1000个物体 . 当用户拖动物体时,画布中的类似结构不可能为我设置动画 . 图 .
在现代显示器上,您还必须考虑到不同的分辨率,这里SVG免费为您提供所有这些 .
小提琴:http://jsfiddle.net/knutsi/PUcr8/16/
全屏:http://jsfiddle.net/knutsi/PUcr8/16/embedded/result/
虽然上面的大多数答案仍有一些道理,但我认为它们值得更新:
多年来,SVG的性能得到了很大改善,现在有 hardware-accelerated CSS transitions and animations for SVG 完全不依赖于JavaScript性能 . 当然,JavaScript性能也得到了提升,Canvas的性能也得到了提升,但没有SVG得到改进的那么多 . 此外,该块上的"new kid"几乎在所有浏览器中都可用,这是 WebGL . 要使用Simon上面使用的相同单词:它是 beats both Canvas and SVG . 这不是一个可以使用的野兽,它只在非常具体的用例中更快 .
对于大多数用例来说,恕我直言,SVG提供了最佳的性能/可用性比率 . 可视化需要非常复杂(关于元素数量)并且同时非常简单(每个元素),因此Canvas甚至更加如此WebGL真正闪耀 .
在this answer to a similar question我提供了更多细节,为什么我认为所有这三种技术中的_163400有时候是你最好的选择 .
答案简短:
SVG对你来说会更容易,因为已经内置了选择和移动它.SVG对象是DOM对象,所以它们有"click"处理程序等 .
DIV很好,但很笨重,而且大量的性能负载很差 .
Canvas具有最佳性能,但您必须自己实现托管状态(对象选择等)的所有概念,或使用库 .
答案很长:
HTML5 Canvas只是位图的绘图表面 . 你设置绘制(用颜色和线条粗细说),绘制那个东西,然后画布不知道那个东西:它不是刚绘制的,它只是像素 . 如果你想绘制矩形并让它们四处移动或者可以选择,那么你必须从头开始编写所有这些代码, including 代码记住你画了它们 .
另一方面,SVG必须维护对它呈现的每个对象的引用 . 您创建的每个SVG / VML元素都是DOM中的真实元素 . 默认情况下,这允许您更好地跟踪您创建的元素,并且默认情况下更容易处理鼠标事件等事情,但是当存在大量对象时,它会显着减慢速度
那些SVG DOM引用意味着处理你绘制的东西的一些步法是为你完成的 . 渲染非常大的对象时SVG速度更快,渲染许多对象时速度更慢 .
Canvas中的游戏可能会更快 . 在SVG中,一个巨大的 Map 程序可能会更快 . 如果你想使用Canvas,我有一些关于使可移动对象运行here的教程 .
Canvas对于更快的事物和繁重的位图操作(如动画)会更好,但如果你想要很多交互性,它会占用更多的代码 .
我在HTML DIV制作的绘图和Canvas制作的绘图上运行了一堆数字 . 我可以发表一篇关于每项优势的重要文章,但我会根据您的具体应用考虑我的测试的一些相关结果:
我制作了Canvas和HTML DIV测试页面,两者都有可移动的“节点” . Canvas节点是我创建的对象,并在Javascript中跟踪 . HTML节点是可移动的Div .
我在两次测试中都添加了100,000个节点 . 他们表现完全不同:
HTML测试选项卡需要永久加载(时间略短于5分钟,chrome要求第一次终止页面) . Chrome的任务经理表示该标签占用了168MB . 当我看着它时占用12-13%的CPU时间,当我不看时它占用0% .
“画布”选项卡在一秒钟内加载,占用30MB . 它总是占用CPU时间的13%,无论是否正在查看它 . (2013年编辑:他们大多修复了)
在HTML页面上拖动更平滑,这是设计所期望的,因为当前设置是在Canvas测试中每30毫秒重绘一次 . Canvas有很多优化可供选择 . (画布失效是最简单的,也是裁剪区域,选择性重绘等等 . 只取决于你实现的感觉)
毫无疑问,你可以让Canvas在对象操作中更快地成为那个简单测试中的div,当然加载时间要快得多 . Canvas中的绘图/加载速度更快,并且具有更多的优化空间(即,排除屏幕外的内容非常容易) .
结论:
SVG可能更适用于项目很少的应用程序和应用程序(少于1000个?真的取决于)
Canvas对于成千上万的对象和谨慎的操作更好,但需要更多的代码(或库)来实现它 .
HTML Divs很笨重而且没有缩放,只有圆角才能形成圆形,使复杂的形状成为可能,但涉及数百个微小的微小像素范围的div . 疯狂随之而来 .
关于divs选项只需2美分 .
Famous / Infamous和SamsaraJS(可能还有其他人)使用绝对定位的非嵌套div(具有非平凡的HTML / CSS内容),结合matrix2d / matrix3d进行定位和2D / 3D转换,并在中等移动硬件上实现稳定的60FPS所以我认为反对div是一个缓慢的选择 .
在Youtube和其他地方有大量的屏幕录制,在浏览器中运行的高性能2D / 3D内容,所有内容都是一个DOM元素,你可以在60FPS上检查元素(与WebGL混合用于某些效果,但不适用于渲染的主要部分) .