Jumping Into Javascript – Moving Objects on the Canvas

In the first part of Jumping Into Javascript, we created a simple html page with a canvas element on it and drew a single square. In this part we will concentrate on moving objects that we have drawn.

The concept of moving an object on the canvas is a bit of a misnomer. We actually won’t move anything at all, instead we must clear the canvas (or part of it) and repaint the object in a new location. Let’s look at the simplest code I could come up with that accomplishes this.

chart.js

var chart = document.getElementById("chart");
var c = chart.getContext("2d");

c.fillRect(10, 25, 20, 50);
c.clearRect(0, 0, chart.width, chart.height);
c.fillRect(30, 25, 20, 50);

This code starts by drawing a rectangle, then c.clearRect(0, 0, chart.width, chart.height) clears the canvas, then it draws another rectangle 20 pixels over to the right. If you run this code, you probably won’t see anything but the final rectangle. This is because it is running very fast. To see it we need to slow things down a bit.

There are a number of ways we could achieve this. We could set an event loop and move the rectangle on each loop, or we could set a timer between draws. However I’m going to use an event handler to call a function that clears the canvas and redraws the rectangle.

chart.js

var chart = document.getElementById("chart");
var c = chart.getContext("2d");
c.fillRect(10, 25, 20, 50);

chart.onclick = moveRect;

function moveRect() {
  c.clearRect(0, 0, chart.width, chart.height);
  c.fillRect(30, 25, 20, 50);
}

When you click on the canvas you will see the rectangle “move” a bit to the right. This illustrates a few things about Javascript that I haven’t covered. First moveRect is an example of how functions are defined in Javascript. You can also define functions like this…

var moveRect = function() { //body; }

see here for an explanation of the difference. This little snippet also hints to us that functions are first-class values in Javascript, but I won’t get into that now.

Also this demonstrates one of the ways to set an event handler. This sets the function moveRect to be called whenever the canvas is left clicked. This method of event handling will work with any modern browser.

Another way to accomplish event handling is to use the inline method. This is the oldest way to set handlers in Javascript. If you have to maintain compatibility with very old browsers you will be forced to use this method. Here’s a link to more info on the inline method and an example…

<canvas id="chart" onclick="moveRect();"></canvas>

So far we’ve got our rectangle to “move” once when the canvas is clicked on. However it will not move any further, no matter how many clicks occur. The reason for this is that we are not incrementing the x position of the rectangle, rather the new position is hardcoded into the moveRect function.

Even though we see a rectangle on the screen, in our source code there is really no notion of the rectangle as a separate entity. There are a variety of options to fix this behavior, we could code the rectangle as an object, or use a closure, or even use 4 different variables to hold the position and size of our rectangle. I’ll be covering some of those options later, but for now I want to focus on arrays.

Temporarily I’ll use an array to hold the values of the rectangle and a variable to hold the array. I’ll call it rect for now. Because the fillRect function does not accept an array as a parameter, we’ll need to define a function drawRect that will call fillRect with the correct values. To keep things simple, I’ll use rect as a global variable.

var chart = document.getElementById("chart");
var c = chart.getContext("2d");

chart.onclick = moveRect;

function drawRect() {
  c.fillRect(rect[0],rect[1],rect[2],rect[3]);
}

function moveRect() {
  c.clearRect(0, 0, chart.width, chart.height);
  rect[0] += 20;
  drawRect();
}

var rect = [10, 25, 20, 50];

drawRect()

When you run this code you’ll notice that the rectangle keeps moving to the right every time you click the canvas. This is exactly the behavior we were looking for here.

Once again there are a few new concepts here. var rect = [10, 25, 20, 50]; creates an array and assigns it to the variable rect. You do not have to specify the number of elements in the array and it is also resizable. Indexing into an array is similar to most Algol inspired languages using varName[n] to access the nth element of an array stored in varName. += also works as expected and destructively increments the value of the index n by the value of the right hand expression. This code also gives you a quick peek at the scoping rules used in Javascript, however a through overview will have to wait for a later article.

That quick overview concludes this post on moving objects on a canvas and arrays. In the next post I’ll probably cover objects and loops and create more rectangles to move about.

GOTO – Part 3 – Objects and Loops

Get JamochaTrade on GitHub

 

Links

Mastering Javascript Arrays

QuirksMode.org – Functions

Advertisements