# SVG Transformation

Jakob Jenkov |

It is possible to transform the shapes created in an SVG image. For instance move, scale and rotate the shapes. This is a handy way of displaying vertical or diagonal text.

## Transformation Example

Here is a simple example:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <rect x="50" y="50" height="110" width="110" style="stroke:#ff0000; fill: #ccccff"transform="translate(30) rotate(45 50 50)"> </rect> <text x="70" y="100"transform="translate(30) rotate(45 50 50)">Hello World</text> </svg>

Here is the resulting image:

Notice the `transform`

attribute of the `<rect>`

and `<text>`

elements.
The `transform`

attribute specifies what transformations to apply to the shapes. In this example a
translation and rotation was applied. Both will be explained later in this text.

## What Elements Can Be Transformed?

You can apply transformation to all SVG shapes. You can also apply transformation to the `<g>`

element, thus effectively transforming a whole group of elements in one go. It is also possible to transform
gradients and fill patterns.

## Transformation Functions

SVG provides four transformation functions:

- translate()
- rotate()
- scale()
- skew()
- matrix()

Each of these functions will be explained in more detail in the following sections.

Actually, the transformation functions do not transform the SVG shape themselves, but the underlying coordinate system of that shape. Thus, a shape with a width of 20 scaled up by a factor of 2, still has a width of 20 logically, even though it is displayed in double size.

## Translate

The `translate()`

function moves a shape. You pass the `x`

and `y`

value to the `translate()`

function inside the parameters. Here is an example:

translate(50,25)

This example moves a shape 50 units along the x-axis and 25 units along the y-axis.

Here is an example showing two equally positioned and sized shapes with and without translation:

<rect x="20" y="20" width="50" height="50" style="fill: #cc3333"/> <rect x="20" y="20" width="50" height="50" style="fill: #3333cc"transform="translate(75,25)"/>

Here is the resulting image:

Notice how the second (blue) shape is moved 75 units along the x-axis and 25 units along the y-axis compared to the first (red) shape.

## Rotate

The `rotate()`

function rotates a shape around the point 0,0.
Here is an example showing a rectangle (outline), and an equal rectangle
(filled) after a rotation of 15 degrees:

<rect x="20" y="20" width="40" height="40" style="stroke: #3333cc; fill:none;" /> <rect x="20" y="20" width="40" height="40" style="fill: #3333cc" transform="rotate(15)" />

Here is the resulting image:

If you want to rotate around a different point than 0,0 then pass the x and y coordinates of that
point to the `transform`

function. Here is an example that shows a non-rotated rectangle
(outline) and an equal rectangle (filled) rotated 15 degrees around its own center:

<rect x="20" y="20" width="40" height="40" style="stroke: #3333cc; fill:none;" /> <rect x="20" y="20" width="40" height="40" style="fill: #3333cc" transform="rotate(15, 40, 40)" />

Here is the resulting image:

All rotation is clock-wise with a number of degrees going from 0 to 360.
If you want to rotate counter-clock-wise, pass a negative number of degrees to the `rotate()`

function.

## Scale

The `scale()`

function scales a shape up or down in size. The `scale()`

function
scales both the shapes dimensions and its position coordinates. Thus, a rectangle positioned at
10,10 with a width of 20 and a height of 30, scaled by a factor of 2 will appear at 20,20 with a width
of 40 and a height of 60.

The `scale()`

function also scales the stroke width of a shape.

Here is an example that shows a rectangle (blue) positioned at 10,0 with a width of 20 and a height of 20, and an equal rectangle (black) which is scaled by a factor of 2:

<rect x="10" y="10" width="20" height="30" style="stroke: #3333cc; fill:none;" /> <rect x="10" y="10" width="20" height="30" style="stroke: #000000; fill:none;"transform="scale(2)" />

Here is the resulting image:

Notice how both the position and size of the rectangles are scaled.

You can scale a shape by a different factor on the x-axis and y-axis. You do so by providing
both an x-scale and y-scale parameter to the `scale()`

function, like this:

scale(2,3);

This example would scale the shape by a factor of 2 along the x-axis, and a factor of 3 along the y-axis. Here is an example of that:

<rect x="10" y="10" width="20" height="30" style="stroke: #3333cc; fill:none;" /> <rect x="10" y="10" width="20" height="30" style="stroke: #000000; fill:none;"transform="scale(2,3)" />

Here is the resulting image:

Notice how the stroke width of the scaled rectangle (black) is also scaled, and scaled differently on the x-axis and y-axis.

### Scale as Mirror Function

You can use the `scale()`

function as a mirror function by scaling by -1 along either
the x-axis or y-axis. When you do, you have to first move (translate) the shape in the x or y direction,
or the mirrored shape will appear outside the SVG canvas.

Here is an example:

