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.
Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.
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 .
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.
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.
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.
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.