更新的问题 我已将此更新为更简洁..:
在这个小提琴中:http://jsfiddle.net/pX2Xb/4/我有一些raphael代码可以在页面上绘制3000个圆圈。然后,它会尝试在10秒内一次动画所有圆圈(更改填充颜色),这会产生笨重的视觉动画。将圆圈数更改为20以查看更平滑的动画以进行比较。
我的问题是(a)我是否可以更顺利地更新3000个元素;(b)如果是这样,那么代码看起来是什么样的?
一些注意事项:
较旧的详情,如果有帮助
我正在制作一张美国郡的大地图,其中有超过3000个;我正在使用this Wikipedia svg file获取相关的SVG路径来创建地图,并使用RaphaelJs渲染地图。
因此,我最终得到了超过3000条类似于以下内容的陈述:
var cc_02130 = rsr.path("M 140.66674,.... 320.11635"); // county path
cc_02130.attr({id: '02130',.. .."marker-start": 'none'}); // init attrs
我还创建了一个Paper.set()
对象来保存所有这些元素:
var myset = paper.set([cc_56039, cc_56040, cc_56041 ...])
暂时忘记这里实际生成的文件非常大,我非常感谢如何对上面详述的对象卷进行更改的建议,这既快又合理,但是CPU明智的< / em>(可能是一个很大的问题)。
我绝对愿意改变我的代码/对象的结构,只要我可以单独更改特定县的属性。 例如,我希望能够在一两秒内为所有路径内容应用不同的颜色(对于所有3000 +)。
我面临的挑战不是如何应用颜色变化,动画等,而是如何快速有效地完成这项工作。现在,如果我循环并对3000多个对象进行更改,我的机器会对我尖叫;作为一种替代方案,我使用setTimeout
将更改分解为更小的块(可能一次10个,延迟40毫秒)。超过3000项,这变得非常慢,仍然使用大量的CPU。
谢谢, OLI
答案 0 :(得分:10)
我不知道为什么,但D3.js在一次动画大量元素时效率更高。您可以通过创建一个Raphael函数使它们无缝地工作,该函数接收一个集合并返回您想要设置动画的html对象:
Raphael.st.nodes = function() {
var elements = [];
this.forEach(function (i) {
elements.push(i.node);
});
return elements;
}
然后你让d3从那里拿走它
//circleholder is a Raphael set
elements = circleholder.nodes()
d3.selectAll(elements)
.transition()
.attr("fill", function(d,i){return colours[randomNum(14)]})
.duration(ANIMATION_DELAY)
这是jsfiddle:http://jsfiddle.net/mFecs/
答案 1 :(得分:0)
由于我目前不熟悉Rapael.js,我只是建议您以通用的JavaScript方式创建一个changeRaphaelPathAttributeEvent,每当您想要更改路径,属性更改为所述事件的参数。然后将事件处理程序附加到执行属性更改的每个路径(如果可能的话)。
这样,您就可以解决循环访问所有路径变量并同步更改属性的问题(这会直接影响页面在处理时的响应性);该方法对用户体验的性能影响较小。
注意:这只是解决即时性能问题的解决方案。也许有其他解决方案可以最大限度地减少访问所需的对象数量,你也应该考虑(而且我无法告诉你,因为我不太了解拉斐尔)。
答案 2 :(得分:0)
您是否手动编写了所有路径?如果你将所有路径都放在一个对象中,我认为会更好。然后,您可以使用例如for in
迭代对象并绘制所有路径。在该过程中,您可以使用element.id = 'name'
为每个路径提供内部ID。一旦你拥有了所有的内部ID和绘制的路径,就可以使用getById方法:getById('pathId')
如果你打算使用集合,我建议你使用Clousures,你可以先声明变量
var setName = Paper.Set()
然后在另一个循环中推送路径
for (countie in Lousiana){
setName.push(countie)
}
如果要将某些属性应用于元素,则可以使用Paper.forEach()
之类的方法。或Set.FotEach()
。两者都采用类似参数的回调函数,然后在每次迭代中执行该函数。
如果你想分享你的代码,那么对我来说检查它并就如何解决某些情况提出意见并不成问题。我也在使用地图,我正在开发一个教育视频游戏,如果你想我也可以与你分享我的代码,没有那么多关于Raphael的文档,所以对我来说看看它是如何有用的你使用它,也许对你来说也一样。
再见!
答案 3 :(得分:-1)
老实说,任何计算机都应该很容易更改3000个项目的属性。 Raphael对每个动画元素使用setInterval。更改元素的属性后,浏览器将重新绘制整个页面。这是2999次必要的重新抽奖。
以下是我要做的事情:使用循环来改变每个元素,而不是使用Raphael动画。它有点复杂,但速度更快。此外,您可以更改每秒的步数。如果动画运行速度太慢,只需减少每秒的步数。
以下是一个示例:http://jsfiddle.net/dqJps/25/
希望这有帮助。