Ease Yourself Into AnimationSydJS, January 18, 2012

Who’s This Clown?

A Brief History of Time

A Brief History of Distance/Time

A Brief History of Easing

Robert Penner

In other words…

The first easing function

Math.easeInQuad = function (t, b, c, d) {
  return c*(t/=d)*t + b;
};

Variables minified for AS1 interpreter quirks.

Variables with longer names take longer to look up than variables with short names, because of the interpreter’s internal hashing procedure.

Robert Penner

Perfect for byte-conscious JS!

JS Implementation #1 - Penner Ported

jQuery & jQuery UI

Penner’s system copied almost exactly.

Penner’s ActionScript
Math.easeInOutSine = function (t, b, c, d) {
  return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
};
jQuery
jQuery.easing.swing = function( p, n, firstNum, diff ) {
  return ( ( -Math.cos( p*Math.PI ) / 2 ) + 0.5 ) * diff + firstNum;
}

Easing for Dummies

Clandestine rendezvous between secret agents:

Mr A. – Animation

Mr E. – Easing

Animation sets the time, Easing sets the place

Animation sets the time, Easing sets the place

Easing for Smarties

At its most basic level, an easing function takes the amount of time that has elapsed for an animation, and returns a new position for the animation based on a function of the time.

Confused? Bored?

Never fear, shiny graphs to the rescue!

Easing for Those Who Like Graphs

Common Easing Methods

Smooth Curves

Sine
Quad
Cubic
Quart
Quint
Expo
Circ

Special Effects

Back
Bounce
Elastic

JS Implementation #2 - Cruft Removal

Raphaël, Dojo & Scriptaculous

Single parameter for percentage – everything else should be handled by the framework.

Dojo – All of Penner’s equations in a new format
Raphaël – similar to Dojo but tweaked a little
function (n) {
  return pow(n, 1.7);
}
Scriptaculous – very few Penner equations, provided defaults aren’t as useful
function(pos) {
  return (-Math.cos(pos*Math.PI)/2) + .5;
}

Look a little deeper: ease-in-back

jQuery.easing.easeInBack
function (x, t, b, c, d, s) {
  if (s == undefined) s = 1.70158;
  return c * (t /= d) * t * ((s + 1) * t - s) + b;
}
Raphael.easing_formulas.backIn
function (n) {
  var s = 1.70158;
  return n * n * ((s + 1) * n - s);
}

Redundant code is redundant, and redundant as well

Easing functions shouldn’t have to care about the start/end values, only the percentage matters.

1.70158 = Penner’s Magic Number.

JS Implementation #3 - Atoms

MooTools & D3

DRY – maximum code reuse.

MooTools
['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){
  Fx.Transitions[transition] = new Fx.Transition(function(p){
    return Math.pow(p, i + 2);
  });
});
D3
function d3_ease_reverse(f) {
  return function(t) {
    return 1 - f(1 - t);
  };
}

function d3_ease_reflect(f) {
  return function(t) {
    return .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t)));
  };
}

There Is No Spoon

Once you know the workings, you can manipulate.

Up and atom!

$.easing.tardis = function easeTardis(t) {
    var steps = 9,
        curStep = ~~(t * steps),
        stepDiff = curStep / steps,
        newPerc = (t - stepDiff) * steps,
        newEasing = $.easing.easeInOutSine(newPerc);
    if (curStep % 2) {
        newEasing = 1 - newEasing;
    }
    return newEasing * .5 + t / 2;
}
$(elem).animate({opacity: 1}, 10000, 'tardis');

A Little Bit of CSS

CSS easing functions based on bezier curves.

transition-timing-function: ease-in-out;
/* Equivalent to */
transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
CSS Easing Graph

(Graph from matthewlein.com/ceaser)

This is not SydCSS

But wait!

Raphaël supports the cubic bezier syntax, so there is relevance after all.

elem.animate(params, duration, "cubic-bezier(0.42, 0, 0.58, 1)")

Take that, King Leonidas!

Questions?

Links

More Information

Robert Penner’s easing site

jQuery Easing

jQuery Easing plugin

James Padolsey’s Interactive Easing Demo

CSS Easing Tools

Ceaser

Cubic Bezier

Shameless self promotion

jQuery Easing Repeater

jQuery Easing Molecules (WIP)