LearnCreate Vector Masks using the HTML5 Canvas

Treehouse
writes on July 13, 2011

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

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

// 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.

// 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.

// 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.

// 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?

11 Responses to “Create Vector Masks using the HTML5 Canvas”

  1. nuriales on July 11, 2013 at 4:30 am said:

    Is it possible to create a responsive mask form ?

  2. CanvasBoy on May 24, 2013 at 6:03 pm said:

    I don’t know, what exactly do you mean by “everything I’ve seen”, but here’s a link for you: http://net.tutsplus.com/articles/web-roundups/21-ridiculously-impressive-html5-canvas-experiments/

  3. renkani on August 4, 2011 at 11:17 am said:

    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.

  4. O 3 S 3 R / 3 R on July 18, 2011 at 1:43 am said:

    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. 

  5. kkatusic on July 16, 2011 at 10:33 am said:

    Can we use canvas element in email? Would it be blocked from e.g. google?

  6. Pretty great!  I have actually been looking for more canvas drawing information in order to use it in tandem with some or our site animations.  Great stuff!

  7. 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

  8. Brihon Dermo on July 13, 2011 at 6:01 pm said:

    Thanks. It was a great article. I specially liked the Go Crazy part. New waves of technologies come and they all are useful. See Timing Control for Script Based Animations for example. It’s a great new feature that can help HTML5 Canva.

Leave a Reply

You must be logged in to post a comment.

Learn to code with Treehouse

Start your 7 day free trial today and get access to hundreds of video courses in web development, design and business!

Learn more