Skip to content


Subversion checkout URL

You can clone with
Download ZIP

Animating between complex transforms

jaukia edited this page · 3 revisions
Clone this wiki locally

It is enough to do the calculation (affine transform) for the matrix only when starting the animation. From there on, you can just animate between the initial affine transform values and the final values.

For example, if you have:

matrix(0.000000, 0.707107, -1.414213, 0.707107, 0.000000, 0.000000)

This can be normalized with:

function affineTransform(m) {
    var a=m[0],b=m[1],c=m[2],d=m[3],e=m[4],f=m[5];

    if(Math.abs(a*d-b*c)<0.01) {

    var tx = e, ty = f;

    var sx = Math.sqrt(a*a+b*b);
    a = a/sx;
    b = b/sx;

    var k = a*c+b*d;
    c -= a*k;
    d -= b*k;

    var sy = Math.sqrt(c*c+d*d);
    c = c/sy;
    d = d/sy;
    k = k/sy;

    if((a*d-b*c)<0.0) {
        a = -a;
        b = -b;
        c = -c;
        d = -d;
        sx = -sx;
        sy = -sy;

    var r = Math.atan2(b,a);
    return {"tx":tx, "ty":ty, "r":r, "k":Math.atan(k), "sx":sx, "sy":sy};

You may use it like this:

m = [0.000000, 0.707107, -1.414213, 0.707107, 0.000000, 0.000000];
var aff = affineTransform(m);

As output, in var aff, you get:

{ k: 0.46364789184359106,
  r: 1.5707963267948966,
  sx: 0.707107,
  sy: 1.414213,
  tx: 0,
  ty: 0}

These params correspond directly to css transform statements and can be converted back with:

function matrixCompose(ia) {
    var ret = "translate("+roundNumber(ia.tx,6)+"px,"+roundNumber(ia.ty,6)+"px) ";
    ret += "rotate("+roundNumber(ia.r,6)+"rad) skewX("+roundNumber(ia.k,6)+"rad) ";
    ret += "scale("+roundNumber(,6)+","+roundNumber(,6)+")";
    return ret;

function roundNumber(number, precision) {
    precision = Math.abs(parseInt(precision,10)) || 0;
    var coefficient = Math.pow(10, precision);
    return Math.round(number*coefficient)/coefficient;

Example with aff:


The output of this is:

"translate(0px,0px) rotate(1.570796rad) skewX(0.463648rad) scale(0.707107,1.414213)"

So basically, this is a way to transform any simple or complex set of transforms into a combination of translate, rotate, skewX and scale. And when you do this conversion to both the animation start and end states, then you can be quite sure that the animation is reasonable and there are no weirdnesses (at least when the corresponding angles are less than PI apart from each other).

Something went wrong with that request. Please try again.