CSS3 Tutorial: matrix transformations

CSS3 Transform matrix

In the previous tutorials Transform and Transform2 we saw how we could translate, rotate, scale , skew , and reflect 2-dimensional shapes using the CSS3 transform property. The transform property accepts a value which is in fact a function, like so:

transform: rotateZ(45deg)
transform: translate(50px, -4em)
transform: skew(20deg, 20deg)
transform: scale(1.5;

But what do these functions actually do behind the scenes? They performs unnoticed certain mathematical operations, the so-called matrix operations. Wouldn't it be great if we could perform such operations directly by ourselves, thus without using the black-box translate(), rotate(), skew(), use and scal () functions, so that we really have all the freedom in transforming shapes or images. But how convenient! CSS3 has a feature which makes it possible: the matrix() function.

/* CSS3 transform operation */
#object {
	transform-origin: 0 0;
	transform:translate(250px,200px);
}   
/* Same CSS3 transform operation using the matrix()( function */
#object {
	transform-origin: 0 0;
	transform: matrix(1, 0, 0, 1, 250, 200);
}

(Note: The browser-specific variants (e.g. moz-transform, etc.) are omitted here for the sake of clarity).

The result


Image 1. transform: translate(250px,200px) is identical to: transform: matrix(1, 0, 0, 1, 250, 200).

The matrix

The matrix function is actually a CSS way of performing a little bit of linear algebra. In pure math, hence linear algebra, we don't use this function, instead we directly use a transformation matrix.

$$ \left( \begin{array}{cc} 1 & 0 & 250 \\ 0 & 1 & 200 \\ 0 & 0 & 1 \end{array} \right) $$

But what do all those numbers mean?

The transformation matrix: a brief explanation.

For each type of transformation (translation, rotation, mirroring, etc.) there is a separate transformation matrix. But how we create the matrix associated with a particular transformation? For this purpose check out the diagram below in which a three-dimensional coordinate system is drawn (with x-plane, y-plane and z-plane) containing 3 red arrows. The red arrows point to a certain point in the coordinate system and are also referred to vectors, not to be confused with vector images. Because they point to the points (1,0,0), (0,1,0) and (0,0,1), these vectors aro also called 'unit vectors'.

assenstelsel

The red arrows, thus the unit vectors, are the first phase for the drafting of a transformation matrix. The question is always, what is the position of the unit vectors after a certain transformation? Let's look at an example:

Example 1: Determining the transformation matrix of a rotation over 90 degrees around the z-axis (that is a rotation within the XY plane, our well known 2 Dimensional space)?.

When we flip the red arrows in the z-axis, we get:

  • The vector OA after the rotation points to (0,-1,0)
  • The vector OB after the rotation points to (1,0 ,0)
  • The vector OC after the rotation points to (0,0,1).

Now, we can set up the transformation matrix associated with a rotation in the XY plane about 90 degrees. This is:

$$ \left( \begin{array}{cc} 0 & -1 & 0 \\1 & 0 & 0 \\ 0 & 0 & 1 \end{array} \right) $$

Finally we can set up the CSS matrix() function associating the rotation

transform: matrix(0, 1, -1, 0, 0, 0);

In general:

$$ transform: matrix (a, b, c, d, e, f) = \left( \begin{array}{cc} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{array} \right) $$

In case you're wondering why the matrix has nine numbers and the matrix () function only six: you have to realize that the matrix function works only in the two-dimensional plane with the horizontal x-axis and vertical y-axis. The z-values of every point in the XY plane remain the same when operating in the XY plane (meaning any transformation in the xy plane). Therefore the bottom row of the transformation matrix never changes and has no influence on the transformation. Therefore they are not be passed as parameters to the matrix () function.

But what exactly is the benefit of using matrices for transformations?

  • To begin with: all transform functions behind the scenes are making use of matrices, the rotate (), the translate (), the scale () as well as the skew () and of course the matrix () function. However, all these functions are limited because they can only perform a limited amount of transformations. Using matrices, however, you can basically perform all imaginary transformations (such as point-reflections and reflections in angled lines), even those in 3-dimensional spaces, and for the über-geeks among us: in 4.5 .... n-dimensional spaces. This , however, we only come across in theoretical mathematical models, such as in quantum physics. Oaf.... !!
  • Using the new matrices you can determine the x and y position of a shape and its vertices after the transformation.
  • You have a good story for your new boyfriend /girlfriend. If they do not find your professional knowledge interesting, then tell her/him that it does the beautiful gift to be paid!
  • You finally understand the many jokes about matrices at nerd parties!

Example2: transformation of a shape with the matrix function.

Check out the shape in the image below. The four vertices of the rectangle are given by: A(0,0), B(200,0), C(200,80) en D(0,80).

This shape can be associated with the following vectors:

$$ \left( \begin{array}{cc} 0 \\ 0 \\ 1 \end{array} \right) $$$$ \left( \begin{array}{cc} 200 \\ 0 \\ 1 \end{array} \right) $$$$ \left( \begin{array}{cc} 200 \\ 80 \\ 1 \end{array} \right) $$en$$ \left( \begin{array}{cc} 0 \\ 80 \\ 1 \end{array} \right) $$

We want to transform the drawn picture by means of the matrix () function. We do this by multiplying the transformation matrix with each of the above vectors associated with the vertices of the figure. The result of these multiplications provides us with the vectors associated with the vertices of the translated shape (whereby the transform-origin is set to 0 0). With CSS we set the original position and the subsequent transformation using the CSS matrix function:

