1

I am using Snap.svg and I have the following code:

http://jsfiddle.net/vdfu010q/8/

Which creates 7 black rectangles. I have a function (rectAnim) which animates the rectangles. I need them to animate in different timings, so I created that setInterval method to delay their animation, but it is not working.

If you remove it and leave only the function call, you'll see the animation running, but the setInterval seems to break it all.

What am I doing wrong? How can I make each rectangle animate with different timings?

var s = Snap('#stuff');

function rectAnim(tgt){
    tgt.animate({
        width: 100,
        x: 50
    }, 1000, mina.easeinout, function(){
        tgt.animate({
            width: 200,
            x: 0
        }, 1000, mina.easeinout, function(){
            tgt.animate({
                width: 100,
                x: 50
            }, 1000, mina.easeinout, rectAnim(tgt));
        });
    });
}

for(var i = 0; i < 7; i++){
    var obj = s.rect(0, 41 * i, 200, 40);

    obj.node.setAttribute('id', 'strap' + i);

    setInterval(function(){
        rectAnim(obj);
    }, 200 * i);
}
Ian
  • 13,724
  • 4
  • 52
  • 75
gespinha
  • 7,968
  • 16
  • 57
  • 91

1 Answers1

1

The problem is your scope of the 'obj' element at the end. When you run it in the loop, it will get overwritten when the function actually runs.

To get around this, you need to create some form of closure. Here is one way you could do it.

for(var i = 0; i < 7; i++){
    var obj = s.rect(0, 41 * i, 200, 40);

    obj.node.setAttribute('id', 'strap' + i);
    (function( myobj ) {
       setTimeout(function(){
          rectAnim(myobj);
       }, 200 * i);
    })( obj )
}

jsfiddle

I also adjusted the callback to use setTimeout, as it should run fine as it is with the existing callbacks in the animation, you may want to change this back if not as intended.

Ian
  • 13,724
  • 4
  • 52
  • 75
  • Great! Thanks :) What do you call that type of enclosure? So I can look for some documentation on that. – gespinha Dec 14 '15 at 19:17
  • its just a 'closure' in general, maybe worth a read through https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures main thing to remember is that javascript has functional scope unlike some other languages. So when you something makes a callback, you need to think about what that variable will be later in that scope. SO question on them here.. http://stackoverflow.com/questions/111102/how-do-javascript-closures-work – Ian Dec 14 '15 at 19:22
  • Ok, Thanks, I will definitely look into that! – gespinha Dec 14 '15 at 19:24
  • Actually, you could probably call the way I used that function, as an immediate invocation function call, (function() {} )() and worth knowing, but there's different ways to create a closure, so worth reading at least the main answers in that SO question. – Ian Dec 14 '15 at 19:28