It’s funny how software development goes in a circle. Ten years ago, I was writing DirectX code. The concept was simple. You have a screen, and you write pixels depending on what you wanted to draw. There were wrappers around common things, such as drawing an image to the screen or writing text. Eventually, I moved away from that into web development. Rendering to a screen was a matter of markup and styling. You lost a lot in finite control, but gained a lot in ease of use. A couple weeks ago I sat back and thought that I’d really like to dive deeper into how HTML5 canvas works, and how developers can use it to build better websites. It didn’t take long to figure out that I’ve completed the circle, and I’m now writing pixels to a screen again. HTML5 Canvas can be intimidating. It’s a line of markup, and then a whole lot of JavaScript. Most tutorials or blog posts out there kinda suck too. They’ll take a canvas and then should you how to plot a line or rectangle on it. That’s useful information to know, but not immediately practical. When I approached Canvas for the first time, I looked at it the same way I look at a lot of technologies. How would I write a game with it? Canvas is appropriate for this question, because a ton of HTML5 based games are built with Canvas instead of Flash or Silverlight. Plotting a rectangle isn’t the most important thing I want to do: plotting an image is. So Kevin, teach me Canvas. Ok. Let’s pretend we want to build a basic tile engine. Here’s ALL the markup we’ll want to write:


<canvas id="game" width="900" height="500"></canvas>  

That’s awesome. The rest is JavaScript. The gooey bits There are three things that we want to do in order for this canvas thing to work properly:

  1. Get the context of the canvas
  2. Load the image we want to render on the canvas
  3. Render the image on the canvas

Canvas context A lot of developers would think that this involves using jQuery to pull the context of the canvas, but it’s much simpler than that. In fact, jQuery isn’t a requirement to do any of the work I’m talking about. I know, blasphemy.

var gameCanvas = document.getElementById("game"); gameCanvas.width = window.innerWidth; gameCanvas.height = window.innerHeight; var ctx = gameCanvas.getContext('2d');

Line 1 shows you how to get a reference to the canvas element. This is how it used to be done in the old days before jQuery. Lines 2 and 3 are used to resize the canvas to the size of our screen. In the demo application I’m building, I want it to run in full screen. This is a must. Line 4 asks the browser to give us a 2D context of the canvas. But Kevin, that implies that I can pull a 3D context too. Yes, Virginia. Loading the image Let’s say I have an image to represent grass in our tile engine. grass This image is 64px by 64px. To load the image, we’ll append the following lines of code:


var img = new Image();  
img.src = “images/grass.png”;  

The src of the image is relative path, but you can point it to wherever you need. If you’re watching your developer tools, you’ll see the browser issue a request for the image. Rendering the image This is the fun part! We’ve loaded our image, and now we’ll want to render it to script.


ctx.drawImage(img, 0, 0);  

We’re calling the drawImage method on the canvas context. In this particular overload, we’re telling it to render our image at the point (0,0) on the canvas. Remember your 7th grade geometry. In 2D math, there is an X axis and a Y axis. For canvas, the origin ( or the 0, 0 point) is in the upper left corner. This is where our image will render. But Kevin, you said Tile Engine. That’s one tile Yup. Let’s wrap the above code in some for loops.


for (var x = 0; x < gameCanvas.width; x += 64) {  
     for (var y = 0; y < gameCanvas.height; y += 64) {  
          ctx.drawImage(imageList[0], x, y);  
     }  
}  

image Ignore the white box in the middle of the grid. That’s for another blog post. The code will render the tile in a series for the width and height of the canvas, which happens to be the same width and height as the inside of our browser. As a note, I disabled scroll bars and did some CSS resetting to make this look the way it does. What’s next? Canvas isn’t hard. It just takes some getting used to. I really wanted to show you here what it takes to do something simple but cool in Canvas. In the next few blog posts, I’ll show you how to take this approach and build a real tile engine with it. We’ll handle rendering custom tile maps, accept keyboard and mouse inputs, and maybe even throw in some special effects. Kevin Griffin keving@componentone.com @1kevgriff