Scalability Problems Animate A Large Number Of Objects
Posted by integragreg apropos on Sat Feb 10th, 2007 at 22:06:04 BST
Initially, we targeted the ASV3 plug-in with IE using SMIL animation with the animateTransform element. We found that as the number of turbines on a diagram increased, so did the frequency of IE crashes and unexpected graphical behaviors. As an alternative, we began using JavaScript to simulate the animation. We thought this might provide better scalability for IE as well as allowing us to achieve animation in Firefox, since Firefox still has no support for SMIL animation.
Unfortunately, our trek down the JavaScript road hasn't yielded much better results. First, we tried simply writing our own JS function that would modify the <transform> tag attributes on a specified time interval using setTimeout(). This worked well for a small number of animated elements, but as the number increased, the animation became very choppy didn't look much better than an animated GIF. Also, the rotation in Firefox is very slow, and doesn't work at all in Opera.
Later, we came across Doug Schepers' <a href='http://www.vectoreal.com/smilscript/'>SMILScript</a> library. SMILScript allows Firefox to support SMIL animation by using JavaScript to provide declarative animation. Since SMILScript also uses a JavaScript setTimeout() function, the results were basically the same as when we used our own JavaScript functions.
The SVG markup included below renders an array of graphical elements that is generated and animated by a couple of JavaScript functions. Increasing the upper bounds on the For loops in the InitMe() function will illustrate the performance degradation mentioned earlier.
At this point we are still searching for a viable solution that meets our performance specification. Perhaps SVG is not a good choice for animating a large number of elements simultaneously. If anyone would like to look at the file and suggest an alternative, we'd love to hear from you.
---
<?xml version="1.0" encoding="utf-8"?>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="1200"
height="1200"
id="TurbineMapScratchPad"
version="1.0"
onload="InitMe(evt);"
>
<script type="text/ecmascript" >
<![CDATA[
var svgDocument = null;
var svgRoot = null;
var bladeRotation=0;
var svgns = "http://www.w3.org/2000/svg";
var xlinkns = "http://www.w3.org/1999/xlink";
function InitMe(evt)
{
if ( svgDocument === null )
{svgDocument = evt.target.ownerDocument;}
svgRoot = svgDocument.documentElement;
for(var y=10; y<600; y+=70)
{
for(var x=20; x<720; x+=40)
{
var gNode = svgDocument.createElementNS(svgns,"g");
var bladeUse = svgDocument.createElementNS(svgns,"use");
var baseUse = svgDocument.createElementNS(svgns,"use");
gNode.setAttributeNS(null,'transform','translate(' + x + ',' + y + ') scale(4.0)');
bladeUse.setAttributeNS(xlinkns,'href','#turbineBlades');
baseUse.setAttributeNS(xlinkns,'href','#turbineBase');
gNode.appendChild(bladeUse);
gNode.appendChild(baseUse);
svgRoot.appendChild(gNode);
}
}
setInterval('animateTurbineBlades()',10);
}
function animateTurbineBlades()
{
var hubX=0;
var hubY=0;
var hubNode = svgDocument.getElementById('bladeHub');
if(hubNode)
{
hubX=parseFloat(hubNode.getAttributeNS(null,"cx"));
hubY=parseFloat(hubNode.getAttributeNS(null,"cy"));
}
var node = svgDocument.getElementById('turbineBlades');
if(node)
{
bladeRotation = bladeRotation + 2;
if(bladeRotation > 360)
{
bladeRotation=0;
}
node.setAttributeNS(null,'transform','rotate(' + bladeRotation + ',' + hubX + ',' + hubY + ')');
}
}
//]]>
</script>
<defs>
<g id="turbineBlades">
<path
d="
M 6.7203394,6.9568743
C 5.5101085,10.802047 5.5101085,10.802047 5.5101085,10.802047
L 5.1509285,12.769531
L 5.1509285,12.769531
L 7.2122104,7.0466693"
style="fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:.100000048px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
<path
d="
M 7.5184653,6.8204787
C 11.453598,5.945983 11.453598,5.945983 11.453598,5.945983
L 13.337079,5.2733
L 13.337079,5.2733
L 7.3502946,6.3496084"
style="fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:.100000048px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
<path
d="
M 7.0542563,6.2458097
C 4.3293545,3.2751324 4.3293545,3.2751324 4.3293545,3.2751324
L 2.8050536,1.9803314
L 2.8050536,1.9803314
L 6.7305561,6.626885"
style="fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:.100000048px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
/>
<circle id="bladeHub" cx="7.1" cy="6.6" r="0.5" style="fill:black" />
</g>
<g id="turbineBase">
<path
d="
M 6.8684577,7.1257859
C 6.8684577,11.288829 6.8684577,11.288829 6.8684577,11.288829
L 7.3010127,11.288829
L 7.3010127,7.1257859
L 6.8684577,7.1257859
L 6.8684577,7.1257859"
style="fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:0.40460387px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="baseUpperNew" />
<path
d="
M 6.5893374,11.295157
C 6.5893374,18.210662 6.5893374,18.210662 6.5893374,18.210662
L 7.5738901,18.210662
L 7.5738901,11.295157
L 6.5893374,11.295157
L 6.5893374,11.295157"
style="fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:0.78674704px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="baseLowerNew" />
</g>
</defs>
</svg>
- Create an account
- About SVG.org
- Frequently Asked Questions
- SVG.org Content with RSS

- Get SVG Help on IRC
- SVG.Open Conferences
- SVG Phones (169 and counting)
- JSR 226 Phones (28 and counting)
