Introduction to the HTML5 Canvas
Tags: html, javascript
Published: 2021-01-03 02:22:09

The canvas element can be used to create everything from simple animations and displays, to games and simulations. For this introduction, we will focus on common strategies for rendering a simple interactive 'screen' using the canvas.

first create a new HTML file, and name it whatever you prefer. Open the file in a text editor of your choice, and add the following markup.

```html
<!DOCTYPE html>
<html>
    <head>
        <title>canvas-intro</title>
    </head>
    <body>
        <canvas height="480"
                width="640"
                style="display: block; margin: 0 auto; background-color: #050505;">
        </canvas>
        <script></script>
    </body>
</html>
```

Open the file in your browser, and you will be able to see the blank canvas.

Now, let's create a reference to the canvas, and canvas context in our script.

```javascript
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
```

There are a number of different rendering contexts, mostly utilizing WebGL for 3D effects, however, 2D is much easier to manage. If you'd like more information about rendering contexts, you can find plenty [here](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext).

We will need to reference our 2D context any time we want to draw to the canvas, or remove previous renderings.

Next, we'll create a simple factory function which will allow us to render rectangles on the canvas.

```javascript
...

function rectangle(x, y, width, height, color) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.update = () => {
        context.fillStyle = color;
        context.fillRect(this.x, this.y, this.width, this.height);
    }
}
```

Within the definition of `rectangle` we have a method named `update`; this method sets the `fillStyle` of our context before a call to `context.fillRect`. In conjunction, a rectangle will be rendered from the x and y value, with the given width, height, and color when `update` is called.

Our next step will be creating a rectangle, and drawing it on the canvas.

```javascript
...

const rect = new rectangle(0, 0, 10, 20, "#f00");
rect.update();
```

If you open/reload the file in your browser, you can see our red rectangle in the top-left corner.

Now, we want the user to be able to move the rectangle; this means that we need to update the canvas using an interval, and listen for key events.

Add the following function, and pass it to `setInterval`; the first argument is the callback which will be called every time the interval has elapsed, and the second argument is the interval time in milliseconds.

```javascript
...

const update = () => {
    rect.x += 0.5; // Move right
    rect.y += 0.5; // Move down
    rect.update();
}
setInterval(update, 20);
```

Open/reload the file, and you'll see that our rectangle slowly moves from its original position toward the bottom-right corner of our canvas. There is, however, one problem; because we aren't removing the previous renderings, we have a trailing effect. To resolve this issue, we simply add the following line at the top of `update`'s definition.

```javascript
...

const update = () => {
    context.clearRect(0, 0, canvas.width, canvas.height);
    rect.x += 0.5; // Move right
    rect.y += 0.5; // Move down
    rect.update();
}

...
```

Again, open/reload the file, and you will no longer see the trail of the rectangle.

On to the interactivity! Remove the two commented lines from our update function. Just above our update function we're going to create an array named `keys`, and listen for key events.

```javascript
...

const keys = [];
window.addEventListener("keydown", e => {
    keys[e.keyCode] = true;
});
window.addEventListener("keyup", e => {
    keys[e.keyCode] = false;
});

...
```

Here, we're setting the value at `keys` index of the key code to true or false, depending on whether the key is down or up, respectively; this allows us to easily track what keys the user is pressing.

Now, we'll just add some simple logic to move the rectangle in the appropriate direction when the user presses the arrow keys, and prevent the rectangle from moving outside of the canvas area.

```javascript
...

const update = () => {
    context.clearRect(0, 0, canvas.width, canvas.height);
    if (keyboard.keys[37] && rect.x > 0)
        rect.x -= 1;
    if (keyboard.keys[39] && rect.x + rect.width < canvas.width)
        rect.x += 1;
    if (keyboard.keys[38] && rect.y > 0)
        rect.y -= 1;
    if (keyboard.keys[40] && rect.y + rect.height < canvas.height)
        rect.y += 1;
    rect.update();
}

...
```

Once more, open/reload the file and use the arrow keys to guide your rectangle around! I know that it isn't very exciting, but this is 90% of what you'll need to know in order to create cool animations, fun games, and more (2D stuff at least).