This topic is only intended for students who are up-to-date. You must complete Topics 1-4, and 6-8,before you attempt this.
The canvas tag allows you to draw 2D graphics in the browser. It has only been available for the past 10 years or so of web development. It was not available in the first 10 to 15 years of the web; at that time people had to rely on proprietary third-party plugins such as Flash which were awkward to install and keep up to date.
It allows you to draw shapes such as lines, rectangles, circles, polygons and curves - as well as text - within the browser. This opens up a number of possibilities including in-browser drawing applications or even games.
Note that to allow you time to do practical work, I will not go through all of these notes in detail. However they are there for you to read.
Simply add a <canvas> tag to your HTML and give it an ID, a width and a height (specify the width and height here, and not in the CSS, otherwise the drawing functions will not work correctly) e.g.:
<canvas id='canvas1' width='500' height='500'></canvas>
You use JavaScript to actually draw on the canvas. Here is a short example which draws a red rectangle. This example only will show the full HTML as well as the JavaScript, but subsequent examples will show the JavaScript only as the HTML remains the same:
<html> <head> <script type='text/javascript' src='canvas.js> </script> </head> <body onload='init()'> <canvas id='canvas1' width='400' height='400'></canvas> </body> </html>JavaScript:
function init() { var canvas = document.getElementById('canvas1'); var ctx = canvas.getContext('2d'); ctx.fillStyle = '#ff0000'; // red ctx.fillRect(10,10,100,100); }What we do in this script is as follows:
var canvas = document.getElementById('canvas1');This gets hold of the canvas element using the DOM.
var ctx = canvas.getContext('2d');This line obtains a drawing context from the canvas. The drawing context is an object we use to draw on the canvas.
ctx.fillStyle = '#ff0000'; // red ctx.fillRect(10,10,100,100);These lines set the fill colour to red and draw a red rectangle at x=10, y=10 of width 100 and height 100 pixels. Here is another example which shows an outline-only, non-filled-in rectangle:
function init() { var canvas = document.getElementById('canvas1'); var ctx = canvas.getContext('2d'); ctx.strokeStyle = '#0000ff'; // blue ctx.strokeRect(10,10,100,100); }Note how this example sets the stroke (i.e. line drawing) colour instead of the fill colour, and draws an outlined rectangle with strokeRect().
We can draw polygons and multi-point lines by creating a path. Here is an example:
function init() { var canvas = document.getElementById('canvas1'); var ctx = canvas.getContext('2d'); ctx.strokeStyle = '#0000ff'; // blue ctx.beginPath(); ctx.moveTo(100,100); ctx.lineTo(150,100); ctx.lineTo(150,150); ctx.stroke(); }Here is an explanation of the new functions:
We could turn it into a polygon, rather than a line, with the addition of the following line immediately before the ctx.stroke():
ctx.closePath();This line effectively "closes the loop".
We could also draw a filled polygon by substituting ctx.stroke() with ctx.fill().
Here is an example which draws text.
function init() { var canvas = document.getElementById('canvas1'); var ctx = canvas.getContext('2d'); ctx.font = '12pt Helvetica'; ctx.fillText('Hello', 300, 300); }This should hopefully be obvious: the font is set to 12pt Helvetica and then the text 'Hello' is drawn at x=300, y=300.
This example draws images. (see here).
function init() { var canvas = document.getElementById('canvas1'); var ctx = canvas.getContext('2d'); var image = new Image(); image.src = "http://server.com/images/hero.png"; image.addEventListener("load", () => { ctx.drawImage(image, 100, 100); }); }Note how we create a new Image object, set its src property to the location of the image on the server, and then draw the image at a given x and y position. Note the image.addEventListener("load", ...) which links to an arrow function which actually draws the image. Why are we doing this? Loading an image from the web might take time, so writing our code this way ensures that the image will only be drawn once it's been loaded.
We can also draw circles, here is an example:
function init() { var canvas = document.getElementById('canvas1'); var ctx = canvas.getContext('2d'); ctx.strokeStyle = '#0000ff'; // blue ctx.beginPath(); ctx.arc(100, 100, 50, 0, Math.PI*2, false); ctx.stroke(); }The 6 parameters to arc() need to be explained as many are not obvious. The reason why there are so many is because the function can be used to draw arcs as well as circles. Here is the explanation:
As we have already seen, event handling is a common technique in client-side web development. An event typically occurs when the user interacts with a page in some way, such as clicking a button or moving the mouse over a div. We have already seen some examples of events with map click events and button click events; indeed events can be classed in the general sense as things that happen outside the main flow of the program, in other words they require asynchronous code. Receiving an AJAX response, or obtaining a GPS signal, are other examples of events. We write callback functions to handle the various types of event; these callback functions are known as event handlers.
The modern way of linking an event to its handler is via the addEventListener() method, which you have already seen. This takes two arguments, the event type and the event handler function. For example:
element.addEventListener("eventtype", eventHandler);For example, to handle a click event we would say:
element.addEventListener("click", eventHandler);where eventHandler is a function which runs when the user clicks on the given element.
In the event handler we need to find out information about the event. Useful information about the event might include:
// init() runs when the page first loads function init() { // Obtain an element var canvas1 = document.getElementById("canvas1"); // Handle mouse down, mouse move and mouse up events // The mouseDownHandler function will handle mouse presses canvas1.addEventListener ("mousedown", mouseDownHandler); // The mouseMoveHandler function will handle mouse movement canvas1.addEventListener ("mousemove", mouseMoveHandler); // The mouseUpHandler function will handle mouse release canvas1.addEventListener ("mouseup", mouseUpHandler); } function mouseDownHandler(e) { console.log(`mouse pressed down at local coordinates: ${e.offsetX}, ${e.offsetY}`); } function mouseMoveHandler(e) { console.log(`mouse moved at local coordinates: ${e.offsetX}, ${e.offsetY}`); } function mouseUpHandler(e) { console.log(`mouse released at local coordinates: ${e.offsetX}, ${e.offsetY}`); }Note how the three event handlers, mouseDown(), mouseMove() and mouseUp() all have one parameter, e, which is the event object. This example uses two properties of the event object, offsetX and offsetY, which represent the current x and y position of the mouse with respect to the element it is currently over (e.g. a canvas).
Other properties of the event object include: