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:
fillStyle
: Sets the colour of whatever you decide to draw. In this case we are using an rgba value that defines a semi-transparent blue. the first three arguments inside the brackets are the amount of red, green and blue you want in your colour (values between 0 and 255), and the third value sets how transparent the colour is (values between 0 and 1).fillRect
: Sets the size and position of the rectangle. The first two arguments set the X and Y position of the top left hand corner of the rectangle, in this case the top left hand corner of the canvas, which is (0,0). The third and fourth arguments set the width and height of the rectangle, in pixels.
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.
- 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 ofi
: - Start
i
and the square values bigger and use a minus iterator to make the square smaller each time:i--
instead ofi++
. But remember to alter the exit condition too, so you don't end up with an infinite loop! - Increase the value of the exit condition so the loop draws more squares.
- Make the iterator itself bigger so the loop draws the squares further apart, for example
i+=5
, which is equivalent toi = i + 5
— "take the existing value of i and add 5 to it". - Define the square colour inside the loop and modify it by i too, for example:
- 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 multiplyingi
by 6 then adding 50, followed by a string of",0.5)"
. - 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.
myContext.fillRect((i*6),(i*4),25+(i*10),25+(i*10));
myContext.fillStyle = 'rgba(0,0,' + (150+(i*6)) + ',0.15)';
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.
This work is licensed under a Creative Commons Attribution 4.0 International License. Share it, make it better, use it for good.