HTML5 canvas - part 1: Drawing
Tags: javascript, programming, tutorial, canvas
Published: 2018-05-14 06:44:34

---
title: HTML5 canvas - part 1: Drawing
published: true
description: First part of a series of articles to dive onto HTML5 canvas. Let's start with drawing.
tags: javascript, programming, tutorial, canvas
cover_image: https://thepracticaldev.s3.amazonaws.com/i/jdmy6rw4g3r6t8rxnlur.png
---

# Drawing in a canvas

Since HTML5, it's possible to use the `<canvas>` tag on your page. But, how are you supposed to use it ?
In this first part, we're going to look at available ways to draw shapes.

## Context

First of all you need to get the drawing context form the HTML element. In our case, we inform the browser we just want to use it for 2 dimensional drawing.

```html
<canvas id="scene"></canvas>
```
```js
const canvasElement = document.getElementById("scene");
const drawingContext = canvasElement.getContext("2d");
```

You can pass `"webgl"` to get a 3 dimensional rendering context, but better keep it simple for now.

## Draw

Once we have a context, we can use it to draw into the browser page.
For example, let's draw a rectangle with the `rect` instruction :

{% codepen //codepen.io/GMartigny/pen/JvbNwq?height=500&default-tab=js,result&embed-version=2#%}

 > Hum, that a blank page.

Well ... that's embarassing ...

### Disillusion

Using canvas is a piece of cake, but the syntax is so cumbersome !
At the same time, this syntax allow for amazing performance boost, but can be very obtuse for new-learners.
In fact, there's 3 way to draw a rectangle, each with varying degree of clarity.

### 1. Direct

The most simple way is to use the `fillRect` method. However, this type of method is only available for rectangles and texts (with `fillText`). Which is too limited, but the only way in the case of rendering text.

{% codepen //codepen.io/GMartigny/embed/QrMgQy/?height=500&default-tab=js,result&embed-version=2#%}

### 2. Current path

Secondly, it's possible to define a path sequentially, then fill it or stroke it.
Not that bad, but you have to keep track of the state yourself.

{% codepen //codepen.io/GMartigny/embed/aGyyNQ/?height=500&default-tab=js,result&embed-version=2#%}

### 3. Path object

Finally, the third way is to use the `Path2D` class to define a path. The big advantage is that you can store a path in a variable and use it later.

{% codepen //codepen.io/GMartigny/embed/BxYpeO/?height=500&default-tab=js,result&embed-version=2#%}

The last one is the most versatile and useful. Paths can be use in many ways in the canvas API :
 - isPointInPath - tell if a position is inside a path
 - clip - Remove everything outside of a path
 - addPath - add path to one another
 - ...

## Render loop

Rendering 1 frame is great, but not very dynamic. The most critical trick to know about animation is the rendering loop.
To create a smooth animation, you need to update the view 60 times per seconds (to achieve 60FPS). One second divided by 60 gives about 16ms, so you could `timeout` for 16ms every draw. Hopefully, there's a better way.

Your browser already refresh itself at 60FPS and you can ask it to sync a function to this loop. Thanks to `requestAnimationFrame`, you can bind a callback to the next window refresh.

Remember that updating means to clear the whole canvas an drawing it again. I also add a check in case we need to stop the animation. And voilà, our first animation.

{% codepen //codepen.io/GMartigny/embed/LmmGPN/?height=500&default-tab=js,result&embed-version=2#%}

 > Are you kidding me ? This is not working again ?

No, no, it working like a charm !
Indeed, nothing going on here because we draw the same frame over and over. We need to update the canvas' state, but this is a story for [part 2](https://dev.to/gmartigny/html5-canvas---part-2-state-54np).

In the meantime, try using [arc](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc) and [ellipse](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/ellipse) instructions on paths. Or even build your own shapes using [`lineTo`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineTo) or [`moveTo`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/moveTo).

See ya !