Introduction to programming

Have fun drawing: HTML5 canvas basics

One of the best way to see instant results with JavaScript is by writing some simple HTML5 <canvas> examples. Canvas is a technology that allows you to use JavaScript to draw a bitmap image, which can then be manipulated/changed.

To do something with a canvas, you first have create one on your HTML page, like putting a picture frame on your wall.

Getting started

Make a new copy of the template file. Add the following to your HTML area:

<canvas width="500" height="500">
</canvas>

<!-- Create a canvas to draw on, 500 x 500 big.
     Note that HTML comments look different to
     JavaScript comments! -->

This creates a blank canvas 500 x 500 pixels big, ready for you to draw on.

To grab a reference to this canvas, we need to add two lines to our JavaScript area:

var myCanvas = document.querySelector('canvas');
// Grab a reference to the canvas element

var myContext = myCanvas.getContext('2d');
// Create the context we will draw in

First of all we store a reference to the Canvas inside the myCanvas variable, in the same way as we saw above. Then we create a drawing context for our canvas, inside a myContext variable. Why did this take two steps? Well, 2d is not the only context you can draw in using canvas. There is also an experimental WebGL (3D context) that allows you to draw things into real 3D space, but we won't touch that here because it's way too complicated!

Next, let's draw a simple rectangle on our canvas — add these lines to the bottom of the JavaScript area:

myContext.fillStyle = 'rgba(0,0,255,0.5)';
// What colour do we want to draw the rectangle?

myContext.fillRect(0,0,200,200);
// Draw the rectangle itself

Note: You can see this basic example running live in our Basic canvas page.

These two in-built functions are doing the following:

Have a play with drawing different rectangles and squares; adjust the values to see what happens. Try playing with these too:

myContext.strokeStyle = 'rgba(0,255,0,0.5)';
// Set a colour for the stroke, which is the outer
//bound of the rectangle. 

myContext.lineWidth = 1;
// How thick do we want the stroke to be?

myContext.strokeRect(200,200,50,50);
// Draw an outline rectangle, not a solid colour
//rectangle like before

Canvas loops

Lets look at some more complex loop examples with canvas. Type in the following, at the bottom of your JavaScipt area:

myContext.fillStyle = 'rgba(0,0,255,0.15)';
for(i = 0; i <= 9; i++) {
// start with variable i having the value 0. Run the loop
// over and over again until i equals 9, increasing the value
// of i by 1 after each time
  myContext.fillRect(i,i,25+i,25+i);  
}

Here we are setting a specific colour, then running a loop 10 times. Each time we run the loop, we draw a square that is slightly bigger, in a slightly different place. You can use this as a template for your experimentations in the next section (see Canvas loop for the example running live.)

Exercise: hacking your canvas loops

Let's try altering some of the code to make different effects.

  1. Altering some other values of the square each time to loop runs by modifying them by i. For example, you could make the square bigger each time, by modifying the size by a multiple of i:
  2. myContext.fillRect((i*6),(i*4),25+(i*10),25+(i*10));
  3. Start i and the square values bigger and use a minus iterator to make the square smaller each time: i-- instead of i++. But remember to alter the exit condition too, so you don't end up with an infinite loop!
  4. Increase the value of the exit condition so the loop draws more squares.
  5. Make the iterator itself bigger so the loop draws the squares further apart, for example i+=5, which is equivalent to i = i + 5 — "take the existing value of i and add 5 to it".
  6. Define the square colour inside the loop and modify it by i too, for example:
  7. myContext.fillStyle = 'rgba(0,0,' + (150+(i*6)) + ',0.15)';
  8. Ok, so that looks quote horrible. the colour value is actually passed in as a string, so to construct the final string we want to pass in we've had to concatenate (glue together) a string of "rgba(0,0,", followed by the blue value created by multiplying i by 6 then adding 50, followed by a string of ",0.5)".
  9. You could also try using random values; Try using say Math.floor(Math.random()*200) for one or more of the RGB colour values, for example.

Advanced loop ideas

How about rotating the squares? Canvas has a built-in rotate function, which unhelpfully takes a rotation value in radians. Just try playing with really small values; for example, try adding this at the bottom of your for loop (just before the closing curly brace (})):

myContext.rotate(0.025);

How about trigonometry? How about a sine wave of squares? Try something like this:

for(i=0;i<=60;i++) {
  myContext.fillRect((i*5),(250+(Math.sin(i/6))*50),10,10);  
}

Or how about replacing our square with a circle? You can draw a circle using the arc() function, but this is a bit more complicated than before. To draw a circle you need to tell canvas to begin the drawing path with beginPath(), and then draw the circle using fill() (or stroke(), if you only want an outline circle; you'd have to use strokeStyle() to set the stroke colour in this case, not fillStyle()):

var myCanvas = document.getElementById('myCanvas');
var myContext = myCanvas.getContext('2d');

for(i=0;i<=100;i++) {
  myContext.fillStyle = 'rgba(0,0,'
    + (Math.floor(Math.random()*200)) + ',0.15)';
  myContext.beginPath();
  myContext.arc((i*5),(250+(Math.sin(i/6))*50),10,0,Math.PI*2,true);
  myContext.fill();
}

This is where programming starts to get fun. The possibilities really are endless! Let's create something interesting, and save it for later use.


Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License. Share it, make it better, use it for good.