Let's Make a Framework: Animations Part 3

2010-06-17 00:00:00 +0100 by Alex R. Young

Welcome to part 17 of Let's Make a Framework, the ongoing series about
building a JavaScript framework. This part continues 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:


Easing is an important animation technique that most people will never
realise exists. It's a surprisingly important technique for creating
natural-looking animations, even for simple web animations. Most
animations use easing functions, and animation frameworks usually use
one by default. Animations can seem strangely abrupt without non-linear

The script.aculo.us

has a useful interactive example of many common easing functions.
Another great resource is in the documentation for

From wikipedia:

"Ease-in" and "ease-out" in digital animation typically refer to a mechanism for defining the 'physics' of the transition between two animation states, eg. the linearity of a tween.

Adding Easing Function Support

Last week the turing.anim.animate method accepted
parameters but didn't do anything with them. Let's change it to work
like this:

turing.anim.animate(box, 1000, { 'marginLeft': '8em', 'marginTop': '100px' }, { easing: 'bounce' });

The default easing will be linear, and I'll include a few easing
functions so other people can reference them and create their own:

var easing = {};
easing.linear = function(position) {
  return position;

Then the animate method just needs to ensure the user has
specified either a string or a function:

if (options.hasOwnProperty('easing')) {
  if (typeof options.easing === 'string') {
    easingFunction = easing[options.easing];
  } else {
    easingFunction = options.easing;

Writing Easing Functions

The classic easing function is based on cos:

easing.sine = function(position) {
  return (-Math.cos(position * Math.PI) / 2) + 0.5;

Mathematical functions can be exploited to create interesting effects.
Functions like sin and cos are oscillators,
and their periodic nature is useful for many types of animation. The
visual impact of this easing function is more like acceleration than
linear movement.

If you'd like to create your own functions based on trigonometry, it's
worth reading the wikipedia page on sine
to get a feel for the
basics first.

I explored the easing functions I've used here with Grapher, which comes
with some versions of Mac OS. If you're familiar with the mathematical
notation for basic trigonometric equations it can be a useful tool for
finding out why a particular function makes everything move backwards

More "programmatic" equations can be created using if
statements to change the position multiplier at certain points:

easing.bounce = function(position) {
  if (position < (1 / 2.75)) {
    return 7.6 * position * position;
  } else if (position < (2 /2.75)) {
    return 7.6 * (position -= (1.5 / 2.75)) * position + 0.74;
  } else if (position < (2.5 / 2.75)) {
    return 7.6 * (position -= (2.25 / 2.75)) * position + 0.91;
  } else {
    return 7.6 * (position -= (2.625 / 2.75)) * position + 0.98;

I based these equations on the
Tweener library and script.aculo.us.

Next Week

Last week I said I'd cover animation helpers and how to build a chained
animation API. I forgot to factor the topic of easing into my plans, so
I'll try to get to these topics next week.