LearnCreate 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. // Grab the Canvas and Drawing Context
  2. var canvas = document.getElementById('c');
  3. 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. // Create an image element
  2. var img = document.createElement('IMG');
  4. // When the image is loaded, draw it
  5. img.onload = function () {
  6.     ctx.drawImage(img, 0, 0);
  7. }
  9. // Specify the src to load the image
  10. 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. // Create an image element
  2. var img = document.createElement('IMG');
  4. // When the image is loaded, draw it
  5. img.onload = function () {
  7.     // Save the state, so we can undo the clipping
  8.     ctx.save();
  10.     // Create a circle
  11.     ctx.beginPath();
  12.     ctx.arc(106, 77, 74, 0, Math.PI * 2, false);
  14.     // Clip to the current path
  15.     ctx.clip();
  17.     ctx.drawImage(img, 0, 0);
  19.     // Undo the clipping
  20.     ctx.restore();
  21. }
  23. // Specify the src to load the image
  24. 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. // Create an image element
  2. var img = document.createElement('IMG');
  4. // When the image is loaded, draw it
  5. img.onload = function () {
  7.     // Save the state, so we can undo the clipping
  8.     ctx.save();
  10.     // Create a shape, of some sort
  11.     ctx.beginPath();
  12.     ctx.moveTo(10, 10);
  13.     ctx.lineTo(100, 30);
  14.     ctx.lineTo(180, 10);
  15.     ctx.lineTo(200, 60);
  16.     ctx.arcTo(180, 70, 120, 0, 10);
  17.     ctx.lineTo(200, 180);
  18.     ctx.lineTo(100, 150);
  19.     ctx.lineTo(70, 180);
  20.     ctx.lineTo(20, 130);
  21.     ctx.lineTo(50, 70);
  22.     ctx.closePath();
  23.     // Clip to the current path
  24.     ctx.clip();
  26.     ctx.drawImage(img, 0, 0);
  28.     // Undo the clipping
  29.     ctx.restore();
  30. }
  32. // Specify the src to load the image
  33. 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. 

    • Jim Hoskins on July 21, 2011 at 8:57 pm said:

      Currently anitaliasing is really up to the browser that renders it. Not much you can do about it

  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. Peter Riley Osborne on July 14, 2011 at 3:04 pm said:

    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. JustWordpress on July 13, 2011 at 7:15 pm said:

    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

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