Create Vector Masks using the HTML5 Canvas

The HTML5 canvas can be used to create a lot of cool things, like games, video effects, graphs and more. It can also be used to produce some slightly less complex effects, like manipulating images on the page.

In this post we will look at how to use the canvas tag and clipping to create images that aren’t so rectangular.

Setting up the Canvas

In this example, I am going to be using an image of Ryan, and see if I can modify the shape of it, using the canvas.

First we need a canvas tag in our page

1
<canvas id="c" width="200" height="158"></canvas>

This just sets up a simple canvas with the width and height of our image. I chose these dimensions so that it does not take up any more space than is needed.

Next in JavaScript we will get the canvas and its drawing context in JavaScript

1
2
3
// Grab the Canvas and Drawing Context
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');

So now we are ready to begin drawing our image into the canvas.

Drawing the Image into the Canvas

We have our canvas set up, now we need to draw the image into that canvas. We can do this easily, but we need an HTML img element with our image in order to draw it.

We could grab an <img> tag from our page, but we can do it using JavaScript.

1
2
3
4
5
6
7
8
9
10
// Create an image element
var img = document.createElement('IMG');
 
// When the image is loaded, draw it
img.onload = function () {
    ctx.drawImage(img, 0, 0);
}
 
// Specify the src to load the image
img.src = "http://i.imgur.com/gwlPu.jpg";

Run this code

Here we are creating a new element for our image. Since we can’t draw the image until it has been downloaded, we need to wait for onload to draw it. Inside of the onload listener, we call the ctx.drawImage(), and pass it the img element. We also pass 0, 0 meaning we want to draw 0 pixels from the top and left.

Finally we set the src of our image, which triggers the browser to fetch the image data.

Clip that Image

In the canvas, we can use a technique called clipping. We can use a path we define to specify that future operations should only affect the area within the path.

Since the canvas is transparent, if we create a clipping path, and then draw the image, the image will only show up inside the shape of that path.

So let’s draw a circle, clip to that path, and draw the image.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Create an image element
var img = document.createElement('IMG');
 
// When the image is loaded, draw it
img.onload = function () {
 
    // Save the state, so we can undo the clipping
    ctx.save();
 
    // Create a circle
    ctx.beginPath();
    ctx.arc(106, 77, 74, 0, Math.PI * 2, false);
 
    // Clip to the current path
    ctx.clip();
 
    ctx.drawImage(img, 0, 0);
 
    // Undo the clipping
    ctx.restore();
}
 
// Specify the src to load the image
img.src = "http://i.imgur.com/gwlPu.jpg";

Run this code

You may notice the ctx.save() and ctx.restore() calls. This is because anything we try to do to the canvas after we clip it will only work within the clipping region. We call save() before we clip and then call restore() after, and the state of the canvas will be restored to before the clipping was applied. Everything you drew will remain, but the clipping definition will be gone.

Go Crazy

You can clip to more than just circles. You can clip to any shape you want. You just need to define your path.

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
// Create an image element
var img = document.createElement('IMG');
 
// When the image is loaded, draw it
img.onload = function () {
 
    // Save the state, so we can undo the clipping
    ctx.save();
 
    // Create a shape, of some sort
    ctx.beginPath();
    ctx.moveTo(10, 10);
    ctx.lineTo(100, 30);
    ctx.lineTo(180, 10);
    ctx.lineTo(200, 60);
    ctx.arcTo(180, 70, 120, 0, 10);
    ctx.lineTo(200, 180);
    ctx.lineTo(100, 150);
    ctx.lineTo(70, 180);
    ctx.lineTo(20, 130);
    ctx.lineTo(50, 70);
    ctx.closePath();
    // Clip to the current path
    ctx.clip();
 
    ctx.drawImage(img, 0, 0);
 
    // Undo the clipping
    ctx.restore();
}
 
// Specify the src to load the image
img.src = "http://i.imgur.com/gwlPu.jpg";

Run this code

You can use clipping in combination with other techniques to create some pretty interesting effects. What cool effects can you create?

Treehouse

Our mission is to bring affordable Technology education to people everywhere, in order to help them achieve their dreams and change the world.

Comments

11 comments on “Create Vector Masks using the HTML5 Canvas

  1. although i’m new to html5 your tutorial for creating vector masks using html5 is straight forward and very easy to understand! thanks for sharing Jim

  2. I knew there had to be away to do this. Now all that needs to be done is some anti-aliasing cause those edges could saw a redwood in half. 

  3. Thanks for sharing your ideas and knowledge. I am just starting learning html and though this is already advance for me it is still straight forward. easy to read and understand. Thanks.