Staggering Animations
by Peter Higgins

There is a little technique I use just about any time I animate more than one node at a time that gives the overall animation a lot more fluidity, and I’d like briefly to share it with you. Quickest Cookie. Ever. Its really easy:

dojo._Animation allows you to pass a delay: parameter to the constructor. Its that easy.

dojo.fadeOut({ node:"foobar", duration:200, delay:200 }).play();

The above animation will last roughly 400ms.

var a = dojo.fadeOut({ node: "foo", delay:400, duration:500 });
var b = dojo.fadeOut({ node: "bar", delay:800, duration:500 });
var c = dojo.fx.combine([a,b]).play();

This will last about 1300ms. After 400ms “foo” will begin to fade out, and 400ms later (100ms before “foo” is gone) “bar” will begin fading out. The combined animation (c) has it’s own events:

dojo.connect(a,"onEnd",function(){ /* "a" fadeout done */ });
dojo.connect(c,"onEnd",function(){  /* all done */ });

Though we don’t always know the nodes or the Id’s or nodes right off the bat. Using dojo.query, we can really easily apply these FX to series of nodes. Consider the markup:

<ul id="foobar">
     <li>Item 1</li>
     <li>Item 2</li>
     <li>Item 3</li>
</ul>

We can run a few lines of code and fade each of them out. Doing it all at once is fine:

dojo.query("#foobar li").fadeOut({ duration:300 }).play();

But we’re adding delays in here, so we’ll use query.forEach, and do some variable setup:

var delay = 100; // initial delay
var inc = 150; // the ms to stagger the next animation
var anims = []; // our array of animations to pass to combine()
dojo.query("#foobar li").forEach(function(li){
     anims.push(dojo.fadeOut({
          node: li, delay: parseInt(delay), duration:500
     }));
     delay += inc; // step 
});
dojo.fx.combine(anims).play();

Each of the animations will play about 150ms after the previous, but will be cached and created in the combine() call.

Don’t forget: to use dojo.fx (which provides combine(), chain() and other animation constructors) you must issue the appropriate require() call:

dojo.require("dojo.fx");
dojo.addOnLoad(function(){ 
     dojo.fx.slideTo({ node: "foo", top:50, left:50 }).play();
});

That’s all there is to it …

Checkout what this does:

dojo.require("dojo.fx");
dojo.require("dijit.form.Button");
var demoDoit = function(){
     var int = 175;
     var delay = 300;
     var anims = [];
     dojo.query(".entry p").reverse()
           .forEach(function(n){
               anims.push(dojo.fadeOut({ node:n, delay: parseInt(delay), duration:420 }));
               delay += int; 
     }).reverse().forEach(function(n){
           delay += int;
           anims.push(dojo.animateProperty({ 
               node:n, 
               delay: parseInt(delay), 
               duration:500, properties: { height:1 }  
            }));
     });
    dojo.fx.combine(anims).play();
};

Tags: ,

This entry was posted on Friday, April 11th, 2008 at 4:58 pm and is filed under Dojo Cookies. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

You must be logged in to post a comment.