#### An in-depth tutorial about Mootools Transitions

Usually when using an effect I used to try out possible transitions one after another until I found the right one, but this got quite boring after some time, so I looked at the mootools source code to understand the logic behind – that’s what this tutorial is about.

General information can be found here: mootools.net/docs/core/Fx/Fx.Transitions » and also here: ryanflorence.com/mootools-fx-transitions-demo/ »

### What is a transition?

The process or a period of changing from one state or condition to another.

This is the dictionary definition — in our case, when using transitions for Mootols Effects this means the process of changing (element-)values from a beginning state to an ending state

.

#### The example

So as an example let’s use Fx.Tween to change the element width from 50px to 550px in 1 second. Here are several examples of transitions – trigger them by clicking the pink boxes.

**If the demo doesn’t work: Reload the page, this should help (or write a comment if the problem persists).**

### How to use transitions

This should be nothing new, here the javascript I used for the examples above:

```
$('element').addEvent('mousedown', function(event) {
this.set('tween', {duration: 'long', transition: 'cubic:in'});
this.tween('width', [50, 550]);
});
```

Alternatively you can write the transition with its classname:

```
transition: Fx.Transitions.Cubic.EaseIn
```

Which notation you use is up to you – if you use the string representation, mootools automatically finds the appropriate Fx.Transitions-class.

### Elements of a transition

Mootools transitions consist of three elements:

- Duration
- Type of transition
- An additional
ease

-value (if the type is notlinear

)

In our example the transition takes the element width and transforms it from the starting value 50 to the target value 500 in one second. The type decides

how the in-between values are being calculated, the ease

decides from which direction

the formula is applied – more about this later on.

#### Duration

This is simply the duration is it takes to change the values – in microseconds, so a duration of 1000 equals 1 second.

There are three predefined durations:

*ms*= ¼ second

normal: 500

*ms*= ½ second

long: 1000

*ms*= 1 second

### How are transitions calculated?

Let’s use the above example, the width of an element is being tweened from 50 to 550 pixel, with a duration of 1000 ms. So our starting value *from* is 50, the target value *to* is 550. That means we’ve got to cover a distance

of 500 pixels in one second.

Now let’s say our transition is expressed as a function *f(x)*, this is the code used in mootools:

*delta*=

*f*((

*current_time*−

*starting_time*) /

*duration*)

*new_value*= (

*to*−

*from*) *

*delta*+

*from*;

This is the mathematical notation, the mootools source code looks more javascript-like of course.

(*current_time – starting_time*) = the number of milliseconds since the effect was started

The argument of the function is *time difference divided by duration* – at the beginning this is about 0.0, after 500 ms this value is 0.5, at the end its approximately 1.0. So the transition function is applied to a range from 0.0 to 1.0 (*normalized*).

Let’s assume we use a linear transition, so *f(x)* = *x*:

So the new_value (our new width) is 0.0 to 1.0 times the range (500) plus the initial value (50). Or: At the beginning the width is set to 50 (initial value), after half the time we’ve got 500*0.5+50 = 300, and at the end 500*1.0+50 = 550.

In this case the values from 50 to 500 are distributed uniformly along the unit interval from 0.0 to 1.0 — a linear function.

### Types of Transitions

These are: Linear, Quad, Cubic, Quart, Quint, Pow, Expo, Circ, Sine, Back, Bounce and Elastic. Now I’ll explain how they work.

##### Linear Transition

A linear transition has no additional ease

-parameter, since it simply divides the range equally along the timeline, as seen above.

*f*(

*x*) =

*x*

##### Polynomial (*x*^{n}) Transitions

^{n}

In this category we’ve got: Quad, Cubic, Quart, Quint, Pow. All these are similar, only the exponent n of the function is changed – from 2 (=Quad) to 6 (=Pow). This is the following function:

*f*(

*x*) =

*x*

^{n}

For these transitions the value will first increase slowly and near the end of the effect it will grow rapidly – like the well-known parabola.

##### Exponential Transition

The exponential transition puts x in the exponent (along with some factors):

*f*(

*x*) = 2

^{8(x−1)}

So the function grows even more rapidly towards the end – compared to the x^{n}-transitions.

##### Circular Transition

The circular transition function describes a perfect circle (in this case a quadrant):

*f*(

*x*) = 1− sin(arccos

*x*)

##### Sinusoidal Transition

The sinusiodal transition delivers a graph which behaves like a part of a sine-curve, the result in this case is a smooth, nearly linear transition (see the graph below).

*f*(

*x*) = 1− sin((1−

*x*) ⋅

^{∏}/

_{2})

##### Back/Bounce/Elastic

These are special functions which use more complex formulas – have a look at the graph below to see how the back and elastic functions behave.

###### Back Transition

Back moves the value first in the opposite direction (in our case: the width gets smaller than 50 px) and then moves it in direction of the target value (view this in the example above).

*f*(

*x*) =

*x*

^{2}(2,618

*x*−1,618)

###### Elastic Transition

Elastic oscillates in increasing intervals between the opposite direction and the desired one. It’s best used with ease:out or ease:in:out, otherwise it may happen that effect doesn’t reach its target value.

*f*(

*x*) = 2

^{10(x−1)}⋅ cos(20⋅

*x*⋅∏⋅

^{1}/

_{3})

This transition appears like being on an elastic rope.

###### Bounce Transition

Bounce is the most complex function – it can’t be described as a simple formula. It first approaches the target value linear and then it oscillates between descreasing intervals, creating a bouncing

effect.

### Ease in and out

**Ease in** is the default behaviour: Here the function is applied normally.

**Ease out** inverts the behaviour – so the effect works backwards.

