
I love CSS3 transitions! They’re easy to implement, more performant than the setTimeout based alternative & because of this work really well on mobile devices1.
One area CSS transitions are not as flexible as the Javascript alternatives is easing functions. Libraries such as jQuery & Scripty2 have a suite of really compelling functions that just aren’t available with CSS transitions.
So we’re left to choose from:
lineareaseease-outease-incubic-bezier
cubic-bezier does provide us with a lot of flexibility but it still has its limitations. What if we want to implement a bounce effect? Unfortunately we’re out of luck as this is not something that can be modelled with a cubic-bezier.
Thomas Fuch’s raised this very issue earlier this year and pointed to how Apple uses CSS animations instead of transitions for more complex effects. He suggested vendors add the ability to enable a Javascript callback to provide custom easing functions but it looks like this isn’t a viable solution.
Introducing Morf, a Javascript work-around for hardware accelerated CSS3 transitions with custom easing functions.
How do I use it?
Using it is simple but does require that you trigger the transition from Javascript. To transition an element to a new state you would do the following:
// Get a reference to the element
var elem = document.getElementById('elem');
var trans = Morf.transition(elem, {
// New CSS state
'-webkit-transform': 'translate3d(300px, 0, 0) rotate(90deg)',
'background-color': '#FF0000'
}, {
duration: '1500ms',
timingFunction: 'bounce'
});
Thats it! Your element will then transition right 300px, rotate 90deg & change colour to red using the bounce easing function.
For more information on the available easing functions checkout the Morf demo or view the docs available on GitHub.
Requirements
Morf requires the following:
- A WebKit browser capable of CSS Animations (Morf uses
@keyframesanimations under the hood) - Shifty.js (>= 0.1.3) – Morf can be downloaded with or without Shifty pre-bundled
Why is this WebKit only?
Although other browser vendors have started to add CSS Animations (e.g. Firefox 5) they do not yet have an alternative implementation for the WebKitCSSMatrix object which is used to calculate the interpolated matrix values.
How does it work?
So you know how to use it but you want to know how it works? Well, what Morf actually does is create a CSS3 animation on the fly for the requested transition. In other words at the time that Morf.transition is called, all the necessary keyframes are generated to give the impression that a transition has taken place.
Even though this is actually a CSS Animation, Morf does its best to masquerade as a transition, event throwing a webkitTransitionEnd event when its finished.
You may also just want to use Morf as a CSS animation generator, in which case you can get the generated keyframes in CSS format using the .css property. So, continuing the above example:
console.log(trans.css);
Tweening CSS
To work out all the interpolated CSS states, Morf uses the fantastic Shifty.js along with some custom code to handle matrix transformations. Shifty is responsible for working out all regular CSS tween values. e.g. width, height, background-color.
Tweening Matrix Transformations
In order to tween the 3D matrix, I had to add some custom functions to the WebKitCSSMatrix object. The process of accurately tweening between two matrix states requires that the matrixes themselves be first decomposed into their composite parts (translate, rotate, scale etc). Once these composite parts are known, its a matter of tweening between each part of each state and then rebuilding the composite matrix.
The bulk of this calculation is done using the custom WebKitCSSMatrix.decompose() function. This function is a Javascript implementation of pseudo code provided by the W3C. Its likely that this is pretty close to how WebKit produces tween values internally but in Javascript rather than native code, so not quite as quick.
In order to get the decompose() function working I also had to supplement the WebKitCSSMatrix object with some other helpful matrix functions and add a basic Vector4 implementation.
Note: The decompose() function is fairly expensive so its only called once for the start and end state of each transition.
My WebKitCSSMatrix additions are standalone and don’t require Morf.js. It may be useful to others so feel free to repurpose them for your own projects: WebKitCSSMatrix.ext.js (MIT License).
- Ok, not all mobile devices! A lot of Android phones lack hardware acceleration so don’t perform too well [↩]

Pingback: Morf.js – Flexible Beschleunigungsfunktionen für CSS3 Transitions » t3n News
Pingback: CSS3 Transitions with custom easing functions - Programming Blog
Pingback: Revision 30: IE10, Google+ und Dr.Web | Working Draft
Pingback: CSS Chops » CSS3 Transitions with custom easing functions