Core fx

The content of this chapter up to this point has concentrated entirely on the animation facilities that are provided by Base. The existing functionality in Base consisting of fadeIn, fadeOut, and animateProperty covers a tremendous amount of use cases; however, there are a few additional functions provided in Core's fx module that you can get for the cost of one additional dojo.require statement. These facilities for effects include functions for sliding nodes and wiping nodes in and out, as well as chaining, combining, and toggling animations.

Sliding

Sliding nodes is just as easy as fading them. You pass a hash containing configuration parameters to the dojo.fx.slideTo function just like you would with animateProperty. Table 8-5 summarizes.

Table 8-5. Parameters for Core's slide functions

Parameter

Type

Comment

node

DOM Node

The node that will be sliding.

duration

Integer

How many milliseconds the fade should last. Default value is 350.

easing

Function

A function that adjusts the acceleration and/or deceleration of the progress across a curve. Default value is (0.5 + ((Math.sin((n + 1.5) * Math.PI))/2).

Note that the easing function is only defined from a domain of 0 to 1 for the fadeIn and fadeOut.

left

Integer

Where the node's left corner should be at the end of the slide.

top

Integer

Where the node's top corner should be at the end of the slide.

Example 8-3 illustrates the sliding functions. The only portions of the page that are any different from the previous fade examples are emphasized.

Example 8-3. Sliding a node

<html>
    <head>
        <title>Animation Station</title>
        <style type="text/css">
            @import "http://o.aolcdn.com/dojo/1.1/dojo/resources/dojo.css";
            .box {
                width : 200px;
                height : 200px;
                margin : 5px;
                background : blue;
                text-align : center;
            }
        </style>
        <script
            type="text/javascript"
            src="http://o.aolcdn.com/dojo/1.1/dojo/dojo.xd.js">
        </script>
        <script type="text/javascript">

            dojo.require("dojo.fx");

            dojo.addOnLoad(function(  ) {
                var box = dojo.byId("box");
                dojo.connect(box, "onclick", function(evt) {
                    dojo.fx.slideTo({

                        node:box,

                        top : "200",

                        left : "200"

                    }).play(  );
                });
            });
        </script>
    </head>
    <body>
        <div id="box" class="box">Slide Me</div>
   </body>
</html>

Wiping

Slides and fades are a lot of fun, but wipes are frequently used and have wonderful utility as well. The basic approach to using them should be no surprise by now. Most of the same arguments apply. Table 8-6 provides a synopsis.

Table 8-6. Parameters for Core's wipe functions

Parameter

Type

Comment

node

DOM Node

The node that will be wiped.

duration

Integer

How many milliseconds the fade should last. Default value is 350.

easing

Function

A function that adjusts the acceleration and/or deceleration of the progress across a curve. Default value is (0.5 + ((Math.sin((n + 1.5) * Math.PI))/2).

Note that the easing function is only defined from a domain of 0 to 1 for the fadeIn and fadeOut.

Warning

Be advised that in some layouts, border, margin, and padding values associated with nodes have been known to affect the layout once wipe animations have completed.

Following suit with the other examples in this chapter, Example 8-4 can get you started.

Example 8-4. Wiping a node

<html>
    <head>
        <title>Animation Station</title>
        <style type="text/css">
            @import "http://o.aolcdn.com/dojo/1.1/dojo/resources/dojo.css";
            .box {
                width : 200px;
                height : 200px;
                text-align : center;
                float : left;
                position : absolute;
                margin : 5px;
            }
        </style>
        <script
            type="text/javascript"
            src="http://o.aolcdn.com/dojo/1.1/dojo/dojo.xd.js">
        </script>
        <script type="text/javascript">
            dojo.require("dojo.fx");

            dojo.addOnLoad(function(  ) {
                var box = dojo.byId("box");
                dojo.connect(box, "onclick", function(evt) {
                    dojo.fx.wipeOut({
                        node:box
                    }).play(  );
                });
            });
        </script>
    </head>
    <body>
        <div class="box">Now you don't</div>
        <div id="box" style="background : blue" class="box">Now you see me...</div>
   </body>
</html>

You may also find it especially interesting to experiment with custom easing functions for wipes. Try our custom, nonmonotonic easing function from earlier and note the interesting bouncy effect with the following addOnLoad change:

dojo.addOnLoad(function(  ) {
    var box = dojo.byId("box");
    dojo.connect(box, "onclick", function(evt) {
        dojo.fx.wipeOut({
            node:box,
            easing : function(x) { return Math.pow(Math.sin(4*x),2);   },
            duration : 5000
        }).play(  );
    });
});

Because the easing function increases, decreases, then decreases again, the internal _Animation that wipeOut uses scales the height of the node accordingly.

Chaining and Combining

There's something that's quite remarkable about watching an object slide, fade, and wipe around the screen, but that's not all you can do: you can use another function in Core fx, dojo.fx.chain, to chain together animations. This function is incredibly simple in that its only argument is an Array of _Animation objects and it returns another _Animation for you to play. Let's use it to make the box do something a little more fancy. Table 8-7 lists the functions for combining and chaining.

Warning

As of Dojo version 1.1, the animation functions chain and combine in this section have several known issues relating to how events such as beforeBegin and onEnd are processed when multiple animations are rolled up. The basic gist is that if you are trying to rely on these events for specific hooks in your application's logic, you might be better off using functions like dojo.connect and dojo.subscribe to rig up your own chains and combinations. Of course, for less advanced tasks, chain and combine work fine.

Table 8-7. Animation combination and chaining

Function

Comment

dojo.fx.chain(/* Array */ animations)

Chains together the animations enclosed in the array that is passed in as a parameter and returns a consolidated animation that you can play as usual. The resulting animation is the sequential result of playing each animation back to back.

dojo.fx.combine(/* Array */ animations)

Combines the animations enclosed in the array that is passed in as a parameter and returns a consolidated animation that you can play as usual. The resulting animation provides the effect of playing each of the original animations in parallel.

Example 8-5 demonstrates a box that makes a zigzag pattern across the screen. Note that you define custom easing function and other parameters just as normal.

Example 8-5. Chaining animations together

dojo.addOnLoad(function(  ) {
    var box = dojo.byId("box");
    dojo.connect(box, "onclick", function(evt) {
        var easing = function(x) { return x; };
        var a1 = dojo.fx.slideTo({
            node:box,
            easing : easing,
            duration : 1000,
            top : "150",
            left : "300"
        });
        var a2 = dojo.fx.slideTo({
            node:box,
            easing : easing,
            duration : 400,
            top : "20",
            left : "350"
        });
        var a3 = dojo.fx.slideTo({
            node:box,
            easing : easing,
            duration : 800,
            top : "350",
            left : "400"
        });
        dojo.fx.chain([a1,a2,a3]).play(  );
    });
});

But say you want to fade and slide at the same time. No problem. Following the same type API call as dojo.fx.chain, the dojo.fx.combine will do it in a jiffy. Any animations you pass into it through the Array parameter are run in parallel. First, let's look at a simple combination of our slide and fade examples. Example 8-6 shows the relevant change to addOnLoad.

Example 8-6. Combining animations

dojo.addOnLoad(function(  ) {
    var box = dojo.byId("box");
    dojo.connect(box, "onclick", function(evt) {
        var a1 = dojo.fx.slideTo({
            node:box,
            top : "150",
            left : "300"
        });
        var a2 = dojo.fadeOut({
            node:box
        });
        dojo.fx.combine([a1,a2]).play(  );
    });
});

Warning

It's easy to forget that slideTo is in dojo.fx while fadeIn and fadeOut are in Base, so take a moment to acknowledge that a call like dojo.fx.fadeIn would give you an error. If you do not issue a dojo.require("dojo.fx") before attempting to use anything in dojo.fx, you'll get an error.

Given that chain returns a single _Animation, let's try something more advanced (but still really simple) because it builds on the same fundamentals: in Example 8-7, we'll chain together several fade animations and combine them with several slide animations that we'll also chain together.

Example 8-7. Chaining and combining animations

dojo.addOnLoad(function(  ) {
    var box = dojo.byId("box");
    dojo.connect(box, "onclick", function(evt) {

        //chain together some slides
        var a1 = dojo.fx.slideTo({
            node:box,
            top : "150",
            left : "300"
        });
        var a2 = dojo.fx.slideTo({
            node:box,
            top : "20",
            left : "350"
        });
        var a3 = dojo.fx.slideTo({
            node:box,
            top : "350",
            left : "400"
        });
        var slides = dojo.fx.chain([a1,a2,a3]);

        //chain together some fades
        var a1 = dojo.fadeIn({
            node:box
        });
        var a2 = dojo.fadeOut({
            node:box
        });
        var a3 = dojo.fadeIn({
            node:box
        });
        var fades = dojo.fx.chain([a1,a2, a3]);

        //now combine the two chains together
        dojo.fx.combine([slides, fades]).play(  );

    });
});

Toggling

The dojo.fx.Toggler class is essentially a wrapper for configuring the animations for toggling (showing and hiding) a node. The class constructor accepts an associative array of parameters that include the show and hide functions as well as the durations for the show and hide functions. Toggler is nice in that there is very little thinking involved about what has to happen. You simply tell it what functions to use, provide the durations, and then manually call its show and hide function accordingly. Both the show and hide function optionally accept a parameter that delays the operation by a said amount of time (Table 8-8).

Table 8-8. Parameters for Core's Toggler function

Parameter

Type

Comment

node

DOM Node

The node to toggle.

showFunc

Function

A function that returns an _Animation for showing the node. Default value is dojo.fadeIn.

hideFunc

Function

A function that returns an _Animation for hiding the node. Default value is dojo.fadeOut.

showDuration

Integer

The duration in milliseconds to run showFunc. Default value is 200 (milliseconds).

hideDuration

Integer

The duration in milliseconds to run hideFunc. Default value is 200 (milliseconds).

Table 8-9 provides the method summary for the class.

Table 8-9. Toggler functions

Method

Comment

show(/*Integer*/delay)

Shows a node over a duration defined by showDuration using showFunc. The optional delay parameter causes the animation to wait by the specified amount before starting.

hide(/*Integer*/delay)

Hides a node over a duration defined by hideDuration using hideFunc. The optional delay parameter causes the animation to wait by the specified amount before starting.

Example 8-8 provides the compulsory source code and another modification to addOnLoad for our working example from Example 8-4.

Example 8-8. Toggling a node

dojo.addOnLoad(function(  ) {
    var box = dojo.byId("box");
    var t = new dojo.fx.Toggler({
        node : box,
        showDuration : 1000,
        hideDuration : 1000
    });
    var visible = true;
    dojo.connect(box, "onclick", function(evt) {
        if (visible)
            t.hide(  );
        else
            t.show(  );

        visible = !visible;
    });
});

If you try out the example, you should notice that clicking on the "Now you see me . . . " box causes it to fade out, while clicking on the "Now you don't" box causes the first box to fade back in.

Get Dojo: The Definitive Guide now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.