When you dive
into the CSS3 transform: matrix3d documentation, you find a short definition of "Specifies a 3D transformation as a 4x4 matrix.", Followed by a function definition in the form:
matrix3d(m00, m01, m02, m03,
m10, m11, m12, m13,
m20, m21, m22, m23,
m30, m31, m31, m33)
And if you are not the god of mathematics, most likely, inside there is a concern about the lack of documentation, followed by the question of how to create a really cool thing? The described approach does not pretend to be called mathematical or complete - I'm just trying to fill a small gap in the documentation.
demo |
original sourceSome linear algebra
Any complex transformation can be represented by three basic ones:
')
Rotate
Scale
Move (translate)
These 3 basic transformations can be combined into one huge comprehensive transformation matrix. So far everything is simple, but how to move from 3 basic stages to that unchecked list of parameters that is needed for matrix3d? Let's start with the simplest matrix in mathematics (to simplify my life, I use
Sylvester for mathematical operations with matrices).
Unit matrix

This matrix does nothing! Nil! Null! Nada! Not a single pixel was hurt! I divided this matrix into 2 sections. The red section is the area where Rotate and Scale are described. The yellow section describes a shift or translate. The remaining parameters are used very rarely, with the exception of the really weird LSD-style FX demos.
We will begin by creating a scaling matrix by multiplying the identity matrix by the scaling factor.
scaleMatrix = indentityMatrix.multiply (s)
Scaling matrix
scaleMatrix = $ M ([
[s, 0,0,0],
[0, s, 0.0],
[0,0, s, 0],
[0,0,0, s]
])
Since we do not want to transform the translate coordinates, let's replace the last scaling parameter by 1:
scaleMatrix = $ M ([
[s, 0,0,0],
[0, s, 0.0],
[0,0, s, 0],
[0,0,0,1]
])
Rotation Matrices
Rotation can be carried out around its own axis X, Y, Z at a given angle. Let's take the angle values for each axis as a, b, c. Corresponding matrices representing such a transformation:
rotationXMatrix = $ M ([
[1,0,0,0],
[0, Math.cos (a), Math.sin (-a), 0],
[0, Math.sin (a), Math.cos (a), 0],
[0,0,0,1]
])
rotationYMatrix = $ M ([
[Math.cos (b), 0, Math.sin (b), 0],
[0,1,0,0],
[Math.sin (-b), 0, Math.cos (b), 0],
[0,0,0,1]
])
rotationZMatrix = $ M ([
[Math.cos (c), Math.sin (-c), 0, 0],
[Math.sin (c), Math.cos (c), 0, 0],
[0,0,1,0],
[0,0,0,1]
])
Each matrix describes a rotation around one axis.
Translate matrix
translationMatrix = $ M ([
[1,0,0,0],
[0,1,0,0],
[0,0,1,0],
[tx, ty, tz, 1]
])
The displacement matrix does not affect most pixels, but adds tx, ty, and tz values to the resulting direction vector.
Fun
Yes, mathematics can be fun, and each of these matrices can be used in composition. So, if you want to rotate something around each axis and then move it a few pixels, simply multiply these matrices. That's all:
tM = rotationXMatrix
.x (rotationYMatrix)
.x (rotationZMatrix)
.x (scaleMatrix)
.x (translationMatrix)
And at the end apply the transformation to the image:
s = "matrix3d ("
s + = tM.e (1,1) .toFixed (10) + "," + tM.e (1,2) .toFixed (10) + "," + tM.e (1,3) .toFixed ( 10) + "," + tM.e (1,4) .toFixed (10) + ","
s + = tM.e (2,1) .toFixed (10) + "," + tM.e (2,2) .toFixed (10) + "," + tM.e (2,3) .toFixed ( 10) + "," + tM.e (2,4) .toFixed (10) + ","
s + = tM.e (3,1) .toFixed (10) + "," + tM.e (3,2) .toFixed (10) + "," + tM.e (3,3) .toFixed ( 10) + "," + tM.e (3,4) .toFixed (10) + ","
s + = tM.e (4,1) .toFixed (10) + "," + tM.e (4,2) .toFixed (10) + "," + tM.e (4,3) .toFixed ( 10) + "," + tM.e (4,4) .toFixed (10)
s + = ")"
document.getElementById ('darth-vader'). style ['- webkit-transform'] = s
Cautions
The first is that if you google a linear transformation and find examples of such matrices, you might be surprised that the matrices are slightly different. The fact is that the CSS matrix is transposed — just like that, transpose the matrix and it should work.
The second is that CSS does not support the scientific form of a number (for example, 123e-15) as parameters — so you need to use toFixed (numberOfDigits) to normalize them.
Development environment
The approach works in -webkit-browsers such as Chrome or Safari, Firefox 10+ and IE 10. You can see the prefixes here
caniuse.com/transforms3d . The demo only works in -webkit- and is written in
coffeescript which is a bit cooler than javascript - but the compiled code should be readable. You can pick up the entire lesson and source code on
github .
DemoOriginal articleFacebook authorTwitter authorSylvester's amazing Javascript libraryLinear transformation article on Wikipedia