*g*(

*x*) = 1−

*f*(1−

*x*)

**Ease in and out** is more complex: In the first half of the time the transition is applied normally, in the second half it is applied reverse.

*x*<= 0.5):

*g*(

*x*) =

*f*(2

*x*) / 2

otherwise:

*g*(x) = 2−

*f*(2(1−

*x*)) / 2

### Transition functions visualized

This graph shows different transition functions (approximately):

### Values of transition functions

If you look at the graph above you might notice a pattern: the domain of transition functions is [0.0 ‥ 1.0] and the range is [−0.5* ‥ 1.0]. The only exception is the elastic

transition and here you should use it with ease:out, otherwise the desired output might not be what you want.

* −0.5 is not a definitive value, lower values are possible — but then some unpredicted results might happen.

So generally speaking (and as nagaozen stated below) a transition function should start at (0,0) and end at (1,1).

*f*: [0‥1] → [−0.5‥1] with

*f*(0) = 0 and

*f*(1) = 1

### Creating an own transition function

In case this is not sufficient, mootools offers us the possibility to apply any function as a transition. Here’s an example:

```
function powsin(p) {
return (Math.pow(p + 0.4, 3) * Math.sin(p - 0.5)); // our own function
};
var transitionPowsin = new Fx.Transition(powsin);
element.set('tween', {duration: 'long', transition: transitionPowsin});
```

Don’t be confused by the variable “p”, it’s mootools standard in this case – you can also use “x” or whatever you like..

Now the powsin

-function isn’t the most useful transition ever, but take it as an example for own experiments.

Here’s how it looks (click the pink rectangle to start):

That’s it – Comments and Feedback of course welcome.

Back Transition

f(x) = x2 (2,618x−1,618)

————————

n=2;…..30.

f(x) = x2 (nx−n)

Good Man, God bless.

Thank you for this Transition explanation with demo. I have this bookmarked long time a ago. I was so thankless till now. :-)

Thanks, nice to hear! :)

in an update, you wrote: So generally speaking (and as nagaozen stated below) a transition function should start at (0,0) and end at (1,0).

This is not correct. It should end at (1,1). That is to say, f(1) = 1.

Also, your own custom transition function does not in fact follow this recommendation. When it is used, the result is visually confusing . You should normalize the fn to deliver f(1)=1. You simply need to use g(x)=(f(x)/f(1)) .

Yes thanks, that was a typo, f(1)=1 as I wrote was correct, but the line above had an error.

And my example function is admittedly not the best one, that’s right.

Hi I want to know can we move any element in cross direction rather than just left right.

Like we can drag element with any direction using Drag functionality, Can this be automated as we can change top and left..

Thanks

Avi

I’m not sure if I understand your question correctly… Is your question about moving an item with

Dragor about moving an item with atransition(like the examples above)? You can also send a link to an example page or graphics.mario

Thanks for explanation and demo. It would be nice if there was a link to return elements to initial state (for transition comparing)

Hi –

good idea, thanks! Added a “reset all”-button to the “trigger all”-button (just above the bars).

Very nice article!

One little note: you use the following notation:

f(x) := 1−f(1−x)

Mathematically this creates a kind of recursion, since you use the f(x) function to define the f(x) function.

Better would be:

g(x) := 1−f(1−x)

Yes, that was of course informal pseudocode, correct would be g(x) = 1 – f(1-x). The

-operator is also at the wrong place (to be really mathematically exact :).Just thought about it.. but i’ve got no idea, why I used this

definition-operator — the last time I’ve used this must have been in PASCAL/MODULA-2 and that was some time ago :)Anyway – thanks for the hint.

For me, your examples don’t work in Chrome, but do work in Firefox. 2.18.10 Thanks for the detailed explanation!

Chrome (Mac) does work here. Does the Javascript Console in Chrome show any errors?

Yup. On first load, none of the examples work in Chrome Mac (5.0.307.1 dev). Reloading consistently fixes it.

On first load, JS Console says:

Uncaught TypeError: Object [object DOMWindow] has no method ‘addEvent’ — mootools-transitions-explained:106

Uncaught TypeError: Object [object DOMWindow] has no method ‘addEvent’ — mootools-transitions-explained:260

Sounds like some weird timing or cache problem (tried it here with empty cache and not being logged in – can’t reproduce). I’ll have a look later on.

[UPDATE] Seems this happens not only here: http://www.google.com/search?hl=en&rls=en&q=object+%22no+method%22+mootools&sa=N

Nice article indeed!

As a side note, the next version of MooTools will allow non 0-1 transitions as well. Me and Olmo experimented a few weeks ago with bounce-in-place kinds of transitions. Fun times™ ahead!

MooTools is has an animation framework where, without loss of generality, animations should start at (0,0) and finish at (1,1). This is a good choice for at least two purposes:

1) Numerical Normalization – Since javascript Number implementation is a IEEE-754 (double) 64-bit floating point, some math involving very large and very small numbers doesn’t converge to what we want. Remember: 0.1 + 0.2 === 0.3 // false in javascript. This is a little issue related to floating points and working inside (0,1) prevents us from a lot of numerical bugs.

2) Having an “a priori” known domain (0,1) and also a known ending point (1,1), MooTools is the only one framework that comes with an easeIn, easeOut and easeInOut interpretation for any seed function you provide.

Thanks – a very good addition!

Great article!

One comment on making your own transitions. Make sure that they start and end with 0 and 1 respectively. Otherwise, you’ll get some unexpected results.

Thanks –

yes right! Just after publishing I realized that something about the set of all possible values (and especially start/end values) is missing somehow. Will put up a paragraph about that the next days.