我正在处理涉及大量小元素的大型SVG粒子动画。有时高达1000.当我为这么多元素设置动画时,浏览器似乎很难,所以我正在寻找优化代码的方法,以获得更好,更平滑的性能(尤其是Firefix)。
我的主要问题是,例如,将元素的stroke
属性设置为属性,还是设置为样式之间是否存在任何差异:
<circle r="0.15" cx="84" cy="782" stroke-width="6" stroke="transparent" style="fill: #ffffff;"></circle>
VS
<circle r="0.15" cx="84" cy="782" stroke-width="6" stroke="transparent" style="stroke:transparent; stroke-width:6; fill: #ffffff;"></circle>
我正在使用D3.js添加一堆这些并使它们四处移动......在Chrome中的事情变得笨拙之前,1000似乎大致是极限。 Firefox更糟糕。
如果您有任何其他表现建议,也欢迎他们。
更新 根据要求:
以下是我创建节点的方法:
var makeNode = function(coeficient, x, y) {
coeficient = coeficient || 1;
return {
radius: (Math.random() * coeficient ).toFixed(2),
cx: function() { return x || Math.round(Math.random()*width) },
cy: function() { return y || Math.round(Math.random()*height) }
}
};
var nodes1 = d3.range(300).map( function(){ return makeNode(1.9); } );
var nodes2 = d3.range(700).map( function(){ return makeNode(.6); } );
// var nodes2 = [];
var svg = d3.select('#sky_svg');
var group1 = svg.append('g').attr("class", "group1");
var group2 = svg.append('g').attr("class", "group2");
var addNodes = function(group, nodes) {
for (var i=0; i<nodes.length; i++){
var node = nodes[i];
var circle = group.append('circle');
circle
.attr("r", node.radius )
.attr("cx", node.cx )
.attr("cy", node.cy )
.attr("stroke-width", 8 )
.attr("stroke", "transparent")
.style("fill", "#FFFFFF");
}
}
addNodes( group1, nodes1 );
addNodes( group2, nodes2 );
这就是他给我们制作动画的方式:
function orbit( target, ease, duration ) {
/* Other easing options here: https://github.com/mbostock/d3/wiki/Transitions#wiki-d3_ease */
ease = ease || 'linear';
duration = duration || 40000;
target
.transition()
.duration( duration )
.ease( ease )
.attrTween("transform", rotTween)
.each('end', function(){ orbit( group1, false ); } );
function rotTween() {
var i = d3.interpolate(0, 360);
return function(t) {
return "rotate(" + i(t) + ","+width/2+","+height/2+")";
};
}
}
orbit( group1, 'sin-in', orbitSpeed );
orbit( group2, 'sin-in', orbitSpeed*2.5 );
我并没有特别嫁给这个实现。我的原始设计使用了力布局,但Firefox挣扎真的难以加载它然后它运行得非常糟糕所以我重构了代码以使用简单的旋转(在FF中几乎可以顺利运行)。
答案 0 :(得分:-1)
圈子的cx,cy,r为baseVal
。有人建议通过baseVal
访问这些属性。使用setAttribute
或attr
(在d3中)更有效。
e.g。
myCircle.cx.baseVal.value=myCx
myCircle.cy.baseVal.value=myCy
myCircle.r.baseVal.value=myR