<path d="M20,20 l20,20 l0,20 l-20,20 Z" style="stroke: #3333cc; fill:none;" /> <path d="M20,20 l20,20 l0,20 l-20,20 Z" style="stroke: #000000; fill:none;" transform="translate(100, 0) scale(-1, 1) " />

Here is the resulting image with a line drawn at x=100 (because the rectangle is translated 100 in the x direction).

The blue shape is the original. The black shape is the translated, scaled shape.

## Skew

The `skewX()`

and `skewY()`

functions skew the x-axis and y-axis. Actually,
the functions skew the given axis according to a certain angle specified in degrees.

Here are a few examples of rectangles shown with different `skewX()`

values.

<rect x="10" y="10" width="20" height="30" style="stroke: #3333cc; fill:none;" /> <rect x="50" y="10" width="20" height="30" style="stroke: #000000; fill:none;" transform="skewX(10)" /> <rect x="100" y="10" width="20" height="30" style="stroke: #000000; fill:none;" transform="skewX(45)" /> <rect x="150" y="10" width="20" height="30" style="stroke: #000000; fill:none;" transform="skewX(60)" />

Here is the resulting image:

As you can see, the `skewX()`

function makes the vertical lines look like they were rotated
by the given angle. Accordingly, the `skewY()`

function makes the horizontal lines look like
they were rotated by the given angle. Here are a few examples:

<rect x="10" y="10" width="20" height="30" style="stroke: #3333cc; fill:none;" /> <rect x="50" y="10" width="20" height="30" style="stroke: #000000; fill:none;" transform="skewY(60)" /> <rect x="100" y="10" width="20" height="30" style="stroke: #000000; fill:none;" transform="skewY(45)" /> <rect x="150" y="10" width="20" height="30" style="stroke: #000000; fill:none;" transform="skewY(10)" />

## Matrix

It is possible to express transformations as a matrix too. The matrix looks like this:

a c e b d f 0 0 1

Since only the first 6 values can be specified, you only provide 6 values to the matrix transformation function. Here is an example:

transform="matrix(a,b,c,d,e,f)"

The other transformation functions can be expressed as matrices. Here are some examples:

Translate 1 0 tx 0 1 ty 0 0 1 matrix(1,0,0,1,tx,ty)

Rotate cos(a) -sin(a) 0 sin(a) cos(a) 0 0 0 1 matrix( cos(a), sin(a),-sin(a),cos(a),0,0 )

Note: the values for `cos(a)`

and `sin(a)`

have to be precomputed before
being inserted into the matrix. The parameter `a`

is the angle to rotate.

Scale sx 0 0 0 sy 0 0 0 1 matrix(sx,0,0,sy,0,0)

A skew transformation along the x-axis can be written as:

Skew 1 tan(a) 0 0 1 0 0 0 1 matrix(1,0,tan(a),1,0,0)

The `tan(a)`

value has to be precomputed before being inserted into
the `matrix()`

function.

A skew transformation along the y-axis can be written as:

Skew 1 0 0 tan(a) 1 0 0 0 1 matrix(1,tan(a),0,1,0,0)

Here is an SVG matrix transformation example which mimics a simple translate function:

<rect x="20" y="20" width="50" height="50" style="fill: #cc3333"/> <rect x="20" y="20" width="50" height="50" style="fill: #3333cc" transform="matrix(1,0,0,1,100,20)" />

Here is the resulting image:

Notice how the right rectangle (blue) is translated compared to the left (red) rectangle.

## Combining Transformations

It is possible to combine transformations. You do so by putting multiple transformation functions
inside the `transform`

attribute.

Here is an example that first translates (moves) and then rotates a rectangle. The example shows both the retangle (blue) before any transformation is applied, and after (black).

<rect x="50" y="10" width="20" height="30" style="stroke: #3333cc; fill:none;" /> <rect x="50" y="10" width="20" height="30" style="stroke: #000000; fill:none;" transform="translate(50,0) rotate(30)" />

Here is the resulting image:

### The Sequence of Transformations Matter

The sequence of transformations matter. The sequence the transformation functions are specified
inside the `transform`

attribute is the sequence they are applied to the shape.

Here is an example that illustrates the difference between translating first and then rotating, and rotating first and then translating the shape:

<rect x="50" y="10" width="20" height="30" style="stroke: #000000; stroke-width: 2px; fill:none;" /> <rect x="50" y="10" width="20" height="30" style="stroke: #3333cc; stroke-width: 2px; fill:none;" transform="translate(100,0) rotate(45)" /> <rect x="50" y="10" width="20" height="30" style="stroke: #cc3333; stroke-width: 2px; fill:none;" transform="rotate(45) translate(100,0)" />

Here is the resulting image:

The black rectangle has no transformation applied. The blue rectangle is first translated, then rotated. The red rectangle is first rotated, then translated.

Tweet | |

Jakob Jenkov |