2
\$\begingroup\$

I have a snap SVG animation which animates a bunch of circles, and draws a line between them if they are within a certain proximity of each other. However, I realize that there is a lot of optimizing I can do, but I'm not exactly sure how to do it. I feel like it would be useful to

  1. have a good example of proximity detection in snap
  2. have some more information on optimizing animations in snap SVG. It hasn't been easy to find.

Here is a working example of the animation:

and here are the things I believe can be optimized:


Each circle calls its own animation function - the circles have all been added to a group, and I'm guessing there is a way to apply random motion to all members of a group that is more performant than call a function for each and every element within the group.

for (var i=0; i<this.drawingConfig.circles.amount;i++){
  ...
  this.animateSingle(circleShape);
}

The proximity function is awkward - for each circle, for each update cycle, I have to loop through an array of all the other circles and find out if the X and Y coordinates are close enough to draw a line to. Plus, that means you're getting duplicate lines, because each circle will draw a line to its neighbors, instead of having a single shared line between the two.

for (var i=0;i<circles.length;i++){
  var nextCircle = circles[i].node;
  var nextCircleX = nextCircle.cx.baseVal.value;
  var distance = Math.abs(nextCircleX-thisCircleX);
  var proximity = mainModule.drawingConfig.circles.proximity;
  if (distance < proximity){

    var nextCircleY = nextCircle.cy.baseVal.value;
    var thisCircleY = shape.node.cy.baseVal.value;
    var distanceY = Math.abs(nextCircleY - thisCircleY);
    if (distanceY < proximity){

      var line = mainModule.s.line(thisCircleX, thisCircleY, nextCircleX, nextCircleY).attr({stroke: '#a6a8ab', strokeWidth: '1px'});
      mainModule.drawingConfig.circles.circleGroup.add(line);
    }
  }
}

Correspondingly, I each circle's animation function clears all the lines on the screen. Ideally all the circles would be sharing one update function, and in that function, you'd clear the lines.

Snap.animate(startX, animX, function (val) {

  var lines = Snap.selectAll('line');
  lines.remove();

  ...

}, mainModule.drawingConfig.circles.animTime);

Right now, I can tell the renderer can't keep up with all of the various animations / loops. Any help optimizing the above things (or anything else you can see that I'm doing weird, would be greatly appreciated.

\$\endgroup\$
  • \$\begingroup\$ Am now running everything in a single loop - not using snap's animation function at all; check this. \$\endgroup\$ – mheavers Jun 5 '14 at 17:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.