As followers of this blog know, I am a pretty big fan of Adobe's JavaScript framework, Spry. Admittedly, it's not a super-huge framework like jQuery, but I like its simplicity and how rapidly I can develop a solution with it.

One thing I've been frustrated with is Spry's effects. While they have some good effects, I never found them particularly flexible or usable beyond little dynamic enhacements. Apparently, most of this is because I hadn't read the documentation enough.

Enter effect clustering. Normally, Spry effects run in turn of function call: so if you have, say, a tool-tip that you want to fade out and move, these effects would run in order (which wouldn't really make sense to do anyway). However, as I discovered with great joy yesterday, Spry allows for something called "effect clustering" which allows any number of effects to be run in parallel with one another.

I about peed my pants when I found this out, it's so cool and useful. So here's an example of this in action.

And here's the code:

FadeMove = function(element, options) {
Spry.Effect.Cluster.call(this, options);

var duration = 1000;
var toggle = 'false';
var from = 100;
var to = 0;
var fromPos = new Spry.Effect.Utils.Position();
fromPos.x = 13;
fromPos.y = 0;
var toPos = new Spry.Effect.Utils.Position();
toPos.x = 13;
toPos.y = -65;
Spry.Effect.makePositioned(element);

var transition = Spry.fifthTransition;

if (options) {
if (options.duration != null) duration = options.duration;
if (options.from != null) from = options.from;
if (options.to != null) to = options.to;
if (options.transition != null) transition = options.transition;
}

var fadeOut = new Spry.Effect.Fade(element, {duration: 500, from: from, to: to, transition: transition, toggle: toggle});
var moveUp = new Spry.Effect.Move(element, fromPos, toPos,{duration: 800, transition: transition, toggle: toggle});

this.addParallelEffect(fadeOut);
this.addParallelEffect(moveUp);
};

FadeMove.prototype = new Spry.Effect.Cluster();
FadeMove.prototype.constructor = FadeMove;

Honestly, this is super-easy to do. You start by extending the Cluster class–any effects that you include in this extension now become a cluster.

FadeMove = function(element, options) {
Spry.Effect.Cluster.call(this, options);
.............
}
FadeMove.prototype = new Spry.Effect.Cluster();
FadeMove.prototype.constructor = FadeMove;

In this example, I want to have an effect that "fades" and "moves", so I called my class extension "FadeMove." You can call it whatever you want.

The next thing to do is to setup some default options for the effects you're going to be using:

var duration = 1000;
var toggle = 'false';
var from = 100;
var to = 0;
if (options) {
if (options.duration != null) duration = options.duration;
if (options.from != null) from = options.from;
if (options.to != null) to = options.to;
if (options.transition != null) transition = options.transition;
}

The function allows you to pass in your own options dynamically, so these are just here as a safety net.

Next, define your effects, just as you normally would for any Spry effect call:

var fadeOut = new Spry.Effect.Fade(element, {duration: 500, from: from, to: to, transition: transition, toggle: toggle});
var moveUp = new Spry.Effect.Move(element, fromPos, toPos,{duration: 800, transition: transition, toggle: toggle});

Simple. So now the only thing left to do is to tell the function that you'd like to have these effects run in parallel. As with all things Spry, this is cake:

this.addParallelEffect(fadeOut);
this.addParallelEffect(moveUp);

Guess what? That's it. There is nothing more to it than that. Seriously, I am completely psyched about abusing this new knowledge on all my projects. Be sure to check out my example.