DEV Community

Brandon Weaver
Brandon Weaver

Posted on

Introduction to the HTML5 Canvas

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.

<!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>
Enter fullscreen mode Exit fullscreen mode

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.

const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
Enter fullscreen mode Exit fullscreen mode

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.

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.

...

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);
    }
}
Enter fullscreen mode Exit fullscreen mode

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.

...

const rect = new rectangle(0, 0, 10, 20, "#f00");
rect.update();
Enter fullscreen mode Exit fullscreen mode

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.

...

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

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.

...

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

...
Enter fullscreen mode Exit fullscreen mode

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.

...

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

...
Enter fullscreen mode Exit fullscreen mode

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.

...

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();
}

...
Enter fullscreen mode Exit fullscreen mode

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).

Top comments (0)