Blog der Heimetli Software AG

Die CSS Transform Matrix

Mit CSS können Elemente rotiert und verschoben werden. Eine besonders flexible Variante arbeitet mit einer Matrix.

Wer sich schon einmal mit Computergraphik beschäftigt hat, kennt die Idee: die Koordinaten jedes Punktes werden mit einer Matrix multipliziert um die transformierten Koordinaten zu bestimmen.

CSS benutzt eine seltsame Darstellung dieser Matrix, denn es werden nur 6 Zahlen angegeben. Die ersten vier Werte bestimmen die Rotation und die Skalierung, und die beiden anderen die Verschiebung.

Im Stylesheet steht also zum Beispiel div { transform: matrix(1,0,0,1,0,0); }

Im Beispiel steht die "Einheitsmatrix". Mit dieser Matrix wird jeder Punkt auf genau auf die gleiche Position transformiert.

CSS Matrix-Transform

Die einfachste Transformation ist eine Verschiebung in X-Richtung: matrix(1,0,0,1,20,0). (Ich habe übrigens versucht, die Position mit calc() zu bestimmen, aber zumindest in Chrome funktioniert das nicht)

CSS Matrix-Transform

Ebenfalls sehr einfach ist das Verschieben in Y-Richtung: matrix(1,0,0,1,0,20).

CSS Matrix-Transform

Skalieren geht ebenfalls, wie das nächste Beispiel zeigt. Die Matrix dazu ist matrix(1.5,0,0,1.5,0,0).

CSS Matrix-Transform

Die Faktoren für x und y können auch unterschiedlich sein, wie hier: matrix(1.5,0,0,0.5,0,0).

CSS Matrix-Transform

Wenn die Faktoren negativ sind, wird das Element gespiegelt: matrix(-1,0,0,1,0,0).

CSS Matrix-Transform

Spiegelung an der anderen Achse: matrix(1,0,0,-1,0,0).

CSS Matrix-Transform

Beide kombiniert: matrix(-1,0,0,-1,0,0).

CSS Matrix-Transform

Für die Rotation braucht es mehr Mathematik, jetzt kommen die Winkelfunktionen ins Spiel. Die ersten vier Einträge in der Matrix haben folgende Bedeutung: matrix( cos(alpha), -sin(alpha), sin(alpha), cos(alpha), 0, 0 ). Für einen Winkel von 45 Grad sieht das so aus: matrix(0.707,-0.707,0.707,0.707,0,0).

CSS Matrix-Transform

Eine besondere Eigenschaft der Transformationsmatrizen ist, dass man sie miteinander multiplizieren kann, und man als Resultat die kombinierte Transformation bekommt.

Mein Math-Unterricht ist schon ziemlich lange her, und so musste ich mich im Internet schlau machen. Weil CSS einen Teil der Matrix einfach weglässt, kann man die Berechnungen aus den Seiten auch nicht einfach übernehmen. Nach einigem knorzen habe ich aber eine JavaScript-Funktion zusammengebracht die anscheinend die richtigen Resultate liefert:

function multiply( a, b, c )
{
   c[0] = a[0] * b[0] + a[2] * b[1] ;
   c[1] = a[1] * b[0] + a[3] * b[1] ;
   c[2] = a[0] * b[2] + a[2] * b[3] ;
   c[3] = a[1] * b[2] + a[3] * b[3] ;
   c[4] = a[0] * b[4] + a[2] * b[5] + a[4] ;
   c[5] = a[1] * b[4] + a[3] * b[5] + a[5] ;
}

Mit dieser Funktion ist der Rotor realisiert. Alle 125ms wird das Element um 15 Grad gedreht.

CSS Matrix-Transform

Nimmt man auch den Tangens zu Hilfe, kann man das Element in X-Richtung verziehen: matrix(1,0,tan(beta),1,0,0).

CSS Matrix-Transform

In Y natürlich ebenso: matrix(1,tan(beta),0,1,0,0).

CSS Matrix-Transform

Und in beide Richtungen: matrix(1,tan(beta),tan(beta),1,0,0).

CSS Matrix-Transform

Bisher habe ich das Element immer um sein Zentrum herum rotiert, aber CSS lässt dem Entwickler freie Hand um einen anderen Punkt als Drehpunkt festzulegen: transform: matrix(0.707,-0.707,0.707,0.707,0,0); transform-origin: 0 0;

CSS Matrix-Transform

Für mich ist damit genug. Wer noch mehr will, soll sich doch im Internet mal nach den 3D-Transforms umsehen ;-)