动态创建元素并能够移动它们的最佳方法是什么?例如,假设我想创建一个矩形、圆和多边形,然后选择这些对象并移动它们。
我知道HTML5提供了三个元素,可以使这成为可能:svg, canvas和div。对于我想做的事情,这些元素中哪一个将提供最佳性能?
为了比较这些方法,我想创建三个视觉上相同的网页,每个网页都有一个页眉、页脚、小部件和文本内容。第一个页面中的小部件将完全使用canvas元素创建,第二个页面完全使用svg元素创建,第三个页面使用普通div元素、HTML和CSS创建。
动态创建元素并能够移动它们的最佳方法是什么?例如,假设我想创建一个矩形、圆和多边形,然后选择这些对象并移动它们。
我知道HTML5提供了三个元素,可以使这成为可能:svg, canvas和div。对于我想做的事情,这些元素中哪一个将提供最佳性能?
为了比较这些方法,我想创建三个视觉上相同的网页,每个网页都有一个页眉、页脚、小部件和文本内容。第一个页面中的小部件将完全使用canvas元素创建,第二个页面完全使用svg元素创建,第三个页面使用普通div元素、HTML和CSS创建。
当前回答
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.
其他回答
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.
为了补充这一点,我一直在做一个图表应用程序,最初是从画布开始的。该图由许多节点组成,而且它们可以变得相当大。用户可以在图中拖动元素。
我发现,在我的Mac上,对于非常大的图像,SVG更好。我有一台MacBook Pro 2013 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);
我同意Simon Sarris的结论:
我比较了Protovis (SVG)和Processingjs (Canvas)中的一些可视化,后者显示> 2000点,Processingjs比Protovis快得多。
使用SVG处理事件当然要容易得多,因为您可以将它们附加到对象上。在Canvas中,你必须手动操作(检查鼠标位置等),但对于简单的交互来说,这应该不难。
还有道场。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/
虽然上面的大多数答案仍然有一定的道理,但我认为它们值得更新:
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才能真正发挥作用。
在这个类似问题的答案中,我提供了更多的细节,为什么我认为这三种技术的组合有时是最好的选择。
只是我对divs选项的意见。
《Famous/Infamous》和《samyazare》(可能还有其他游戏)使用绝对定位的非嵌套divs(带有非繁琐的HTML/CSS内容),结合matrix2d/matrix3d进行定位和2D/3D转换,并在中等移动硬件上实现了稳定的60FPS,所以我不认为divs是一个缓慢的选择。
Youtube和其他地方有大量的屏幕记录,高性能的2D/3D东西运行在浏览器中,所有东西都是一个DOM元素,你可以在上面检查元素,60FPS(混合WebGL用于某些效果,但不适用于渲染的主要部分)。