3

See JSfiddle!

I am wanting to animate a set of elements and execute a callback when finished like so:

s.selectAll('.active').animate( {
        transform: matrix 
    },
    300,
    mina.linear,
    function() {
       //callback doesnt fire
       alert('callback')
    }
)

The elements are animated correctly but the callback isnt executed.

However, when I apply the animation to a group of elements, the callback is fired:

group.animate( {
        transform: matrix 
    },
    300,
    mina.linear,
    function() {
       alert('callback')
    }
)

.. But I don't want to put my selected elements in a group as this would cause more complications in other places.

Is it possible to animate a set of elements that I got via a .select() or .selectAll() while being able to fire the callback?

Thanks a lot in advance!

Edit: For future readers, you can animate a set of elements by using forEach and counting if all elements are done animating:

function hideToPoint(elements, x, y, callback) {
    var finished = 0;
    elements.forEach(function(e) {

        e.animate( {
                //do stuff
            },
            300,
            mina.linear,
            function () {
                finished++;
                if (finished == elements.length) {
                    callback();
                }
            }
        )
    })
}
ngmir
  • 450
  • 6
  • 26
  • Try and put it on a fiddle if possible. Does the animation run, anything in console log ? – Ian Jun 24 '14 at 09:47
  • Yes, the animation does run, console.log is clear. The callback parameter is passed correctly when i log it in hideToPoint(). – ngmir Jun 24 '14 at 09:56
  • Putting together a fiddle will take a bit of time since this is part of a larger thing, I will edit the post when I got to do it. – ngmir Jun 24 '14 at 09:56
  • See this to create your example: http://stackoverflow.com/help/mcve – edi9999 Jun 24 '14 at 10:14
  • I rephrased the question with clearer examples and some new insights. – ngmir Jun 24 '14 at 11:36

1 Answers1

3

I'm going to have a stab at answering a couple of problems, even though I'm not sure if related to the callback. Its hard to tell if its just the example code or not without a proper test like a jsfiddle.

However, there are at least 2 problems in the code above.

Creating a matrix is with

new Snap.Matrix();   // as opposed to Snap.matrix()

Also

elements.animate()

The problem here is that animate acts on one element (edit: looks like it can work on elements within a set, but not the callback as example here, edit2: callbacks on sets may now be supported), not multiple elements as such (you can sometimes apply somethings to a set which deals with them individually, but as far as I'm aware, thats not the case with animate).

So you either want to do a

elements.forEach( function(el) { el.animate({blah: value}, 2000, mina.linear.callback ) 
});

or if its an svg group (as opposed to a set), the original code would possibly work (but I would call it 'myGroup' or something instead of 'elements' for code readability and guessing what it contains)

fiddle (have included a different animation using snap animation string)

Ian
  • 13,724
  • 4
  • 52
  • 75
  • thanks a lot for the answer. looks like you typed it just as I was rephrasing the question. – ngmir Jun 24 '14 at 11:36
  • looks like this solved my problem: you can animate a group but not a set. thanks a lot. – ngmir Jun 24 '14 at 11:49
  • 1
    @lan If the callback is not working, why `set.animate` still provides the callback param? – merlin Aug 01 '14 at 03:17
  • @lan When using `set.animate`, the elements are animated correctly but the callback isn't executed. – merlin Aug 02 '14 at 01:49
  • 1
    Not sure actually, I was a bit surprised animate works on a set in fact. If you think it should work ok with a callback, I would be tempted to raise an issue on snaps github. Otherwise I would use a group if possible. – Ian Aug 02 '14 at 11:00