Learning the basics of HTML5 canvas
In Chapter 3 of his book, Foundation HTML5 Canvas, Rob Hawkes explains how to use the canvas element, draw basic shapes and text, change the colour, erase the canvas and how to make it fill the browser window.
- Knowledge needed: Basic JavaScript and HTML5
- Requires: jQuery
- Project Time: 1-2 hours
- Support file
This excerpt is Chapter 3 of Foundation HTML5 Canvas: For Games and Entertainment by Rob Hawkes.
By now you should already have a good idea about what canvas is and why it’s a fantastic part of HTML5. In this article, we will take a proper look at the features of HTML5 canvas, from learning how to actually get it into a HTML document to drawing shapes and other kinds of objects on it. We will also look at how to change how shapes and objects are drawn on HTML5 canvas, as well as finding out how to erase it. Finally, we’ll end with an example showing you how to make canvas the same size as the browser window, an integral skill to have for developing immersive games. I hope by the end of this tutorial that you feel even more excited about HTML5 canvas and the possibilities that it opens up in front of you.
ADVERTISEMENT
01. Getting friendly with the canvas element
Just like video and audio, the HTML5 canvas element uses absolutely no external plug-ins or voodoo to do its thing. All you need is some HTML and a sprinkling of JavaScript courtesy of the 2d rendering context API. Don’t worry if you don’t have a clue what the 2d rendering context API is right now — you’ll be an expert in it soon enough.
Using the canvas element is simple - and I mean really, reallysimple. The following code is all you need to get started with it:
I suppose I should be honest and tell you that this doesn’t actually do anything spectacular. All it does is create a new blank canvas element, but you won’t be able to see anything yet because you haven’t done anything with the 2d rendering context. We’ll get on to drawing things on to the canvas shortly, which is simple as well.
For now, it’s important to note the width and height attributes used when creating the canvas element. These attributes obviously define the size of the canvas element, which in turn define the size of the 2d rendering context. Without defining a size like this the canvas element and the 2d rendering context would be set to the default width and height of 300 by 150, respectively. Later on in this chapter we’ll look at the ways to create a canvas element that changes size dynamically and fills the whole browser window.
Note: The position of the HTML5 canvas element is defined by its location within your HTML document. It can be moved around with CSS as required, just like other HTML elements.
02. Browser support for canvas
Most modern browsers support the HTML5 canvas element and the majority of its features, but it comes as no surprise that Internet Explorer doesn’t, at least not in any version earlier than Internet Explorer 9. If you’re happy with this fact of life, then you can put a suitable message in the fallback content for the canvas element that lets those poor IE users know that they should upgrade. The other option is to use the fantastic ExplorerCanvas script, which has been developed by some boffins at Google. The beauty of this method is that you only need to include one script into your web page and the canvas element will work in Internet Explorer browsers prior to version 9.
If this is something you’re interested in then you should download the script from the ExplorerCanvas website and follow the instructions for installation.
03. The 2d rendering context
The canvas element isn’t the cool part of canvas at all; that acclaim falls to the 2d rendering context, the piece of awesome that you draw absolutely everything on to. The purpose of the canvas element is to act as a wrapper around the 2d rendering context, providing you with all the necessary methods and juicy functionality to draw on and manipulate it. It’s really important to understand this, so let me make it clear: you draw on to the 2d rendering context, not the canvas element. You access and display the 2d rendering context through the canvas element. I don’t expect this to make complete sense yet, my hope is that things will clear up a bit when you get stuck in with using the canvas for yourself.
04. The coordinate system
The 2d rendering context is a standard screen-based drawing platform. Like other 2d platforms, it uses a flat Cartesian coordinate system with the origin (0, 0) at the top left. Moving to the right will increase the x value, and moving downwards will increase the y value. Understanding how the coordinate system works is integral if you want to have things draw in the right place.
A single unit in the coordinate system is usually equivalent to 1 pixel on the screen, so the position (24, 30) would be 24 pixels right and 30 pixels down. There are some occasions where a unit in the coordinate system might equal 2 pixels, like with high definition displays, but the general rule of thumb is that 1 coordinate unit equals 1 screen pixel.
05. Accessing the 2d rendering system
There’s no point faffing around trying to explain this all in words when we could just start using it. So let’s do just that by creating a basic HTML web page with an empty canvas element:
You won’t see anything if you run it as it stands, so let’s access the 2d rendering context so we can start to draw stuff. Place the following inside of the jQuery statement, just like we did with the previous JavaScript examples:
var canvas = $("#myCanvas");
var context = canvas.get(0).getContext("2d");
var context = canvas.get(0).getContext("2d");
All we’re doing here is assigning the canvas element to a variable then assigning the 2d rendering context to another variable by calling the getContext method. I should point out that, because we’re using jQuery, we need to call the get method so we gain access to the DOM for the canvas element, from there we then have access to the canvas getContext method. I wouldn’t worry too much about trying to understand why: just be aware that the get method has nothing to do with canvas itself.
Now we have a variable that contains the 2d rendering context we can start to draw stuff. Exciting times! Add the following line after declaring the context variable:
context.fillRect(40, 40, 100, 100);
If you refresh the page you’ll see something amazing has happened; a black square has appeared!
You’ve just drawn your first element using canvas. Feels good, doesn’t it? The square is black because that is the default color of elements drawn with canvas; we’ll look at how to use something other than the default color later in this chapter.
06. Drawing basic shapes and lines
As you can see, drawing a square is pretty straightforward; it’s just one line of code, the fillRect method:
context.fillRect(40, 40, 100, 100);
The obvious thing you’ll notice is that the method is calledfillRect and not fillSquare. I’m sure most of you already know that a square is actually a rectangle with sides of the same length, but for those who don’t, a square is actually a rectangle with sides of the same length!
There are four arguments needed to create a rectangle. The first two are the (x, y) coordinate values for the origin of the square (its top left corner), and the final two are the width and height of the rectangle. The width of a rectangle is drawn to the right of the (x, y) position, and the height of the rectangle is drawn downwards from the (x, y) position. You can see why it’s important to know how the coordinate system works, otherwise you may have assumed the height would draw upwards from the (x, y) position. The fillRect method could be rewritten like this to visualise the arguments:
context.fillRect(x, y, width, height);
For the sake of clarity, change the width value of our square to 200, save the file, and refresh the page.
What a surprise, it’s a rectangle. And to draw the rectangle in a different position? Yup, just change the (x, y) position values. For example, an x position of 200 and a y position of 300.
This is the beauty of canvas; it’s ridiculously easy to manipulate the objects you’ve drawn, you just change the values of a couple of arguments.
Note: It may not seem obvious, but if you draw something with an origin point beyond the dimensions of the canvas element, it won’t appear on the screen. Only shapes drawn with an origin point, or some part of the shape inside of the canvas element will be visible to you.
Alongside fillRect is the strokeRect method, the evil twin. Whereas fillRect draws a rectangle and fills it with a color (in our case black), the strokeRect method draws a rectangle and strokes it. That’s not to say that strokeRect gives it a soothing pat with its hand (it wouldn’t be an evil twin if it was that nice); it means that the outline of the rectangle has a line drawn around it. If you change the fillRect example to usestrokeRect instead you’ll see what I mean.
The rectangle now has an outline; it’s effectively hollow. Now this is fun and all, but how about we try something a little more adventurous, like a full-blown line? Why not.
07. Lines
Lines are created a little differently to shapes. They’re actually known as paths. To create a simple path, you have to first call the beginPath method on the 2d rendering context, which effectively says, “get ready, we’re about to start drawing a path.” The next method to call is moveTo, which sets the (x, y) origin of the path we’re about to draw. Following this is a call to lineTowith the (x, y) of the destination of our line, with a call toclosePath to finish drawing the path. Finally, a call to strokewill make the line visible by drawing its outline. By putting this all together you come with something like this:
context.beginPath(); // Start the path
context.moveTo(40, 40); // Set the path origin
context.lineTo(340, 40); // Set the path destination
context.closePath(); // Close the path
context.stroke(); // Outline the path
context.moveTo(40, 40); // Set the path origin
context.lineTo(340, 40); // Set the path destination
context.closePath(); // Close the path
context.stroke(); // Outline the path
Which should look like this, a nice and boring straight line:
Lines don’t have to be horizontal or vertical though, by changing the (x, y) arguments of the lineTo method you can make it diagonal:
context.lineTo(340, 340);
Straight lines aren’t mighty exciting on their own, but they can be combined to produce complex shapes that are exciting. I’ll go through the advanced features of paths in the next chapter. For now, let’s try something else. How about drawing circles? They’re definitely a bit more exciting.
08. Circles
It doesn’t take a genius to realize circles are very different to rectangles. However, knowing this goes some way to explaining why creating a circle in canvas is very different to creating a rectangle. A circle is a fairly complex shape, and because of this there isn’t actually a special method in canvas to create a circle. What there is is a method for drawing arcs, which is all a circle really is—an arc joined at both ends. It’s a bit confusing, so how about we jump in and create a circle in canvas:
context.beginPath(); // Start the path
context.arc(230, 90, 50, 0, Math.PI*2, false); // Draw a circle
context.closePath(); // Close the path
context.fill(); // Fill the path
context.arc(230, 90, 50, 0, Math.PI*2, false); // Draw a circle
context.closePath(); // Close the path
context.fill(); // Fill the path
You should already recognize the first and last two lines, they just start and close the path (the arc) and then fill it when we’re done (fill is the companion method to stroke). The juicy part is the second line, which does everything necessary to draw a circle. It may look a bit complicated, so let me break it down for you.
There are six arguments used in the creation of an arc; the (x, y) coordinate values for the origin of the arc (the centre of the circle in our case), the radius of the arc, the start angle, the end angle, and finally a boolean value that draws the arc anti-clockwise if true, or clockwise if false. The arc method could be rewritten in a more readable way like so:
context.arc(x, y, radius, startAngle, endAngle,anticlockwise);
The first three arguments are self-explanatory so I’ll skip past those. The start angle and end angle arguments are seemingly simple, but they deserve some explaining to properly understand how they work. In short, an arc in canvas is defined as a curved path that starts at a distance from the (x, y) origin equal to the radius, and is at the angle defined by the start angle. The path ends at the end angle one radius away from the (x, y) origin.
It’s important to note that angles in canvas are in radians and not degrees and, without going into too much detail, it’s safe to assume that 360 degrees (a complete circle) is 2π (pi multiplied by 2) radians. People much cleverer than me have worked out how to convert from degrees to radians and they have come up with the following formula (written in JavaScript for our purposes):
var degrees = 1; // 1 degree
var radians = degrees * (Math.PI / 180); // 0.0175 radians
var radians = degrees * (Math.PI / 180); // 0.0175 radians
We’re going to be using radians throughout the book, as it saves us from performing unnecessary conversions from degrees, so to make things easier you can use the image below as a quick guide for the angle along a circle in radians.
For anything more complicated you should use the formula described previously.
So now you know how angles work in canvas. Let’s bring the focus back to the circle example. You can see now that the start angle is 0, the beginning of our arc, and the end angle isMath.PI*2 (pi multiplied by 2); these angles are the start and end of a circle. If you don’t believe me then check out the image above.
Note: To get access to the value of pi in JavaScript you use theMath object, which is a special object that allows you to do all sorts of cool math-based stuff. We’ll be using it in the future for tasks like generating random numbers.
If you run the example you should get a display in your browser like this:
A circle, hooray! Now, what would the end angle be if you wanted to draw half a circle instead? Check the image above if you want. That’s right, it would be plain and simple π, which looks like this in JavaScript:
context.arc(230, 90, 50, 0, Math.PI, false); // Draw a semi-circle
If all went well should have a lovely semi-circle in your browser.
Although the sixth argument in the arc method is meant to be optional, Firefox will throw an error if it is left out. Because of this, it’s worth keeping it in and explicitly defining a direction to draw the arc.
You could fiddle with the angles all day to create quarter circles, pizza slices—all sorts really. However, I’ll leave it up to you if you want to play around with that. We’ve got more important things to be getting on with, like changing the color of stuff!
09. Style
Black is so last season. If only there was a way to change the color of our shapes and lines. Wait, there is? And it’s really easy? Like one line of code easy? Awesome! I’m not lying about it being easy by the way. Let’s jump straight in and change the color of the square we made at the beginning of the chapter.
context.fillStyle = "rgb(255, 0, 0)";
context.fillRect(40, 40, 100, 100);
context.fillRect(40, 40, 100, 100);
By setting the fillStyle property of the 2d rendering context you’re able to change the color that shapes and paths are filled in as. In the previous example, an rgb (red, green, and blue) color value is assigned, although you could also use any valid CSS color value, like a hex code (eg. #FF0000 or the word “red”). In the example, the color is set to red (full red, no green, no blue) and your square should look something like this:
I told you it was easy, but don’t get too excited, as there is a downside. The issue is that setting the fillStyle property means that everything you draw after setting it will be in that color. This isn’t a problem if that’s what you want to happen, but it’s important to be aware of in case you only wanted to change the color of one object. One way to get around this is to set thefillStyle property back to black (or another color) once you’ve drawn your objects to canvas, like so:
context.fillStyle = "rgb(255, 0, 0)";
context.fillRect(40, 40, 100, 100); // Red square
context.fillRect(180, 40, 100, 100); // Red square
context.fillStyle = "rgb(0, 0, 0)";
context.fillRect(320, 40, 100, 100); // Black square
context.fillRect(40, 40, 100, 100); // Red square
context.fillRect(180, 40, 100, 100); // Red square
context.fillStyle = "rgb(0, 0, 0)";
context.fillRect(320, 40, 100, 100); // Black square
Which will look like this in the browser:
You can also do the same thing with stroked shapes and paths by using the strokeStyle property. For example, the following is the same as previous example except it’s using stroked outlines instead of fills:
context.strokeStyle = "rgb(255, 0, 0)";
context.strokeRect(40, 40, 100, 100); // Red square
context.strokeRect(180, 40, 100, 100); // Red square
context.strokeStyle = "rgb(0, 0, 0)";
context.strokeRect(320, 40, 100, 100); // Black square
context.strokeRect(40, 40, 100, 100); // Red square
context.strokeRect(180, 40, 100, 100); // Red square
context.strokeStyle = "rgb(0, 0, 0)";
context.strokeRect(320, 40, 100, 100); // Black square
Note: There’s nothing stopping you from combining bothfillStyle and strokeStyle to give a shape a fill and stroke that are completely different colors.
Nothing complicated here, it’s all very basic stuff. It’s just as easy to change the color of lines as well:
context.strokeStyle = "rgb(255, 0, 0)";
context.beginPath();
context.moveTo(40, 180);
context.lineTo(420, 180); // Red line
context.closePath();
context.stroke();
context.strokeStyle = "rgb(0, 0, 0)";
context.beginPath();
context.moveTo(40, 220);
context.lineTo(420, 220); // Black line
context.closePath();
context.stroke();
context.beginPath();
context.moveTo(40, 180);
context.lineTo(420, 180); // Red line
context.closePath();
context.stroke();
context.strokeStyle = "rgb(0, 0, 0)";
context.beginPath();
context.moveTo(40, 220);
context.lineTo(420, 220); // Black line
context.closePath();
context.stroke();
And that really is all there is to changing color in canvas.
10. Changing line width
Changing color is good fun, but our line examples have been a bit on the thin side. Fortunately in canvas, there is a method of fattening them up a bit, and that is the lineWidth property of the 2d rendering context. By default the lineWidth property is set to 1, but you can set it to anything you want. For example, let’s change the width of our red and black lines:
context.lineWidth = 5; // Make lines thick
context.strokeStyle = "rgb(255, 0, 0)";
context.beginPath();
context.moveTo(40, 180);
context.lineTo(420, 180); // Red line
context.closePath();
context.stroke();
context.lineWidth = 20; // Make lines even thicker
context.strokeStyle = "rgb(0, 0, 0)";
context.beginPath();
context.moveTo(40, 220);
context.lineTo(420, 220); // Black line
context.closePath();
context.stroke();
context.strokeStyle = "rgb(255, 0, 0)";
context.beginPath();
context.moveTo(40, 180);
context.lineTo(420, 180); // Red line
context.closePath();
context.stroke();
context.lineWidth = 20; // Make lines even thicker
context.strokeStyle = "rgb(0, 0, 0)";
context.beginPath();
context.moveTo(40, 220);
context.lineTo(420, 220); // Black line
context.closePath();
context.stroke();
The result of this is a slightly thicker red line and an overly thick black line:
And lineWidth works just as well on shapes:
context.lineWidth = 5; // Make lines thick
context.strokeStyle = "rgb(255, 0, 0)";
context.strokeRect(40, 40, 100, 100); // Red square
context.strokeRect(180, 40, 100, 100); // Red square
context.lineWidth = 20; // Make lines even thicker
context.strokeStyle = "rgb(0, 0, 0)";
context.strokeRect(320, 40, 100, 100); // Black square
context.strokeStyle = "rgb(255, 0, 0)";
context.strokeRect(40, 40, 100, 100); // Red square
context.strokeRect(180, 40, 100, 100); // Red square
context.lineWidth = 20; // Make lines even thicker
context.strokeStyle = "rgb(0, 0, 0)";
context.strokeRect(320, 40, 100, 100); // Black square
Which as you’ve probably guessed, makes two slightly thicker red squares with an overly thick black square.
You’ve practically mastered the basics now, but there are still a couple of things left to cover before we move on to the reallycool stuff.
11. Drawing text
Canvas is not just for graphics and images, you can also use it to display text. Although if I’m to be truthful, there aren’t many occasions where drawing text using canvas is a better option compared to creating text using a more traditional HTML element approach (like with a p element). Let me explain.
Text in canvas is drawn as an image, which means that it isn’t selectable with a mouse cursor like normal text in a HTML document—it isn’t actually text, it just looks like it. If you’ve used Microsoft Paint before, then you’ll understand what I mean; once text has been drawn it can’t be edited unless you erase it and redraw it again. The benefit to drawing text in canvas is that you can use all the wonderful transformations and other functionality that comes with drawing in canvas. However, I must stress that you shouldn’t create text in canvas unless you have a legitimate reason not to create it using normal, selectable HTML elements. Instead, you should use normal HTML elements to create text, and then layer them over the top of the canvas with CSS positioning. The point here is that HTML was built to deal with text (content), whereas canvas has been built to deal with pixels and graphics.
Now that’s out the way I can show you how to draw text in canvas, it’s really easy:
var text = "Hello, World!";
context.fillText(text, 40, 40);
context.fillText(text, 40, 40);
That is all you need to draw a string of text. The fillText method of the 2d rendering context takes four arguments (one is optional, so we’ve left it out for now); the first is the string of text you want to draw, and the second and third are the (x, y) coordinate values for the origin of the text (the bottom left). I told you it was easy.
I won’t show you the output just yet as it’s going to be too small to see, that is because the default font settings for text in canvas are 10px sans-serif (absolutely tiny). So let’s change the size now, and while we’re at it I might as well show you how to change the font. To do this you need to set the font property of the 2d rendering context, like so:
var text = "Hello, World!";
context.font = "30px serif"; // Change the size and font
context.fillText(text, 40, 40);
context.font = "30px serif"; // Change the size and font
context.fillText(text, 40, 40);
The font property takes a string value in exactly the same way as the font property in CSS. In the previous example, you give the pixel size to want the font to be, followed by the name of the font family you want to use. You’ve set it to serif which means the default font on the computer that is a serif font (something like Times New Roman). When put together it should look something like this:
That’s a bit better, you can actually read it now. You could even make the text italic if you really wanted by doing this:
var text = "Hello, World!";
context.font = "italic 30px serif";
context.fillText(text, 40, 40);
context.font = "italic 30px serif";
context.fillText(text, 40, 40);
All that’s changed here is the word italic has been added to the font string.
As the font property goes there are many more settings you can use, like the line height, and fallback font families. I won’t be covering these, but if you’re interested in using text in canvas, then I suggest that you check them out.
Note: As I hope you can see, the basics of canvas are very much self-explanatory. The reason for this is that the 2d rendering context API uses methods and properties that are named in a way that makes them easy to understand. It should now make sense why I stressed the importance of naming variables properly back in Chapter 2.
Before we move on, let me show you how to create stroked text—this is useful to know:
var text = "Hello, World!";
context.font = "italic 60px serif";
context.strokeText(text, 40, 100);
context.font = "italic 60px serif";
context.strokeText(text, 40, 100);
This time you’re using the strokeText method, which takes exactly the same parameters as fillText. It looks a bit weird at a small font size so in this example the size is larger and the origin has been moved down slightly so the text doesn’t go off the top of the screen. It should look a little something like this:
Generally I don’t see much excitement to stroked text, but you might have an amazing project that just wouldn’t be complete without it. If that’s the case then I suggest you knock yourself out and go crazy with it.
12. Erasing the canvas
Drawing on to the canvas is really fun, but what do you do when you make a mistake or want to wipe the slate clean and draw something else? Fortunately there are two options at your disposal: the clearRect method, or the width/height trick. Let’s take a look at the clearRect method of the 2d rendering context first.
Say you’ve just drawn a square and a circle on to the canvas:
context.fillRect(40, 40, 100, 100);
context.beginPath();
context.arc(230, 90, 50, 0, Math.PI*2, false);
context.closePath();
context.fill();
context.beginPath();
context.arc(230, 90, 50, 0, Math.PI*2, false);
context.closePath();
context.fill();
And you’ve now decided, for whatever reason, that you want to wipe the canvas clean. To do this all you need to do is callclearRect with the (x, y) origin of our canvas, its width, and its height. If the canvas was 500 pixels wide and 500 pixels tall then the call to clearRect would look like this:
context.clearRect(0, 0, 500, 500);
Which, when run, would display nothing in the browser, because you’ve just wiped the entire canvas clean. You can also even call clearRect when you don’t know the size of the canvas by using the jQuery width and height methods, like so:
context.clearRect(0, 0, canvas.width(), canvas.height());
Which would look like this in its entirety:
var canvas = $("#myCanvas");
var context = canvas.get(0).getContext("2d");
context.fillRect(40, 40, 100, 100);
context.beginPath();
context.arc(230, 90, 50, 0, Math.PI*2, false);
context.closePath();
context.fill();
context.clearRect(0, 0, canvas.width(), canvas.height());
var context = canvas.get(0).getContext("2d");
context.fillRect(40, 40, 100, 100);
context.beginPath();
context.arc(230, 90, 50, 0, Math.PI*2, false);
context.closePath();
context.fill();
context.clearRect(0, 0, canvas.width(), canvas.height());
I’ve included the original canvas variable in this example just to remind you where we’re calling it from in the clearRectmethod.
Note: The canvas element actually provides you with width andheight properties, so it’s up to you whether you want to use the jQuery way, or the pure JavaScript way of accessing the dimensions of the canvas.
You don’t have to clear the entire canvas though; you can just as easily clear a particular area of it. For example, if we wanted to remove only the square in the example then you would callclearRect like so:
context.clearRect(40, 40, 100, 100);
Which leaves you with a lonely circle.
The way this works is that the arguments in clearRect can be changed so a very specific area is cleared. In our case we’ve moved the origin of the area we want to erase (the top left) to be the top left of the square (40, 40), and the width and height of the area we want to erase has been set to the width and height of the square (100). The result is that only a specific area around the square is set to be cleared. You could quite easily remove the circle instead by changing the arguments of clearRect to the following:
context.clearRect(180, 40, 100, 100);
Which, if our calculations are correct, should leave us with just a square.
Remember that the origin of an arc is its centre, so to get the correct origin for the clearRect method we need to take the origin of the arc and subtract its radius for both the x and y.
Not that you would ever need to do this, but there’s nothing to stop you erasing only part of an object in canvas:
Not that you would ever need to do this, but there’s nothing to stop you erasing only part of an object in canvas:
context.fillRect(40, 40, 100, 100);
context.beginPath();
context.arc(230, 90, 50, 0, Math.PI*2, false);
context.closePath();
context.fill();
context.clearRect(230, 90, 50, 50);
context.beginPath();
context.arc(230, 90, 50, 0, Math.PI*2, false);
context.closePath();
context.fill();
context.clearRect(230, 90, 50, 50);
This example should take a big slice out of your circle:
This technique is sometimes used to draw complex shapes quickly and easily by drawing a basic shape and chopping bits off of it.
13. The width/height trick
If you only want to erase everything on the canvas and start again from scratch then you might want to consider the width/height trick. If I’m honest this isn’t really a trick, but rather a potent and little-documented method to reset a canvas back to its default, fresh state. The idea is that when the width and height attributes of a canvas element are set, at any point, the canvas should be cleared back to its original state. This method does have some drawbacks, so let me give you an example:
context.fillStyle = "rgb(255, 0, 0)";
context.fillRect(40, 40, 100, 100);
context.beginPath();
context.arc(230, 90, 50, 0, Math.PI*2, false);
context.closePath();
context.fill();
context.fillRect(40, 40, 100, 100);
context.beginPath();
context.arc(230, 90, 50, 0, Math.PI*2, false);
context.closePath();
context.fill();
This will draw a red square and circle onto the canvas, nothing crazy yet. Now let’s add in the canvas reset:
canvas.attr("width", canvas.width());
canvas.attr("height", canvas.height());
canvas.attr("height", canvas.height());
What’s happening here is a bit of jQuery magic. You need to change the width and height attributes of the canvas element, so to do this you use the attr method in jQuery. My hope is that by now you should be comfortable enough to guess what is going on. If not, we’re passing the name of the attribute we want to edit (width and height) followed by the value we want to set it to (the same width and height as it was previously). If all went well you should see a blank canvas.
Now add the following line after clearing the canvas with the width/height trick:
context.fillRect(40, 40, 100, 100);
Surely this should draw a red square, right? (Remember: we set the fillStyle property previously.) So why on earth is it drawing a black square?
The downside with the width/height trick is that absolutely everything in the canvas is reset, including styles and colors. This is why you should only use this trick if you’re prepared to completely reset the canvas, not just wipe the display clean.
14. Making canvas fill the browser window
Up until now the canvas element has been at a fixed width and height of 500 pixels, which is great, but what if we wanted to make it fill the entire browser window. How do you do it? Well with a normal HTML element you can normally set the widthand height attributes to 100% and you’re all sorted. However, the canvas element doesn’t work this way and ignores the percentage, interpreting 100% as 100 pixels, 200% as 200 pixels, and so on. A different method is required.
The easiest way to do it is to set the width and height of the canvas element precisely to the pixel width and height of the browser window. We can get access to the width and height of the window by using the window browser object and a bit of jQuery magic:
var canvas = $("#myCanvas");
var context = canvas.get(0).getContext("2d");
canvas.attr("width", $(window).get(0).innerWidth);
canvas.attr("height", $(window).get(0).innerHeight);
context.fillRect(0, 0, canvas.width(), canvas.height());
var context = canvas.get(0).getContext("2d");
canvas.attr("width", $(window).get(0).innerWidth);
canvas.attr("height", $(window).get(0).innerHeight);
context.fillRect(0, 0, canvas.width(), canvas.height());
The reason I’ve used $(window).get(0).innerHeightinstead of $(window).height() is that the latter doesn’t seem to return the full height in all browsers. You’ll notice that this method hasn’t actually worked properly as there is still a white gap around the canvas element and scrollbars in the browser window:
To fix this we need to use some CSS, so open up a new file in your favourite text editor and save it as canvas.css in the same directory as your HTML document. Put this inside of the CSS file and save it:
* { margin: 0; padding: 0; }
html, body { height: 100%; width: 100%; }
canvas { display: block; }
html, body { height: 100%; width: 100%; }
canvas { display: block; }
The first line resets the margin and padding of every HTML element to 0, removing the white border you can see in the screenshot above. This is commonly known as a CSS reset; there are much better ways of doing it, but this will serve our purposes right now. The second line isn’t entirely necessary, but makes sure that the html and body elements are the full width and height of the browser window. The final line changes the canvas element from inline to block, which allows the width the height to be set properly, in turn allowing it to take the full width and height of the browser window without causing scrollbars.
To use this CSS in the HTML document you need to add the following line before the jQuery script element, inside of thehead element:
To use this CSS in the HTML document you need to add the following line before the jQuery script element, inside of thehead element:
This links to the CSS file you just created and runs the styles within it. The result is a canvas element that perfectly fills the browser window.
Unfortunately we’re not done yet. If you resize the browser window the canvas element will stay at the size it was before, causing scrollbars if you shrink it too much:
To get around this you need to resize the canvas element at the same moment that the browser window is resized. If only jQuery had a resize method that was fired at the moment a browser window was resized, a little like how the ready method is fired when the DOM is ready. Well luckily for us, it does have have aresize method, and it does exactly that!
$(window).resize(resizeCanvas);
function resizeCanvas() {
canvas.attr("width", $(window).get(0).innerWidth);
canvas.attr("height", $(window).get(0).innerHeight);
context.fillRect(0, 0, canvas.width(), canvas.height());
};
resizeCanvas();
function resizeCanvas() {
canvas.attr("width", $(window).get(0).innerWidth);
canvas.attr("height", $(window).get(0).innerHeight);
context.fillRect(0, 0, canvas.width(), canvas.height());
};
resizeCanvas();
There isn’t much new here, most of the code has just been moved around a little. The main addition is the jQuery resizemethod which has been set to call the resizeCanvas function when the browser window is resized. All the functionality you had previously to set the width and height of the canvas element has been moved into that function, including the drawing of the rectangle the size of the canvas (remember: changing the width and height will reset the canvas, so everything has to be redrawn). The final addition is a call to the resizeCanvasfunction to kick things off when the page is loaded for the first time.
If you try that now you’ll notice the canvas element resizes beautifully and no scrollbars appear. It works, well done!
15. Summary
We’ve covered all sorts of interesting stuff in this chapter, particularly if you’ve never used canvas before. You’ve learned how to use the canvas element, how to draw basic shapes and paths, and how to change the color of those shapes and paths. You’ve also learned how to draw text, erase the canvas, and how to make canvas fill the browser window. It’s a huge amount really, so I think you should pat yourself on the back and go make yourself another cup of tea to let things soak in.
Liked this? Read these!
- How to build an app
- Free graphic design software available to you right now!
- Brilliant Wordpress tutorial selection
- Create a perfect mood board with these pro tips
- The ultimate guide to logo design
- Our favourite web fonts - and they don't cost a penny
No comments:
Post a Comment