jquery sequential animation

rick picture rick · Jul 3, 2011 · Viewed 7.4k times · Source

i'm trying to replicate this animation

http://tympanus.net/Tutorials/AnimatedContentMenu/

i'm not able to animate the menu items, than sliding up sequentially

    $('#bar').animate(
    {width: '100%'},
    {duration: 500,
    specialEasing: {width: 'linear'},
    complete: function() {
        $('li').each( function() {
                $(this).animate(
                    {top:'0px'},
                    {queue: true, duration: 200, specialEasing: {top: 'easeOutBack'},
                }); 
        });
    }
});

In this way the menu items are animated simultaneously.....what's wrong?

Answer

Nick Craver picture Nick Craver · Jul 3, 2011

Since the queue is per element, nothing is actually queueing here, that's why they're all animating at once. There are a few ways to do this though. One simple way to do this with a small number of items is with .delay(), like this:

$('#bar').animate(
    {width: '100%'},
    {duration: 500,
    specialEasing: {width: 'linear'},
    complete: function() {
        $('li').each(function(i) {
            $(this).delay(i*200).animate(
                {top:'0px'},
                {queue: true, duration: 200, specialEasing: {top: 'easeOutBack'},
            }); 
        });
    }
});

You can test a demo out here.

What this does is delay the animation 200ms * the index of the element in the .each() iteration, so the first animations is instant, the second 200ms later, the next 200ms after that, etc. The reason I recommend this is you don't have to use 200ms for the delay, you can use a smaller number and have the animations overlap a bit, which seems to be the effect you're after.

Another way to do this (more verbose, sequential only, and allows no overlap) is to use .queue() to build your own, for example:

$('#bar').animate(
    {width: '100%'},
    {duration: 500,
    specialEasing: {width: 'linear'},
    complete: function() {
        $('li').each(function() {
            $(document).queue(function(n) {
              $(this).animate(
                {top:'0px'},
                {queue: true, duration: 200, specialEasing: {top: 'easeOutBack'},
                complete: n //call the next item in the queue             
              }); 
            });
        });
    }
});

You can test that version out here.