The Canvas API

The Canvas API lets you draw graphics pixel by pixel with JavaScript — shapes, lines, text, and images — by calling methods on a <canvas> element's 2D rendering context.

Learn The Canvas API in our free JavaScript course — an interactive lesson with runnable examples, a practice exercise and a quick reference.

Part of the free JavaScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

It powers charts, games, image editors, data visualizations, and any custom drawing the browser's normal HTML and CSS cannot express.

💡 About the runnable demos: A real <canvas> needs a browser, so the drawing code lives in the read-only blocks. Each Try it Yourself computes the geometry — the exact coordinates a shape would be drawn at — and logs it, which is the part people actually get wrong. Paste the read-only snippets into a browser to see them paint.

🖌️ Real-World Analogy: The canvas is a painter's canvas and the context is your set of brushes and pens . You don't move shapes around like furniture (that's the DOM); you paint them on. Want something to move? You wipe the canvas and repaint the whole scene a little differently — 60 times a second.

Grab the 2D context with canvas.getContext("2d") . The coordinate system starts at the top-left : X grows right, Y grows down . The quickest things to draw are rectangles: fillRect(x, y, w, h) paints a solid box, strokeRect outlines one, and clearRect erases a region.

To center a box you must offset by half its size — the classic coordinate bug. Let's compute that placement for real:

Anything beyond rectangles is a path . Start with beginPath() , move the "pen" with moveTo(x, y) , draw straight segments with lineTo(x, y) , and draw circles or arcs with arc(cx, cy, radius, startAngle, endAngle) — angles in radians . Finish by calling fill() or stroke() .

💡 Tip: Always call beginPath() before a new shape. Forget it and your new path connects to the previous one, producing stray lines.

A circle is really just points placed with trigonometry. Here we compute the points where arc would place markers around a circle — the basis of every pie chart and clock face:

Replace the blank with the argument that asks for the 2D drawing context.

Draw labels with ctx.font and fillText(text, x, y) . To animate, use requestAnimationFrame : it calls your function right before the next repaint. Each frame you clearRect the whole canvas, update positions, redraw, and schedule the next frame. Because the canvas is immediate-mode, nothing persists — you repaint the entire scene every time.

The motion itself is just arithmetic per frame. Here we compute the box's x-position over several frames, including the wrap-around — exactly what the loop above does:

Replace the blank so each cell's x is its column times the cell size.

ctx.clearRect(0, 0, canvas.width, canvas.height) .

Before you can draw a bar chart you must compute each bar's rectangle. Given some values and a chart height, produce the fillRect arguments for each bar so they sit on the baseline and scale to the tallest value.

Up next: Checkpoint: Browser APIs — tie it all together. 🏁

Practice quiz

How do you get the 2D drawing context from a canvas element?

  • canvas.getContext('2d')
  • canvas.context2d()
  • canvas.draw('2d')
  • canvas.get2D()

Answer: canvas.getContext('2d'). canvas.getContext('2d') returns the CanvasRenderingContext2D object, the toolbox of methods like fillRect, arc, and fillText.

Where is the origin (0, 0) on a canvas?

  • The center
  • The bottom-left corner
  • The top-left corner
  • The top-right corner

Answer: The top-left corner. The coordinate system starts at the top-left: X grows right and Y grows downward.

Which method paints a solid filled rectangle?

  • strokeRect(x, y, w, h)
  • clearRect(x, y, w, h)
  • fillRect(x, y, w, h)
  • drawRect(x, y, w, h)

Answer: fillRect(x, y, w, h). fillRect(x, y, w, h) paints a solid box; strokeRect outlines one and clearRect erases a region.

What units does arc() use for its start and end angles?

  • Degrees
  • Radians
  • Pixels
  • Percentages

Answer: Radians. arc() angles are in radians; a full circle is Math.PI * 2 (using 360 would be wrong).

To draw a custom path, which method should you call first to start a new shape?

  • closePath()
  • beginPath()
  • moveTo()
  • fill()

Answer: beginPath(). Always call beginPath() before a new shape; forgetting it makes the new path connect to the previous one, producing stray lines.

Which API is used to animate by running a draw function before each repaint?

  • setInterval
  • requestAnimationFrame
  • setTimeout
  • queueMicrotask

Answer: requestAnimationFrame. requestAnimationFrame calls your draw function right before the next repaint (about 60 times a second).

How do you erase the whole canvas at the start of each animation frame?

  • ctx.reset()
  • ctx.fillRect(0, 0, w, h)
  • ctx.clearRect(0, 0, canvas.width, canvas.height)
  • ctx.beginPath()

Answer: ctx.clearRect(0, 0, canvas.width, canvas.height). Because canvas is immediate-mode, you clearRect(0, 0, canvas.width, canvas.height) to wipe before repainting each frame.

To center an 80x40 box on a 300x200 canvas, what are the fillRect x and y?

  • x: 150, y: 100
  • x: 110, y: 80
  • x: 80, y: 40
  • x: 220, y: 160

Answer: x: 110, y: 80. fillRect takes the top-left corner, so x = 300/2 - 80/2 = 110 and y = 200/2 - 40/2 = 80.

What is the difference between fill and stroke?

  • fill outlines, stroke fills inside
  • fill paints the inside, stroke draws the outline
  • They are identical
  • fill is for text, stroke is for shapes

Answer: fill paints the inside, stroke draws the outline. fill paints the inside of a shape using fillStyle; stroke draws only its outline using strokeStyle and lineWidth.

Why should you size a canvas with width/height attributes instead of CSS?

  • CSS sizing is slower to load
  • Attributes set the real pixel resolution; CSS just stretches the bitmap and looks blurry
  • CSS only works in Firefox
  • Attributes enable WebGL automatically

Answer: Attributes set the real pixel resolution; CSS just stretches the bitmap and looks blurry. Setting width/height attributes sets the real pixel resolution; using CSS stretches a smaller bitmap and produces a blurry result.