Transformations

The canvas element supports transformations – moving, rotating, scaling.

Moving

The translation is done using the translate() method :

translate(x, y)

The first parameter indicates the offset along the X axis, and the second parameter specifies the offset along the Y axis.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas in HTML5</title>
</head>

<body>
    <canvas id="myCanvas" width="300" height="250" style="background-color:#eee; border:1px solid #ccc;">
        Your browser does not support Canvas
    </canvas>
    <script>
        var canvas = document.getElementById("myCanvas"),
            context = canvas.getContext("2d");

        context.fillStyle = "blue";
        context.fillRect(50, 50, 100, 100);

        context.translate(100, 50); // offset 100px right and 50px down

        context.globalAlpha = 0.5;
        context.fillStyle = "red";
        context.fillRect(50, 50, 100, 100);
    </script>
</body>

</html>
 

Here, two equal rectangles are drawn at the same position: blue and red. However, a move transformation is applied to the red rectangle:

Rotation

To rotate shapes on a canvas, use the rotate() method :

rotate(angle)

The rotation angle in radians relative to the point with coordinates (0, 0) is passed to this method as a parameter.

 
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas in HTML5</title>
</head>

<body>
    <canvas id="myCanvas" width="300" height="250" style="background-color:#eee; border:1px solid #ccc;">
        Your browser does not support Canvas
    </canvas>
    <script>
        var canvas = document.getElementById("myCanvas"),
            context = canvas.getContext("2d");

        context.fillStyle = "blue";
        context.fillRect(50, 50, 100, 100);

        context.rotate(.52);    // rotate 0.52 radians or 30 degrees

        context.globalAlpha = 0.5;
        context.fillStyle = "red";
        context.fillRect(50, 50, 100, 100);
    </script>
</body>

</html>
 

Scaling

To scale shapes, use the scale() method :

scale(xScale, yScale)

The parameter xScale indicates scaling along the X axis, and yScale- along the Y axis.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas in HTML5</title>
</head>

<body>
    <canvas id="myCanvas" width="300" height="250" style="background-color:#eee; border:1px solid #ccc;">
        Your browser does not support Canvas
    </canvas>
    <script>
        var canvas = document.getElementById("myCanvas"),
            context = canvas.getContext("2d");

        context.fillStyle = "blue";
        context.fillRect(30, 30, 100, 100);

        context.scale(1.5, 1.3); // stretching in width by 1.5 times and compression in height by 1.3 times

        context.globalAlpha = 0.5;
        context.fillStyle = "red";
        context.fillRect(50, 30, 100, 100);
    </script>
</body>

</html>
 

Transformation matrix

If necessary, we can apply successively several transformations:

 
ctx.scale(1.5, 1.3);
ctx.translate(100, 150);
ctx.rotate(0.34);

But the context of the canvas element also provides a transform() method that allows you to set the transformation matrix:

transform(a, b, c, d, e, f)

All parameters of this method sequentially represent the elements of the transformation matrix:

  • a: X-axis scaling
  • b: rotate around the x-axis
  • c: rotate around the y-axis
  • d: Y-axis scaling
  • e: horizontal offset
  • f: vertical offset

For example:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas in HTML5</title>
</head>

<body>
    <canvas id="myCanvas" width="300" height="250" style="background-color:#eee; border:1px solid #ccc;">
        Your browser does not support Canvas
    </canvas>
    <script>
        var canvas = document.getElementById("myCanvas"),
            context = canvas.getContext("2d");

        context.fillStyle = "blue";
        context.fillRect(100, 50, 100, 100);

        context.transform(
            Math.cos(Math.PI / 6), Math.sin(Math.PI / 6), -1 * Math.sin(Math.PI / 6),
            Math.cos(Math.PI / 6), 0, 0);

        context.globalAlpha = 0.5;
        context.fillStyle = "red";
        context.fillRect(100, 50, 100, 100);

    </script>
</body>

</html>
 

Substitution transformations

When you successively apply different transformations, they are simply applied sequentially to the shapes. However, a situation may arise when it is necessary to apply the transformation not together with others, but instead of others, that is, to replace the transformation. To do this, use the setTransform() method :

setTransform(a, b, c, d, e, f)

Its parameters represent the transformation matrix, and in general its application is similar to that of the transform(). For example:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas in HTML5</title>
</head>

<body>
    <canvas id="myCanvas" width="300" height="250" style="background-color:#eee; border:1px solid #ccc;">
        Your browser does not support Canvas
    </canvas>
    <script>
        var canvas = document.getElementById("myCanvas"),
            context = canvas.getContext("2d");
        var k = 0;
        for (var x = 0; x < 30; x++) {
            k = Math.floor(255 / 34 * x);
            context.fillStyle = "rgb(" + k + "," + k + "," + k + ")";
            context.fillRect(50, 50, 200, 100);
            context.setTransform(1, 0, 0, 1, x, x);
        }

    </script>
</body>

</html>
 

Reset transformations

When applying transformations, all subsequent drawing of figures is subjected to these transformations. But a situation is possible when, after a single application of the transformation, we no longer need to apply it. And for all subsequent rendering, we can reset the transformations using the method:


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas in HTML5</title>
</head>

<body>
    <canvas id="myCanvas" width="300" height="250" style="background-color:#eee; border:1px solid #ccc;">
        Your browser does not support Canvas
    </canvas>
    <script>
        var canvas = document.getElementById("myCanvas"),
            context = canvas.getContext("2d");

        context.fillStyle = "blue";
        context.fillRect(50, 50, 100, 100);

        context.translate(100, 50);
        // then the transformation is applied
        context.globalAlpha = 0.5;
        context.fillStyle = "red";
        context.fillRect(50, 50, 100, 100);

        context.resetTransform();
        // the transformation is no longer applied
        context.fillStyle = "green";
        context.fillRect(0, 0, 100, 100);

    </script>
</body>

</html>