This entry is part 6 of 8 in the series Dojo Quick Start Guide

Note: The Dojo Quick Start Guide posts – while still relevant – are a bit dated. Please visit http://dojotoolkit.org/documentation/ for expert tutorials and API documentation to help you get up and running with Dojo.

Dojo has a powerful animation system with several pre-made animations for a lot of common use cases. Adding some visual flair to you projects has never been easier, and typically makes the users experience a lot more interesting.

All animations use a single “magic object” as its only parameter. The most important being the node property, the domNode to apply our animation. Some parameters are optional, and some are for advanced usage. A common setup would look something like:

dojo.ready(function(){ 
     var animArgs = {
          node: "testHeading",
          duration: 1000, // ms to run animation
          delay: 250 // ms to stall before playing
     };
     dojo.fadeOut(animArgs).play();
});

Base Animations:

Animations included in base dojo.js are: fadeIn, fadeOut, and animateProperty. dojo.animateProperty is very powerful, and is the foundation for most advanced animations, and other animations in Dojo Core.

dojo.ready(function(){
     dojo.style("testHeading","opacity","0"); // hide it 
     var anim1 = dojo.fadeOut({ node: "testHeading", duration:700 });
     var anim2 = dojo.animateProperty({
       node: "testHeading", delay: 1000,
       properties:{
	  // fade back in and make text bigger
	  opacity: { end: 1 }, fontSize: { end:19, unit:"pt"}
       }
     }); 
     anim1.play();
     anim2.play();	
});

As seen, dojo.animateProperty will fade the element back in via its opacity property, and simultaneously make the text larger. You can animate most any CSS property this way.

In JavaScript, when modifying multi-word properties such as font-size and border-top, you must use a mixed cased version, as hypens are illegal as keys. Use fontSize and lineHeight, instead of font-size or line-height for example.

Additional FX

Base animations provide extensive visual power, in particular animateProperty. To minimize the size of the base dojo.js, many animations and tools are packaged into the dojo.fx module, optionally added in via dojo.require. Adding the module to your code provides several additional animation methods: dojo.fx.combine, dojo.fx.chain, dojo.fx.wipeIn, dojo.fx.wipeOut and dojo.fx.slideTo.

dojo.require("dojo.fx");
dojo.ready(function(){
     // slide the node to 75,75
     dojo.fx.slideTo({
       node:"testHeading",
       top:75, left:75
     }).play(); // and play it
});

dojo.fx.chain and dojo.fx.combine are very useful, too. They run animations in parallel or in sequence, returning a single instance of dojo._Animation to use:

dojo.require("dojo.fx");
     dojo.ready(function(){
       var anim = dojo.fadeOut({ node: "testHeading" });
       var anim2 = dojo.fadeIn({ node: "testHeading" });
       dojo.fx.chain([anim,anim2]).play();
});

Combining an animation to fade in and out wouldn’t make sense, so let’s fade it out and slide the node simultaneously using

dojo.fx.combine:

dojo.require("dojo.fx");
     dojo.ready(function(){
       var anim = dojo.fadeOut({ node: "testHeading" });
       var anim2 = dojo.fx.slideTo({ node: "testHeading", top:75, left:75 });
       var result = dojo.fx.combine([anim,anim2]);
       result.play();
});

Animation Events

Each dojo.Animation has a series of “events” to tie into for more advanced usage. Going back to the one-stop-event-shop dojo.connect, we can connect to specific actions of the animation, and do other things. The most common are onEnd and beforeBegin:

dojo.ready(function(){
     var anim = dojo.fadeOut({ node: "testHeading" });
     dojo.connect(anim,"onEnd",function(){
       console.log(" the animation is done ");
     });
     dojo.connect(anim,"beforeBegin",function(){
       console.log(" the animation is about to start ");
     });
     anim.play();
});

These events are especially helpful when you want to do things like change some content out while a node is hidden and then fade it back in:

dojo.ready(function(){
     var anim = dojo.fadeOut({ node: "testHeading" });
     dojo.connect(anim,"onEnd",function(){
        dojo.byId("testHeading").innerHTML = "replaced after fade!";
	dojo.fadeIn({ node:"testHeading" }).play();
     });
     anim.play();
});

Conveniently, you can pass the event functions as properties to the animation. Using dojo.connect to setup the functions gives us a lot more power, and are typically safer for advanced uses, but sometimes it’s easier to wrap it all in:

dojo.ready(function(){
     var anim = dojo.fadeOut({
	node: "testHeading",
	onEnd: function(){
	   dojo.byId("testHeading").innerHTML = "replaced ... ";
	   dojo.fadeIn({ node: "testHeading" }).play();
        }
     }).play();
});

The full explanation of events is available at the dojo.Animation API pages.

Note: older versions of Dojo use dojo._Animation prior to its "promotion" as a stable public API in Dojo 1.4.

animateProperty

Probably the most powerful of the base animations, dojo.animateProperty allows us to easily animate multiple CSS properties simultaneously.

Since animateProperty is a dojo._Animation, it uses the same arguments as other animations. With an additional object, we can define properties to style any property of a node, from start to end. Using a unit attribute is optional.

Manipulating our header element to use a new font color, size, and overall opacity is as easy as:

dojo.ready(function(){
     var anim = dojo.animateProperty({
	node:"testHeading",
	duration:700,
	properties: {
	  // javascript css names are camelCase
	  // (not hyphenated)
	  fontSize: { start:12, end:22, unit:"pt" },
	  opacity: { start:1, end:0.5 },
	  color: { start: "#000", end:"#FFE" }
	},
	delay:100 // Note! trailing commas break IE.
     });
     anim.play();
});

dojo.query Animations

Dojo provides another convenient module: dojo.NodeList-fx, which adds additional methods to dojo.query for the available dojox.fx animations. To enable these methods, simply add in the required module:

dojo.require("dojo.NodeList-fx");
     dojo.ready(function(){
       dojo.query("#testHeading").fadeOut().play();
});

The above gives us the same effect as calling dojo.fadeOut directly, but dojo.query here makes an animation for each of of the NodeList elements, and combines them into a single dojo.Animation. This can be useful when you have groups of like nodes you want to easily affect (in this case, all the nodes with class="fadeNode"):

dojo.require("dojo.NodeList-fx");
var fadeThem = function(){
     dojo.query(".fadeNode").fadeOut().play();
}
dojo.ready(function(){
     dojo.connect(dojo.byId("testHeading"),"onclick","fadeThem");
});
Unlike other dojo.query() chains, the NodeList-fx methods return an instance of dojo.Animation, preventing further chaining.