Matrix transformations made easy.
Imagine a HTML element that may have a CSS transform applied. If we want to add 45° of Z-rotation, we have no way to handle this safely in CSS—we’d just risk overwriting an existing transform. So we decide to use JavaScript, and check the current transform...
getComputedStyle(element)
returns the computed styles, and inspecting the transform
property shows:
'matrix3d(0.707107, 0.707107, 0, 0, -0.707107, 0.707107, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)'
It’s here we discover that browsers actually use transformation matrices under the hood to describe rotation, translation, scale and shear. This means if we wish to manage CSS transforms with JavaScript (without overwriting existing transformations), we’re stuck working with matrices.
Rematrix is an easy way to create and combine matrix transformations that work seamlessly with CSS.
You can paste this snippet for the minified distribution directly into your page:
<script src="https://unpkg.com/rematrix/dist/rematrix.min.js"></script>
This will create the global variable Rematrix
.
npm install rematrix --save
const Rematrix = require('rematrix')
import * as Rematrix from 'rematrix'
Most API methods look a lot like CSS, so for example, in CSS if we would write transform: rotateZ(45deg)
, we can create the same transformation in JavaScript using Rematrix like this:
Rematrix.rotateZ(45)
This returns a 45° rotation along the Z-axis, represented as an array of 16 values:
[0.707107, 0.707107, 0, 0, -0.707107, 0.707107, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
These 16 values represent our transformation matrix in column-major order.
Where Rematrix really outshines CSS, is the ability to combine transforms — using matrix multiplication. We’ll recreate the same 45° rotation along the Z-axis, but using separate matrices this time:
var r1 = Rematrix.rotateZ(20)
var r2 = Rematrix.rotateZ(25)
var product = Rematrix.multiply(r1, r2)
Here product
describes the same array of 16 values (seen above):
[0.707107, 0.707107, 0, 0, -0.707107, 0.707107, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
There’s a good chance we’ll need to multiply quite a few matrices together, so its helpful to store them in an array in order to use Array.prototype.reduce
to multiply them all in one line:
var r1 = Rematrix.rotateZ(20)
var r2 = Rematrix.rotateZ(65)
var r3 = Rematrix.rotateZ(-40)
var product = [r1, r2, r3].reduce(Rematrix.multiply)
Order is very important. For example, rotating 45° along the Z-axis, followed by translating 500 pixels along the Y-axis... is not the same as translating 500 pixels along the Y-axis, followed by rotating 45° along on the Z-axis.
Before applying any of our transforms, we should capture the existing transform of our element using the Rematrix.parse()
method:
var element = document.querySelector('#example')
var style = getComputedStyle(element)['transform']
var transform = Rematrix.parse(style)
var r1 = Rematrix.rotateZ(20)
var r2 = Rematrix.rotateZ(65)
var r3 = Rematrix.rotateZ(-40)
var product = [transform, r1, r2, r3].reduce(Rematrix.multiply)
By passing the computed transform styles to Rematrix.parse()
, we create a matrix of the existing transform. We can now factor this into our multiplication.
The existing transformation has been deliberately placed at the start of the array to ensure the computed transform is the foundation for the succeeding transformations.
We need only to turn our matrix back into a string of CSS:
var css = 'transform: matrix3d(' + product.join(', ') + ');'
From here it’s up to you how to use the CSS, but for simplicity’s sake here, we’ll just apply it inline to our element:
element.setAttribute('style', css)
And that concludes this introduction to Rematrix. Please explore the finished Live Demo on JSFiddle.
- Rematrix
- .format(source)
- .identity()
- .inverse(source)
- .multiply(m, x)
- .parse(source)
- .rotateX(angle)
- .rotateY(angle)
- .rotateZ(angle)
- .scale(scalar, [scalarY])
- .scaleX(scalar)
- .scaleY(scalar)
- .scaleZ(scalar)
- .skew(angleX, [angleY])
- .skewX(angle)
- .skewY(angle)
- .translate(distanceX, [distanceY])
- .translateX(distance)
- .translateY(distance)
- .translateZ(distance)
Transformation matrices in the browser come in two flavors:
matrix
using 6 values (short)matrix3d
using 16 values (long)
This utility follows this conversion guide to expand short form matrices to their equivalent long form.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
source | array |
Accepts both short and long form matrices. |
Returns a matrix representing no transformation. The product of any matrix multiplied by the identity matrix will be the original matrix.
Tip: Similar to how
5 * 1 === 5
, where1
is the identity.
Kind: static method of Rematrix
Returns a matrix describing the inverse transformation of the source matrix. The product of any matrix multiplied by its inverse will be the identity matrix.
Tip: Similar to how
5 * (1/5) === 1
, where1/5
is the inverse.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
source | array |
Accepts both short and long form matrices. |
Returns a 4x4 matrix describing the combined transformations of both arguments.
Note: Order is very important. For example, rotating 45° along the Z-axis, followed by translating 500 pixels along the Y-axis... is not the same as translating 500 pixels along the Y-axis, followed by rotating 45° along on the Z-axis.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
m | array |
Accepts both short and long form matrices. |
x | array |
Accepts both short and long form matrices. |
Attempts to return a 4x4 matrix describing the CSS transform matrix passed in, but will return the identity matrix as a fallback.
Tip: In virtually all cases, this method is used to convert a CSS matrix (retrieved as a string from computed styles) to its equivalent array format.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
source | string |
String containing a valid CSS matrix or matrix3d property. |
Returns a 4x4 matrix describing X-axis rotation.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
angle | number |
Measured in degrees. |
Returns a 4x4 matrix describing Y-axis rotation.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
angle | number |
Measured in degrees. |
Returns a 4x4 matrix describing Z-axis rotation.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
angle | number |
Measured in degrees. |
Returns a 4x4 matrix describing 2D scaling. The first argument is used for both X and Y-axis scaling, unless an optional second argument is provided to explicitly define Y-axis scaling.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
scalar | number |
Decimal multiplier. |
[scalarY] | number |
Decimal multiplier. |
Returns a 4x4 matrix describing X-axis scaling.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
scalar | number |
Decimal multiplier. |
Returns a 4x4 matrix describing Y-axis scaling.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
scalar | number |
Decimal multiplier. |
Returns a 4x4 matrix describing Z-axis scaling.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
scalar | number |
Decimal multiplier. |
Returns a 4x4 matrix describing shear. The first argument defines X-axis shearing, and an optional second argument defines Y-axis shearing.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
angleX | number |
Measured in degrees. |
[angleY] | number |
Measured in degrees. |
Returns a 4x4 matrix describing X-axis shear.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
angle | number |
Measured in degrees. |
Returns a 4x4 matrix describing Y-axis shear.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
angle | number |
Measured in degrees |
Returns a 4x4 matrix describing 2D translation. The first argument defines X-axis translation, and an optional second argument defines Y-axis translation.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
distanceX | number |
Measured in pixels. |
[distanceY] | number |
Measured in pixels. |
Returns a 4x4 matrix describing X-axis translation.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
distance | number |
Measured in pixels. |
Returns a 4x4 matrix describing Y-axis translation.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
distance | number |
Measured in pixels. |
Returns a 4x4 matrix describing Z-axis translation.
Kind: static method of Rematrix
Param | Type | Description |
---|---|---|
distance | number |
Measured in pixels. |