Drawing shapes with canvas


Remember the SVG module where we learned how to draw various shapes on the screen? Now, we'll be doing this again, but with canvas instead—and the approach is quite different!

Let's make some circles again! 🎉

Free
4 minutes read

Let's make a circle (again)

📍 Start with a canvas element

Everything begins with the DOM. In the return statement of our graph component, rather than rendering multiple SVG elements as we did previously,

we now render just a single canvas element.

return (
    <canvas width={width} height={height} ref={canvasRef}/>
);

⛏️useRef and useEffect to draw in it

Next, we’ll need to “edit” the canvas by drawing on it. To achieve this, we need a reference to the canvas element so we can target it directly. Then, we can use useEffect to write the code for drawing inside it.

// define a ref = a way to target the canvas element
const canvasRef = useRef(null);

// once the canvas element is mounted, draw some stuff in it imperatively
useEffect(() => {
  const canvas = canvasRef.current; // find the target canvas element

  const ctx = canvas.getContext('2d'); // initialize a canvas "context"

  // draw whatever you want in the canvas
}, []);

✏️ A new syntax for the actual drawing

Finally, it’s time to create the actual drawing.

For each element, we start by initializing a path with beginPath(). There are various functions available for drawing different shapes. To draw a circle, for example, we use the arc() function.

Setting a color follows a slightly unusual pattern: first, we set the color with fillStyle(), and then we apply the fill using fill().

ctx.beginPath();
ctx.arc(100, 100, 50, 0, 2 * Math.PI);
ctx.fillStyle = 'blue';
ctx.fill();

🔵 Complete circle example

A simple circle drawn with canvas

🟪 What about rectangles?

The process is almost identical!

The only change is the canvas call inside useEffect. This time, we’ll use the rect() function as shown:

ctx.beginPath();
ctx.rect(100, 100, 80, 50); // Draw the rectangle (x, y, width, height)
ctx.fillStyle = "purple";
ctx.fill();

And that’s it! Here’s a complete example:

A simple Rectangle drawn with canvas

🍔 Stacking Order Matters

Drawing with canvas is a bit like using a pen on paper: whatever you draw second will always appear on top of what was drawn first!

For data visualizations, we need to carefully consider the stacking order, as there’s no way to change it afterward.

Similarly, individual elements can’t be removed from the canvas. The only option is to redraw everything from scratch—which isn’t an issue since it’s very fast.

A few shapes drawn with canvas

Your turn!