Custom Transformation in Canvas: HTML5

Today lets learn how to apply custom transformation to our drawings on canvas.

custom transformation canvas html5

In this video tutorial, we draw 3 rectangles and show you how scale, skew and move properties of custom transform methods work.

Custom Transformation Methods
transform(a, b, c, d, e, f);
setTransform(a, b, c, d, e, f);

custom transformation matrix canvas html5

Custom transformation takes the form of a square matrix, as shown above.

a – Scales drawing horizontally
b – Skews drawing horizontally
c – Skews drawing vertically
d – Scales drawing vertically
e – Moves drawing horizontally
f – Moves drawing vertically

Recommended Read:
Translate Transformation in Canvas: HTML5
Scale Transformation in Canvas: HTML5
Rotate Transformation in Canvas: HTML5

index.html and myStyle.css file content are same as Linear Gradients in Canvas: HTML5

JavaScript file: Transform method
myScript.js

1
2
3
4
5
6
7
context.fillStyle = "blue";
context.fillRect(5, 5, 150, 75);
 
context.transform(1, 0.5, 0.5, 1, 10, 10);
 
context.fillStyle = "red";
context.fillRect(5, 5, 150, 75);

transform() method changes the origin of the canvas to (x, y) = (10, 10) and scale horizontally and vertically, so that we can see it drawn on the canvas. Also skews by 0.5 both horizontally and vertically.

JavaScript file: Transform method is Additive
myScript.js

1
2
3
4
5
6
7
8
9
10
11
12
context.fillStyle = "blue";
context.fillRect(5, 5, 150, 75);
 
context.transform(1, 0.5, 0.5, 1, 10, 10);
 
context.fillStyle = "red";
context.fillRect(5, 5, 150, 75);
 
context.transform(1, 0, 0, 1, 20, 200);
 
context.fillStyle = "gray";
context.fillRect(5, 5, 150, 75);

Using transform() method we draw third rectangle at (x, y) = (20, 200); And horizontal and vertical skew is made 0, but still a skew of 0.5 is applied both in horizontal and vertical direction, since the transform() method written before for second rectangle is influencing it.

JavaScript file: setTransform method is not Additive
myScript.js

1
2
3
4
5
6
7
8
9
10
11
12
context.fillStyle = "blue";
context.fillRect(5, 5, 150, 75);
 
context.transform(1, 0.5, 0.5, 1, 10, 10);
 
context.fillStyle = "red";
context.fillRect(5, 5, 150, 75);
 
context.setTransform(1, -0.5, 0, 1, 20, 200);
 
context.fillStyle = "gray";
context.fillRect(5, 5, 150, 75);

setTransform() method is non-additive in nature. It is independent of its previous transformation matrix. All other parameter and behavior are same with respect to transform() and setTransform() methods.

Custom Transformation in Canvas: HTML5


