DEV Community

Cover image for HTML5 canvas - part 1: Drawing
Guillaume Martigny
Guillaume Martigny

Posted on • Edited on

HTML5 canvas - part 1: Drawing

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.

<canvas id="scene"></canvas>
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 :

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.

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.

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.

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.

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.

In the meantime, try using arc and ellipse instructions on paths. Or even build your own shapes using lineTo or moveTo.

See ya !

Top comments (11)

Collapse
 
nektro profile image
Meghan (she/her)
Collapse
 
gmartigny profile image
Guillaume Martigny

github.com/GMartigny/pencil.js
When great minds collide ;)

Collapse
 
nektro profile image
Meghan (she/her)

Very nice indeed :D

Collapse
 
andy profile image
Andy Zhao (he/him)

Cool intro post! I just started to learn about HTML5 canvas too :)

Collapse
 
gmartigny profile image
Guillaume Martigny

See you soon for part 2. And, don't hesitate to share some of your work here whatever the result. ;)

Collapse
 
iandavid profile image
David Okpare

Hi Guillaume. Quick question: how can I achieve the canvas used on rushordertees.com/design-t-shirts/. Will it part of your coming series, drawing on pictures?

Collapse
 
gmartigny profile image
Guillaume Martigny

Hi David o/
The link you provide did't use <canvas>. However, you can easily achieve the same effect with it. I don't want to sound too teasing, but images will be treated in part 3 ;) (if you have more question, you can mail or tweet me)
Stay tuned.

Collapse
 
iandavid profile image
David Okpare

Also. Great article.

Collapse
 
matthewodle profile image
Matthew Odle

Nice post!

I've been using canvas for a while to make arcade games, mostly as a way to sharpen the Javascript saw.

Collapse
 
dougmckechie profile image
Douglas McKechie

I'm a huge fan of HTML canvas having played with it a lot over a number of years, so great to see a (well written) post about it! HTML canvas can be a lot of fun, looking forward to part 2.

Collapse
 
gmartigny profile image
Guillaume Martigny

Thanks for you comments, it's heartwarming. Hope I could teach you 1 or 2 things despite your experience. Subscribe to not miss out ;)