Image Transitions Manual

2. Further Development

This is the advanced user guide, which focuses on how to synchronise transitions, such as triggering one from another to create interesting two-stage effects. It will also show you how to synchronise longer, more complex sequences, for things like slideshows, presentations and image-rotation scripts.

  1. Defining the transition callback
  2. Synchronising multiple transitions

Defining the transition callback

At the heart of the script's synchronisation capabilities is the ability to define an asynchronous callback, that the transition method will call immediately after the transition has finished. You can use the callback function simply to start another transition straight away, or put it to use as part of a more sophisticated sequence of events.

The callback function is the final argument to any transition method — you can define an anonymous function directly, or pass a reference to a named function. So for example, when added to fade, it would be argument [4]:

Transitions.fade("#flag", "red.png", "Red Flag", "2", myCallback);

Or added to any of the other transition methods, it would be [7]:

Transitions.wipe("#flag", "red.png", "Red Flag", "2", "RND", "0", "No", myCallback);

However, since the fade depth and reverse transition arguments are optional, the script allows you to omit those arguments entirely, and define the callback function directly after the animation type. You can omit both those optional arguments, or just the last one, and this saves you having to add their values simply to re-create their defaults. So all three of the examples below are effectively identical:

Transitions.wipe("#flag", "red.png", "Red Flag", "2", "RND", "0", "No", myCallback);
Transitions.wipe("#flag", "red.png", "Red Flag", "2", "RND", "0", myCallback);
Transitions.wipe("#flag", "red.png", "Red Flag", "2", "RND", myCallback);

Synchronising multiple transitions

We've seen how the key to synchronisation is the use of a transition callback. So now let's take a look at some of the things we can do!

Creating a two-stage transition effect

The simplest kind of synchronisation is using the callback to start a second transition, combining both transitions to create some kind of two-stage effect.

The previous version of this script included an effect called Swap-Fade, whereby the original image would fade-out and then the new image would fade-in — two discreet transitions, as opposed to the cross-fade the current script implements.

But we can still create that swap-change effect with the help of a callback function, by implementing a two-stage transition via an intermediate shim (a completely transparent image, either GIF or PNG):

Transitions.fade("#flag", "shim.png", "", "1", function()
    Transitions.fade("#flag", "red.png", "Red Flag", "1");

We're not just limited to fade, of course, we can do this with any transition. How about using grow, for an effect where the original image shrinks-away then the new one grows in its place:

Transitions.grow("#flag", "shim.png", "", "1", "TB", "0", "Yes", function()
    Transitions.grow("#flag", "red.png", "Red Flag", "1", "TB");

Notice how the first transition is a reverse top-to-bottom — which is different than a forward bottom-to-top. A reverse transition shrinks the original image to reveal the new one underneath; but conversely, a forward transition grows the new image to cover-over the original — and that's not the effect we want. More to the point, since the new image in the first transition is completely blank, if we ran that half as a forward transition we wouldn't see anything at all.

Don't forget to cache the images first!

Creating a longer sequence

Now that we have the basic idea, we can extend the principle as far as we like, to create a longer, more complex sequence with any number of images. Such a sequence could form the basis of a slideshow, or a presentation, or it could be the eye-candy on top of an image-viewing gallery — whatever.

If we create a wrapper function around a single transition, and pass the transition a callback function which calls the wrapper again, then we have a process that will run forever! But further logic inside the function could determine when to stop, what the next image is, or whatever else it takes to create the finished product.

So for example — let's define some images in an array, then run a bunch of transitions from one to the next, until we've seen them all; we can use a numeric pointer to track our progress through the array:

var n = 0, flags = ["red", "gold", "green", "blue"];

function sequence()
    Transitions.fade("#flag", flags[n] + ".png", flags[n] + " flag", "0.8", 
        if(++n < flags.length) { sequence(); }


In that example, the ALT text for each image is extrapolated from the image SRC, but if the images you're using require more intelligent descriptions, you can always define a second array to store different text for each one. And not just for ALT, of course — the same principle is true for any of the transition methods' arguments.

Supposing we wanted each transition to have a different animation type, we could define an array of types and use the same pointer to refer to it. This next example uses double-slide transitions, to move between four images that are slices from a larger one — giving the impression of panning around a single, large image:

var n = 0, 
    types = ["DLR", "DTB", "DRL", "DBT"], 
    slices = ["bottom-left", "top-left", "top-right", "bottom-right"];

function sequence()
    Transitions.slide("#map", slices[n] + ".jpg", "Map of Australia", "1.6", types[n], 
        if(++n < slices.length) { sequence(); }


So, using the same approach of creating additional argument arrays, we can organise any parameter into a sequence of events. Perhaps you'd like to vary the timing, so that some changes are quicker than others; maybe introduce a pause between each image and the next one, as slideshows and image-rotation scripts generally do. With a very long list of images, you might even wish to pre-load on-the-fly — for example, only cache the first five images, and then use each sequence iteration to load the next one in line (having buffered five frames' worth of data, you should have enough time to load each new image before you need to display it; or if the images are particularly large, the buffer should probably be larger as well).

Sequencer fallback timing for partially-supported browsers

As we've noted before, there are a few browsers that only support some of the transitions — Firefox 3.0, for example, doesn't support grow, twist or skew. There's also the possibility, in any supported browser, that the user is viewing the page with images disabled. In both these cases, the fallback behavior is to do a simple image-swap.

And therefore ... any sequence you put together will always produce some kind of result — a basic image-rotation at least — whichever transitions you use and whatever the state of the browser that views it. The issue, however, is one of timing.

The callback fires as soon as the method completes, but if all it's doing is the basic swap — which happens almost instantly, rather than being a timed effect — then each iteration will happen so fast that it rips-through the whole set of images in virtually no time at all!

To get round this problem, there's a configuration option called "long-fallback", which when enabled, adds a delay to the fallback behavior, so it still has the same duration as the original transition effect. Used with a sequence of transitions, it means that you'll still see each image (or its ALT text) for the right length of time, as they're stepped-through progressively rather than spewed out in an instantaneous blur!

Detecting the fallback behavior

You can also detect when a browser does the fallback behavior for a transition, because when this happens, the transition method will return null to indicate the exclusion (rather than returning true for success, as it otherwise normally would).

The timing of transition methods and their callbacks is such that the method will always return before its callback fires. So if you save what the method returns, then you can refer to it from within the callback to infer what the browser did:

var result = Transitions.skew("#flag", "red.png", "Red Flag", "2", "TRDF", 
    if(result === true)
        //the browser ran this transition
    else if(result === null)
        //the browser did the fallback behavior instead

Using the Script | ← main page


Get the script

BSD License → Terms of use

Image Transitions Manual

  1. Using the Script
  2. Further Development [this page]

main page


Website gadgets

Bits of site functionality:

Usability widgets

Local network apps

Web-applications for your home or office network:

Game and novelties

Our internal search engine is currently offline, undergoing some configuration changes in preparation for a major site overhaul. In the meantime, you can still search this site using Google Custom Search.

In this area

Main areas

[brothercake] a round peg in a square hole, that still fits