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.
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)
Ebenfalls sehr einfach ist das Verschieben in Y-Richtung: matrix(1,0,0,1,0,20).
Skalieren geht ebenfalls, wie das nächste Beispiel zeigt. Die Matrix dazu ist matrix(1.5,0,0,1.5,0,0).
Die Faktoren für x und y können auch unterschiedlich sein, wie hier: matrix(1.5,0,0,0.5,0,0).
Wenn die Faktoren negativ sind, wird das Element gespiegelt: matrix(-1,0,0,1,0,0).
Spiegelung an der anderen Achse: matrix(1,0,0,-1,0,0).
Beide kombiniert: matrix(-1,0,0,-1,0,0).
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).
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.
Nimmt man auch den Tangens zu Hilfe, kann man das Element in X-Richtung verziehen: matrix(1,0,tan(beta),1,0,0).
In Y natürlich ebenso: matrix(1,tan(beta),0,1,0,0).
Und in beide Richtungen: matrix(1,tan(beta),tan(beta),1,0,0).
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;
Für mich ist damit genug. Wer noch mehr will, soll sich doch im Internet mal nach den 3D-Transforms umsehen ;-)