Canvas

The HTML <canvas> element is a blank, bitmap drawing surface that you control entirely from JavaScript through its 2D context, letting you draw shapes, text, images, and gradients pixel by pixel for games, charts, and animations.

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

By the end you'll draw shapes, text, and gradients on a <canvas> , capture mouse input to draw freehand, and run a smooth animation loop with requestAnimationFrame .

What You'll Learn

Before you start: Canvas is driven entirely by JavaScript, so you'll want to be comfortable with variables, functions, and events first. If you need a refresher, revisit the previous lesson and the JavaScript course.

💡 Real-World Analogy

Think of canvas as a whiteboard with a single marker . You don't place objects you can move later — you give the browser instructions ("put the pen here, draw a circle, fill it green"), and it stains the board with pixels. Once a stroke is down it isn't a separate "thing" anymore; to change it you wipe the area and redraw. That's why animation means clear, then redraw the whole scene on every frame.

1. The drawing context

The <canvas> element is just a blank rectangle until you grab its 2D context — the object that holds every drawing method. You get it once and reuse it:

Coordinates start at (0, 0) in the top-left ; x grows to the right and y grows downward . Canvas is great for games, charts, and effects; for icons and logos prefer SVG (next lesson) because it stays sharp at any zoom.

Canvas vs SVG — pick the right tool

Feature

Canvas

SVG

Type

Pixel-based (bitmap)

Vector-based (DOM nodes)

Scaling

Gets blurry on zoom

Infinitely sharp

Best for

Games, visualisations, effects

Icons, logos, diagrams

Interactivity

Manual hit-testing

Native DOM events per element

Performance

Better with many objects

Slows with 100s of nodes

2. Shapes, fills, strokes, text & gradients

Read this fully-commented example, then run it. Notice three patterns you'll use constantly: fill vs stroke (inside colour vs outline), paths ( beginPath → arc / lineTo → fill / stroke ), and a gradient built from colour stops.

Important: Set canvas size with HTML attributes ( <canvas width="500" height="300"> ), not CSS. CSS only stretches the bitmap — the real resolution stays at the attribute values, so mismatched CSS sizes produce blurry output.

3. 🎯 Your turn — a traffic light

Time to practise fill and beginPath . Fill in the blanks marked ___ following the 👉 hints. Each lamp is its own path, so beginPath() before every circle.

4. Capturing mouse input

To draw freehand you turn mouse positions into a path. On mousedown you start a path, on mousemove you lineTo the new point and stroke() , and you stop on mouseup . getBoundingClientRect() converts the page coordinates into canvas-local ones.

5. Animating with requestAnimationFrame

An animation is just a function that draws one frame and then asks to be called again. requestAnimationFrame(fn) runs fn right before the next repaint (~60 times/sec). Each frame you clear (or paint a faint layer for trails), update positions, redraw, then schedule the next frame.

6. 🎯 Your turn — a moving square

Build your own animation loop. Fill in the three blanks: the clear method, and the function name passed to requestAnimationFrame so the loop keeps going.

7. A real example — bar chart from data

Loops + rectangles + text alignment combine into a genuine data visualisation. Watch how textAlign = 'center' changes what the x coordinate means for the labels.

8. 🎯 Mini-challenge — smiley face

No blanks this time — just a comment outline. Combine everything you've learned (paths, arcs, fills, strokes) to draw a smiley face. The trick for the smile: an arc from 0 to Math.PI draws the bottom half of a circle.

When to reach for canvas

Common Errors & Fixes

📋 Quick Reference

Method / Property

What it does

canvas.getContext('2d')

Get the 2D drawing context (the "pen")

fillStyle / strokeStyle

Colour for fills / for outlines

fillRect(x,y,w,h)

Draw a filled rectangle

strokeRect(x,y,w,h)

Draw a rectangle outline

clearRect(x,y,w,h)

Erase a rectangular area to transparent

beginPath()

Start a new path (call before each shape)

arc(x,y,r,0,Math.PI*2)

Add a circle (or arc) to the path

moveTo(x,y) / lineTo(x,y)

Move pen without drawing / draw a line

fill() / stroke()

Paint the current path's inside / outline

fillText(text,x,y)

Draw text (y is the baseline)

createLinearGradient(...)

Make a gradient for fillStyle/strokeStyle

drawImage(img,x,y)

Draw a loaded image onto the canvas

requestAnimationFrame(fn)

Run fn before the next repaint (~60fps)

Frequently Asked Questions

🎉 Lesson Complete

Up next: SVG Mastery — the vector counterpart to canvas, perfect for crisp icons and diagrams.

Practice quiz

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

  • canvas.getContext('2d')
  • canvas.draw2d()
  • canvas.context('2d')
  • canvas.get2D()

Answer: canvas.getContext('2d'). canvas.getContext('2d') returns the 2D drawing context — your 'pen' for all drawing methods.

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

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

Answer: The top-left. Canvas coordinates start at (0,0) in the top-left; x grows right and y grows downward.

What is the correct way to set a canvas's drawing resolution?

  • With CSS width and height
  • With the width and height HTML attributes
  • With the resolution attribute
  • It is set automatically

Answer: With the width and height HTML attributes. Set size with the width/height HTML attributes; CSS only stretches the bitmap and causes blur.

What does fillRect(x, y, w, h) do?

  • Draws a rectangle outline only
  • Draws a filled rectangle
  • Clears a rectangle
  • Defines a path

Answer: Draws a filled rectangle. fillRect paints a filled rectangle using fillStyle; strokeRect draws only the outline.

Why should you call ctx.beginPath() before drawing a new shape with a path?

  • To clear the canvas
  • To set the fill color
  • So the new shape isn't joined to the previous path
  • To start the animation loop

Answer: So the new shape isn't joined to the previous path. Without beginPath() the path keeps accumulating, so every new arc/line joins the previous shape.

What is the difference between fill() and stroke()?

  • fill() paints the inside, stroke() paints the outline
  • fill() paints the outline, stroke() paints the inside
  • They are identical
  • Only fill() works on paths

Answer: fill() paints the inside, stroke() paints the outline. fill() paints the inside of a path using fillStyle; stroke() paints its outline using strokeStyle.

Which method draws a full circle as a path?

  • circle(x, y, r)
  • arc(x, y, r, 0, Math.PI * 2)
  • ellipse(x, y, r)
  • drawCircle(x, y, r)

Answer: arc(x, y, r, 0, Math.PI * 2). arc(x, y, radius, 0, Math.PI * 2) sweeps a full 360-degree circle.

Which method should you call each frame to schedule smooth ~60fps animation?

  • setInterval(fn, 16)
  • requestAnimationFrame(fn)
  • setTimeout(fn, 60)
  • ctx.animate(fn)

Answer: requestAnimationFrame(fn). requestAnimationFrame(fn) runs fn right before the next repaint, about 60 times per second.

How do you erase a rectangular area of the canvas back to transparent?

  • ctx.eraseRect(...)
  • ctx.clearRect(x, y, w, h)
  • ctx.deleteRect(...)
  • ctx.reset()

Answer: ctx.clearRect(x, y, w, h). clearRect(x, y, w, h) erases that rectangle to transparent — used to clear each animation frame.

Compared to canvas, what is SVG better suited for?

  • Per-pixel image filters
  • Games with many sprites
  • Crisp icons and logos that scale
  • Real-time particle effects

Answer: Crisp icons and logos that scale. SVG is vector-based, staying sharp at any zoom — ideal for icons, logos, and diagrams.

Continue this course