[youtube https://www.youtube.com/watch?v=9eyr9MQNAuM]

YouTube Link: https://www.youtube.com/watch?v=9eyr9MQNAuM [Watch the Video In Full Screen.]



JavaScript file: Full Free Code
myScript.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
window.onload = canvas;
 
function canvas()
{
var myCanvas = document.getElementById("myCanvas");
 
if( myCanvas && myCanvas.getContext("2d") ) 
{
var context         = myCanvas.getContext("2d");
 
context.fillStyle   = "blue";
context.fillRect(5, 5, 150, 75);
 
context.transform(1, 0.5, 0.5, 1, 10, 10);
 
context.fillStyle   = "red";
context.fillRect(5, 5, 150, 75);
 
context.setTransform(1, -0.5, 0, 1, 20, 200);
 
context.fillStyle   = "gray";
context.fillRect(5, 5, 150, 75);
}
}

Skewing can be done both in positive and negative direction, as shown in the video. If you previously used scale() and/or rotate() transformations that will be additive to transform() method, and will have no influence on setTransform() method.

Rotate Transformation in Canvas: HTML5

Today lets learn about rotate transformation. And also lets see how we can use translate transformation and rotate transformation to create simple animation.

Recommended Read:
Translate Transformation in Canvas: HTML5
Scale Transformation in Canvas: HTML5

rotate transformation canvas html5

Demo

Syntax
rotate(angleInRadians);
The rotate() transformation causes the subsequent drawing operations to be rotated by a given angle. Note that the angles are in radian and not in degrees. Also the rotation takes place around the current origin and not with respect to the center of the object or the element drawn.

index.html and myStyle.css file content are same as Linear Gradients in Canvas: HTML5

JavaScript file: Rotate Transformation On a rectangle
myScript.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
window.onload = canvas;
 
function canvas()
{
var myCanvas = document.getElementById("myCanvas");
 
if( myCanvas && myCanvas.getContext("2d") ) 
{
var context         = myCanvas.getContext("2d");
 
context.fillStyle   = "blue";
                context.fillRect(150, 50, 100, 50);
                context.rotate(0.5);
                context.fillRect(150, 50, 100, 50);
 
}
}

Here we take 2 rectangles with same x and y axis and same width and height. For second rectangle we apply a rotation of 0.5 radians. With this you can see that the rotation takes place with respect to the origin of the canvas, which is (0, 0).

JavaScript file: Rotate Transformation On a Circle
myScript.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
window.onload = canvas;
 
function canvas()
{
var myCanvas = document.getElementById("myCanvas");
 
if( myCanvas && myCanvas.getContext("2d") ) 
{
var context         = myCanvas.getContext("2d");
 
var rdl             = context.createRadialGradient(175, 175, 25, 175, 175, 100);
rdl.addColorStop(0.0, "#f00"); //RED
rdl.addColorStop(0.5, "#00f"); //BLUE
rdl.addColorStop(1.0, "#0f0"); //Green
 
 
setInterval(function(){
context.beginPath();
context.fillStyle  = rdl;
context.arc(175, 175, 100, 0, 2 * Math.PI);
context.fill();
context.translate(175, 175);
context.rotate(2);
}, 50);
 
}
}

Here we draw a radialgradient and rotate it with 2 radians with a time interval of 50 milliseconds. Before we rotate the circle we change the origin of the canvas to 175px x-axis and 175px y-axis, so that the rotation takes place with respect to the point (175, 175).

Rotate Transformation and Animation in Canvas: HTML5


[youtube https://www.youtube.com/watch?v=U3v5J-fOeV0]

YouTube Link: https://www.youtube.com/watch?v=U3v5J-fOeV0 [Watch the Video In Full Screen.]



Note:
We convert degree to radian using a simple mathematical formula:
Radian = (PI / 180 ) * degree;

While developing moving objects in our applications(like online games applications), we need not remember lot of locations/points on the canvas to move our element, instead, we can change the origin of the canvas using translate transformation and move the elements or rotate them!

Scale Transformation in Canvas: HTML5

Today lets learn about scale transformation.

scale-transformation-canvas-html5

Syntax
scale(x, y);
Scales drawing operations by multiples of x and y.

Related read: Translate Transformation in Canvas: HTML5 (important)

index.html and myStyle.css file content are same as Linear Gradients in Canvas: HTML5

JavaScript file: Scale Transformation of 2 rectangles
myScript.js

1
2
3
4
5
6
context.fillStyle  = "red";
context.fillRect(10, 10, 50, 50);
 
context.scale(2, 2);
context.fillStyle  = "blue";
context.fillRect(40, 40, 50, 50);

Here we have 2 rectangles with red and blue color, at two different x, y axis, but with same height and width i.e., 50px each
But using scale() method, we scale the second rectangle by 2. So the second rectangle is drawn at 80px x-axis, 80px y-axis with a width and height of 100px.

JavaScript file: Scale Transformation of 3 rectangels
myScript.js

1
2
3
4
5
6
7
8
9
10
11
12
context.fillStyle  = "red";
context.fillRect(10, 10, 50, 50);
context.save();
 
context.scale(2, 2);
context.fillStyle  = "blue";
context.fillRect(40, 40, 50, 50);
 
context.restore();
context.scale(0.5, 0.5);
context.fillStyle  = "green";
context.fillRect(100, 40, 50, 50);

Here we save the scale value of first rectangle(which is 1,1), and restore it for the third rectangle – using canvas status. If we don’t use canvas status, then the (0.5, 0.5) scale for the third rectangle will be applied with respect to the second rectangle which has a scale of (2, 2). Hence, third rectangle scale will be (1.5, 1.5). As 2.0 – 0.5 = 1.5

JavaScript file: Full Free Code
myScript.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
window.onload = canvas;
 
function canvas()
{
    var myCanvas = document.getElementById("myCanvas");
 
    if( myCanvas && myCanvas.getContext("2d") ) 
    {
var context         = myCanvas.getContext("2d");
context.fillStyle  = "red";
context.fillRect(10, 10, 50, 50);
context.save();
 
context.scale(2, 2);
context.fillStyle  = "blue";
context.fillRect(40, 40, 50, 50);
 
context.restore();
context.scale(0.5, 0.5);
context.fillStyle  = "green";
context.fillRect(100, 40, 50, 50);
    }
}

With save and restore methods applied:
1st rectangle: (1.0, 1.0);
2nd rectangle: (2.0, 2.0);
3rd rectangle: (0.5, 0.5);

Without save and restore methods applied:
1st rectangle: (1.0, 1.0);
2nd rectangle: (2.0, 2.0);
3rd rectangle: (1.5, 1.5);

Scale Transformation in Canvas: HTML5


[youtube https://www.youtube.com/watch?v=kGLYu62ao6Q]

YouTube Link: https://www.youtube.com/watch?v=kGLYu62ao6Q [Watch the Video In Full Screen.]



The scale() transformation causes drawing operations to be multiplied by a given scale factor in the x and y direction.

scale() transformation can be applied to any drawing operation on the canvas, like circles, triangle, images etc.

Translate Transformation in Canvas: HTML5

Transformation are the way objects are drawn on to the canvas. There are 3 transformations.
1. Translate
2. Scale
3. Rotate

..along with a way to define our own free-form transformations.

In this video tutorial, we shall see how to use Translate Transformation.

translate-transformation-canvas-html5

Translate Transformation moves the canvas origin to a new location.

index.html and myStyle.css file content are same as Linear Gradients in Canvas: HTML5

JavaScript file: Translate Transformation
myScript.js

1
2
3
4
5
context.fillStyle = "red";
context.fillRect(0, 0, 75, 75);
 
context.translate(80, 80);
context.fillRect(0, 0, 75, 75);

Here we draw a red color filled Rectangle at 0px x-axis and 0px y-axis, with a width and height of 75px each. Next we call translate method, and change the point of origin of the canvas to 80px x-axis and 80px y-axis. Then we copy paste the same rectangle code with same settings, but this time, the rectangle appears at the new canvas origin i.e., at 80px x-axis and 80px y-axis.

JavaScript file: Full Code
myScript.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
window.onload = canvas;
 
function canvas()
{
var myCanvas = document.getElementById("myCanvas");
 
if( myCanvas && myCanvas.getContext("2d") ) 
{
var context         = myCanvas.getContext("2d");
 
context.shadowColor = "black";
context.shadowBlur  = 20;
 
context.fillStyle   = "red";
context.fillRect(0, 0, 75, 75);
 
context.translate(80, 80);
context.fillRect(0, 0, 75, 75);
 
context.lineWidth   = 2;
context.strokeStyle = "blue";
context.arc(100, 100, 20, 0, 2 * Math.PI);
context.fill();
context.stroke();
}
}

Here we apply shadow effect to 3 elements: 2 rectangles and 1 circle. When we draw circle with (100, 100) as its center, the origin is traced from (80, 80) and not (0, 0), as we draw the arc/circle after calling translate() method.

Translate Transformation in Canvas: HTML5


[youtube https://www.youtube.com/watch?v=vSasdyo69bU]

YouTube Link: https://www.youtube.com/watch?v=vSasdyo69bU [Watch the Video In Full Screen.]



Note: Since all the elements which follow translate method will have a new origin, we can effectively use canvas status and save, restore the status to our advantage.

drawImage() in Canvas: HTML5

Today lets learn in-depth about drawImage() method of HTML5.

Using drawImage() method we can draw a portion or an entire image, fetch a video frame, fetch an image(drawing) from another canvas element. We can grab – re-size, crop etc an image, video or something present on another canvas.

drawImage-method-canvas-html5

drawImage() syntax

Basic:
drawImage(imgSrc, dx, dy);

imgSrc – image soruce.

Top Right Corner Position
dx – destination/main canvas x-axis value.
dy – destination/main canvas y-axis value.

drawImage(imgSrc, dx, dy, dw, dy);

dw – destination width to which the image should fit into. [optional]
dh – destination height to which the image should fit into. [optional]

drawImage(imgSrc, sx, sy, sw, sh, dx, dy, dw, dy);
sx – source image or video or another canvas elements x-axis value. [optional]
sy – source image or video or another canvas elements y-axis value. [optional]

sw – selecting source image or video or another canvas’s width. [optional]
sh – selecting source image or video or another canvas’s height. [optional]

In other words!!

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

sx – The x coördinate where to start clipping(optional).
sy – The y coördinate where to start clipping(optional).
x – The x coördinate where to place the image on the canvas.
y – The y coördinate where to place the image on the canvas.
swidth– The width of the clipped image(optional).
sheight– The height of the clipped image(optional).

stretch or reduce the image
width– The width of the image to use(optional).
height– The height of the image to use(optional) .

HTML file
index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
< !DOCTYPE HTML>
<html>
<head>
<title>Canvas: HTML5</title>
<meta charset="utf-8"/>
<link href="myStyle.css" rel="stylesheet" />
<script src="myScript.js"></script>
</head>
<body>
 <canvas id="myCanvas" width="500" height="300">
  Upgrade Browser
 </canvas>
 
 <canvas id="two" width="50" height="50"></canvas>
 
 <img id="img" src="technotip.jpg" style="display: none;" />
 <video id="video" src="technotip.mp4" style="display: none;"></video>
 
</body>
</html>

Here we have 2 canvas elements. 1 image and 1 video. Image and video are set to display none, so that they’re not shown below or besides the canvas element on the html document. Our main canvas with the id myCanvas has a width of 500px and a height of 300px. This is the canvas on which we draw image by fetching it from an image file or a video frame or another canvas element.

CSS file
myStyle.css

1
2
3
canvas {
border: 2px dotted black;
}

We assign 2px black dotted border to the canvas present on our HTML page.

JavaScript file: Image example
myScript.js

1
2
var myImg = document.getElementById("img");
context.drawImage(myImg, 35, 15, 550, 550, 0, 0, 500, 300);

Fetch the image by its id. Using drawImage() method, we grab a portion of the image and fit display it on the main canvas.

JavaScript file: Fetching video frame
myScript.js

1
2
3
4
5
6
7
8
9
10
11
12
                var myVideo             = document.getElementById("video");
myVideo.play();
 
setInterval(function(){
 
var myCanvas   = document.getElementById("myCanvas");
var context    = myCanvas.getContext("2d");
 
var myVideo    = document.getElementById("video");
context.drawImage(myVideo, 30, 0, 950, 720, 0, 0, 500, 300);
 
}, 3000);

We grab the video using its id. using play() method, we start playing the video automatically. Once the video starts playing, we set the time interval to 3 seconds and for every 3 seconds we grab the current video playback frame and display it on the specified position and in specified width and height of the main canvas.

JavaScript file: Fetching image from another canvas
myScript.js

1
2
3
4
5
6
7
canvas2.arc(25, 25, 25, 0, 2 * Math.PI);
canvas2.fillStyle   = "red";
canvas2.strokeStyle = "blue";
canvas2.fill();
canvas2.stroke();
 
context.drawImage(second, 0, 0, 50, 50, 120, 20, 250, 250);

Here we draw a circle on smaller canvas. And then display it on main canvas by enlarging it.
Related: Draw Arcs/Circle with Canvas: HTML5

JavaScript file: Full Code
myScript.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
window.onload = canvas;
 
function canvas()
{
var myCanvas = document.getElementById("myCanvas");
 
if( myCanvas && myCanvas.getContext("2d") ) 
{
var context          = myCanvas.getContext("2d");
 
 
// var myImg         = document.getElementById("img");
// context.drawImage(myImg, 35, 15, 550, 550, 0, 0, 500, 300);
 
 
 
var second           = document.getElementById("two");
var canvas2          = second.getContext("2d");
 
canvas2.arc(25, 25, 25, 0, 2 * Math.PI);
canvas2.fillStyle    = "red";
canvas2.strokeStyle  = "blue";
canvas2.fill();
canvas2.stroke();
 
context.drawImage(second, 0, 0, 50, 50, 120, 20, 250, 250);
 
 
 
var myVideo          = document.getElementById("video");
myVideo.play();
 
setInterval(function(){
 
var myCanvas = document.getElementById("myCanvas");
var context  = myCanvas.getContext("2d");
 
var myVideo  = document.getElementById("video");
context.drawImage(myVideo, 30, 0, 950, 720, 0, 0, 500, 300);
 
}, 3000);
 
}
}

By changing the x-axis and y-axis values of source and destination, we can change position of the image and we can snatch a particular video frame or a particular part of an image or another canvas element. By using source / destination width and height we can shrink or stretch the image.

drawImage() in Canvas: HTML5


[youtube https://www.youtube.com/watch?v=f9ZjZc1XiFg]

YouTube Link: https://www.youtube.com/watch?v=f9ZjZc1XiFg [Watch the Video In Full Screen.]



drawImage() method will be helpful in building image manipulation and video oriented applications.

Example: You can grab a particular frame image from your video and set it as it’s cover pic! Like YouTube allows video uploader to select a cover image to each video – by default, it’s fetched randomly from the uploaded video file frames.