Let's Make a Framework: Animations
Welcome to part 15 of Let’s Make a Framework, the ongoing series about building a JavaScript framework. This part starts looking at JavaScript animations.
If you haven’t been following along, these articles are tagged with lmaf. The project we’re creating is called Turing and is available on GitHub: turing.js.
JavaScript Animation
JavaScript animation libraries are usually comprised of the following elements:
- Methods to work with CSS properties and animate them
- A queuing system, for scheduling animations, and animating each “frame”
- CSS colour parsing
- Helpers that make common web effects easy to use alongside events
Animation Frameworks
One of the first popular libraries that addressed animation was script.aculo.us. The effects.js script offered many pre-baked effects that developers wanted to use on their sites, and transition effects like Effect.Highlight, Effect.Appear and Effect.BlindDown quickly became popular. These effects are built using some JavaScript logic to manipulate CSS properties.
The script.aculo.us API is based around instantiated objects:
new Effect.EffectName(element, required parameters, [options]);
Most effects take a duration, from and to parameter:
new Effect.Opacity('element', {
duration: 2.0,
transition: Effect.Transitions.linear,
from: 1.0,
to: 0.5
});
The transition option refers to a control function that determines the rate of change.
MooTools has a similar API in its Fx module:
new Fx.Reveal($('element'), { duration: 500, mode: 'horizontal' });
Shortcuts can be added to the Element class as well:
$('element').reveal({ duration: 500, mode: 'horizontal' });
jQuery provides another animation API with helpers and CSS property manipulation. jQuery UI and other plugins build or extend this functionality. The main method is animate which accepts properties to animate, duration, easing function and a termination callback. Most tasks can be completed with the helpers.
The nice thing about jQuery’s animation API is it’s very easy to create sequences of animations — just chain a list of calls:
$('#element').slideUp(300).delay(800).fadeIn(400);
jQuery builds a queue to create these animation sequences. The queue documentation has an example that demonstrates how a queue is built up based on the animation call order and durations.
The Glow framework builds a set of helper methods for common animation tasks from a core animation class called glow.anim.Animation. This can be combined with glow.anim.Timeline to create complex animations.
Queues and Events
Animation frameworks usually use setInterval and clearInterval interval to sequence events. This can be combined with custom events. Due to JavaScript’s single-threaded environment, setInterval and events are the best way of managing the asynchronous nature of animations.
Animation Basics
As we’ve seen, animation frameworks build on top of CSS property manipulation. At its most basic, animation looks like this:
// Box CSS: #box { background-color: red; width: 20px; height: 20px; position: absolute; left: 0; top: 10 }
function animate() {
var box = document.getElementById('box'),
duration = 1000,
start = (new Date).valueOf(),
finish = start + duration,
interval;
interval = setInterval(function() {
var time = (new Date).valueOf(), frame = time > finish ? 1 : (time - start) / duration;
// The thing being animated
box.style.left = frame * 100 + 'px';
if (time > finish) {
clearInterval(interval);
}
}, 10);
}
I based this code on emile.js. It uses setInterval which calls a function every few milliseconds. Time calculations (based on the number of milliseconds returned by new Date) are used to set up the animation and stop it. Once the end of the animation has been reached, clearInterval is called.
This is essentially what jQuery’s animation library does with its queues.
Next Week
Next week I’ll expand on this code to start the basis of an animation library.