In this section we will look at how to implement the HTML5 Canvas tag to create a GUI (Graphic User Interface), along with the audio tag to create full fledged applications on the browser. This opens us up to many new interesting opportunities such as making games.
The HTML5 Canvas tag is a rectangular element that we can draw on using JavaScript, with it we can make a varaity of things such as : graphs, animations, images, etc. Here is the setup:
<canvas id="myCanvas" width="100" height="100">
And our canvas is created:
As you can see the canvas is transparent, the canvas tag can have CSS applied to it like all other elements. It's very common to place a border around the canvas or center it:
CSS:
canvas{ border: 1px solid black; // Place border around canvas display: block; // change to block-level so we can margin. margin: auto; // center canvas horizontally }
The Canvas uses a cartesian coordinate system such that (0,0) is the top left, (width, 0) is top right, (width, height) is bottom right, and (0, height) is bottom left.
In order to draw on the Canvas we need to get it and it's context:
var canvas = document.getElementById("myCanvas"); // The HTML canvas element var ctx = canvas.getContext("2d"); // ctx (context) is the 2d drawing context of the canvas.
The context objects has a varaity of methods and properties to use for drawing on the canvas, here are some common ones:
Code that produces Canvas drawings:
var canvas = document.getElementById("myCanvas3"); // Canvas element var ctx = canvas.getContext("2d"); // Canvas context. ctx.fillRect(20,20,30,30); // Draw filled Rect ctx.strokeRect(105,20,30,30); // Draw outlined Rect ctx.beginPath(); // Draw Lines ctx.moveTo(170,20); ctx.lineTo(200,30); ctx.lineTo(190,10); ctx.stroke(); ctx.beginPath(); // Draw lines ctx.moveTo(250,20); ctx.lineTo(280,30); ctx.lineTo(270,10); ctx.closePath(); // Close path ctx.fill(); // Fill-in closed path ctx.beginPath(); ctx.arc(370,38,20,0,Math.PI*2); // Draw circle ctx.stroke(); ctx.font = "28px Arial"; // Set font to 28px ctx.fillText("Hello",10,100) // Draw filled text "Hello" ctx.strokeText("Hello",90,100) // Draw outlined text "Hello" ctx.font = "8px Arial"; ctx.fillText('A',177,90); // Draw text 'A' with 8px size ctx.font = "30px Arial"; ctx.fillText('A',170,120); // Draw text 'A' with 30px size ctx.fillStyle = "#FF0000"; // Set fills to be red ctx.fillRect(280,80,30,30); // Draw red rect var crate = new Image(); // Create Image crate.src = 'crate.png'; // Set Image source crate.onload = function(){ // Draw Image when it loads ctx.drawImage(crate, 348, 70, 45, 45); };
A static canvas is nice, although often we will want to make it more dynamic. For animation we will want a way to update the canvas, we will look into how to redraw to the canvas and using timers and events to do so. Now lets look exactly what is going on by updating the canvas.
Here is a common process on how we do this:
Here is a basic example of a moving box. While simple we will be doing the same thing for all our programs, so be sure you understand this example well:
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = "#FF0000"; var myBox = new Box(10,10,30); // x = 10 y = 50 size = 30 function main() { // * Clear the Canvas ctx.clearRect(0,0,canvas.width,canvas.height); // * Update Items // If our box hits the sides of the canvas reverse it's direction. if(myBox.x > canvas.width - myBox.size || myBox.x < 0) myBox.vel = -myBox.vel; myBox.moveX(); // * Draw Items myBox.draw(); } function Box(x, y, size) { this.x = x; this.y = y; this.size = size; this.vel = 3; // speed and direction for our box this.moveX = function() { this.x += this.vel; } this.draw = function() { ctx.fillRect(this.x, this.y, this.size, this.size); } } setInterval(function(){main()}, 30); // Call main every 30 milliseconds
Feel free to experiment and see what you can do with this, perhaps make it move and reflex in with the X and Y directions. HERE is the code.
In this program we are first creating a Box object. We give it: x and y for it's position, size for how big it is, and vel for how fast it moves. The two methods this Box object has is draw(), which draws the box to the canvas, and moveX(), which changes our x position base on our vel. For the main() function we are performing 3 steps: clearing, updating, and drawing. For clearing we simply paint the screen white. Next for updating we are first checking if our box is past the canvas side edges, if it is then we change the direction of our box. Then we move our box by vel(3) pixels. Finally for drawing we simple draw the box to the canvas. Note if we had more then one box we would need to go though them and draw each one (we could for example use an aray for that).
For this section we will be looking into how to utilize keyboard and mouse input to be used as user input for the canvas. First let me introduce a few new event handlers:
We will be adding an event listener to our document, even listeners are basically things that listen to events. Such that if we have a keyboard event a keyboard listener would fire whenever we have some type of keyboard input. Here is an example for keydown:
document.addEventListener("keydown", function(e) { // Do stuff });
The parameter given in the function is an object about the key information, I've given it the name e short for event, while there are a few properties I will only talk about the most commonly used ones: e.keyCode and e.charCode.
Here is a basic example of printing the keyCode text to the canvas, press a key on your keyboard and it will show the keyCode on the canvas below:
var canvas = document.getElementById("keyCanvas"); var ctx = canvas.getContext("2d"); ctx.font = "20px Arial"; ctx.fillText("keyCode = ",5,40); ctx.font = "30px Arial"; document.addEventListener("keydown", function(e) { ctx.clearRect(100,0,canvas.width,canvas.height); ctx.fillText(e.keyCode,110,40); });
HERE is the fiddle example.
When we have mouse event listeners the e argument (event), from it we can get our X and Y mouse coordinates of the window by using e.clientX and e.clientY. The only problem to this is these are repect to the window and not the canvas, we want (0,0) to be the top left corner of the canvas. To solve this we first get the coordinates (in the form of a rectangle object) of the canvas with respect to the client window by using canvas.getBoundingClientRect(), then we subract the window positions(clientX, clientY) from the canvas positions(left, top):
var canvas = document.getElementById("mouseCanvas"); var ctx = canvas.getContext("2d"); ctx.font = "20px Arial"; canvas.addEventListener("mousemove", function(e) { var cRect = canvas.getBoundingClientRect(); var canvasX = e.clientX - cRect.left; var canvasY = e.clientY - cRect.top; ctx.clearRect(0,0,canvas.width,canvas.height); ctx.fillText("X: "+canvasX+", Y: "+canvasY, 10, 30); });
Move your mouse over the canvas and it will show your mouse positions:
Along with a GUI, we would also like sound in our applications. I will give you a short introduction to the HTML5 Audio tag, we will be using this for our music and sound:
<audio controls> <source src="fileName.mp3" type="audio/mp3"> Your browser does not support the audio tag. </audio>
The audio tag supports 3 formats: mp3, wav, and ogg. To have it not show an interface simply remove the control attribute. To play it's sound we call the play() method:
var canvas = document.getElementById("soundCanvas"); var ctx = canvas.getContext("2d"); ctx.font = "20px Arial"; ctx.fillText("Click to play",20,30); canvas.addEventListener("click", function(e) { document.getElementById("audioPlayer").play(); });