#transformedObject {
     position: absolute;
     left: 0px;
     top: 0px;
     width: 200px;
     height: 80px;
     transform:  matrix(0.9, -0.05, -0.375, 1.375, 220, 20);
     transform-origin: 0 0;
}

The transformation matrix that goes with all this looks as follows:

$$ \left( \begin{array}{cc} 0.9 & -0.375 & 220 \\ -0.05 & 1.375 & 20 \\ 0 & 0 & 1 \end{array} \right) $$

Now, multiply the transformation matrix with each of the vectors of the vertices of the figure. We start with the point (0,0), then we multiply the vectors of the points B(200.0), C(200.80) and D(0.80)

$$ \left( \begin{array}{cc} 0.9 & -0.375 & 220 \\ -0.05 & 1.375 & 20 \\ 0 & 0 & 1 \end{array} \right) $$.$$ \left( \begin{array}{cc} 0 \\ 0 \\ 1 \end{array} \right) $$=$$ \left( \begin{array}{cc} 0.9 × 0 + -0.375 × 0 + 220×1 \\ -0.05 × 0 + 1.375 × 0 + 20 × 1 \\ 0 × 0 + 0 × 0 + 20 × 1 \end{array} \right) $$=$$ \left( \begin{array}{cc} 220 \\ 20 \\ 1 \end{array} \right) $$
$$ \left( \begin{array}{cc} 0.9 & -0.375 & 220 \\ -0.05 & 1.375 & 20 \\ 0 & 0 & 1 \end{array} \right) $$.$$ \left( \begin{array}{cc} 200 \\ 0 \\ 1 \end{array} \right) $$=$$ \left( \begin{array}{cc} 0.9×200 + -0.375×0 + 220×1 \\ -0.05×200 + 1.375×0 + 20×1 \\ 0×200 + 0×0 + 20×1 \end{array} \right) $$=$$ \left( \begin{array}{cc} 400 \\ 0 \\ 1 \end{array} \right) $$
$$ \left( \begin{array}{cc} 0.9 & -0.375 & 220 \\ -0.05 & 1.375 & 20 \\ 0 & 0 & 1 \end{array} \right) $$.$$ \left( \begin{array}{cc} 200 \\ 80 \\ 1 \end{array} \right) $$=$$ \left( \begin{array}{cc} 0.9×200+-0.375×80+220×1 \\ -0.05×200+1.375×80+20×1 \\ 0×200 + 0×80 + 1×1 \end{array} \right) $$=$$ \left( \begin{array}{cc} 370 \\ 120 \\ 1 \end{array} \right) $$
$$ \left( \begin{array}{cc} 0.9 & -0.375 & 220 \\ -0.05 & 1.375 & 20 \\ 0 & 0 & 1 \end{array} \right) $$.$$ \left( \begin{array}{cc} 0 \\ 80 \\ 1 \end{array} \right) $$=$$ \left( \begin{array}{cc} 0.9×0 + -0.375×80 + 220×1 \\ -0.05×0 + 1.375×80 + 20×1 \\ 0×0 + 0×80 + 20×1 \end{array} \right) $$=$$ \left( \begin{array}{cc} 190 \\ 130 \\ 1 \end{array} \right) $$

Armed with the newly calculated vectors of the transformed vertices , we can draw the transformed shape.

More transformations, more matrices

All other CSS3 transform functions have their own equivalent of matrix notation:

Scale(a)scaleX(x)scaleY(y)
$$ \left( \begin{array}{cc} a & 0 & 0 \\ 0 & a & 0 \\ 0 & 0 & 1 \end{array} \right) $$ $$ \left( \begin{array}{cc} x & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{array} \right) $$ $$ \left( \begin{array}{cc} 1 & 0 & 0 \\ 0 & y & 0 \\ 0 & 0 & 1 \end{array} \right) $$
translateX(x)translateY(y)translate(x,y)
$$ \left( \begin{array}{cc} 1 & 0 & x \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{array} \right) $$ $$ \left( \begin{array}{cc} 1 & 0 & 0 \\ 0 & 1 & y \\ 0 & 0 & 1 \end{array} \right) $$ $$ \left( \begin{array}{cc} 1 & 0 & x \\ 0 & 1 & y \\ 0 & 0 & 1 \end{array} \right) $$
skewX(x)skewY(y)skew(x,y)
$$ \left( \begin{array}{cc} 1 & \tan \left( x \right) & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{array} \right) $$ $$ \left( \begin{array}{cc} 1 & 0 & 0 \\ \tan \left( y \right) & 1 & 0 \\ 0 & 0 & 1 \end{array} \right) $$ $$ \left( \begin{array}{cc} 1 & \tan \left( x \right) & 0 \\ \tan \left( y \right) & 1 & 0 \\ 0 & 0 & 1 \end{array} \right) $$
rotate(θ)
\[ R\left( \theta \right) =\left[ \begin{array}{cc} \cos \left( \theta \right) & -\sin \left( \theta \right) \\ \sin \left( \theta \right) & \cos \left( \theta \right) \end{array} \right] \]
Reflecting
in x-axis
Reflecting
in y-axis
Reflecting in
line y=x
$$ \left( \begin{array}{cc} 1 & 0 & 0 \\ 0 & -1 & 0 \\ 0 & 0 & 1 \end{array} \right) $$ $$ \left( \begin{array}{cc} -1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{array} \right) $$ $$ \left( \begin{array}{cc} 0 & 1 & 0\\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{array} \right) $$

Acknowledgments

  • The MathML that I used in this tutorial for the mathematical equations and matrices, is displayed using the open source Javascript library LaTeXMathML
  • To carry out vector-matrix calculations I used the Sylvester JavaScript library, written by James by Coglan.

Leave a comment