JavaScript Notes
Learn the HTML5 Canvas API in JavaScript. Draw shapes, images, text, and build animations with 2D rendering context. Includes real examples, output blocks, and interview Q&A.
The Canvas API provides a pixel-level drawing surface directly inside the browser. Unlike SVG (which works with vector objects), Canvas operates like a physical painting canvas — you draw pixels and they stay there. This makes it ideal for games, data visualisations, image editing, and animations.
💡 Key insight: Canvas is a *stateful* drawing API. You set properties like colour and line width on the context, then draw. Think of it as a painter's setup: pick up a brush, choose paint colour, stroke the canvas.
Setting Up the Canvas
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d"); // 2D rendering context
console.log(canvas.width, canvas.height);400 300
Always setwidthandheightas HTML attributes (not CSS). CSS sizing scales the canvas but doesn't change the internal resolution, causing blurry output.
Drawing Shapes
Rectangles
// Filled rectangle
ctx.fillStyle = "#3498db";
ctx.fillRect(50, 50, 150, 80); // x, y, width, height
// Outlined rectangle
ctx.strokeStyle = "#e74c3c";
ctx.lineWidth = 3;
ctx.strokeRect(220, 50, 120, 80);
// Clear a rectangle (punch a hole)
ctx.clearRect(90, 70, 40, 40);// Canvas now shows: // - Blue filled rectangle at (50,50) sized 150x80 // - Red outlined rectangle at (220,50) sized 120x80 // - Transparent hole at (90,70) sized 40x40
Paths — Lines, Curves, Polygons
ctx.beginPath(); // start a new path
ctx.moveTo(50, 200); // lift pen and move
ctx.lineTo(150, 100); // draw line to
ctx.lineTo(250, 200); // draw another line
ctx.closePath(); // connect back to start
ctx.fillStyle = "rgba(52, 152, 219, 0.5)";
ctx.fill();
ctx.strokeStyle = "#2980b9";
ctx.lineWidth = 2;
ctx.stroke();// Canvas shows a semi-transparent blue triangle // with a solid blue outline
Circles & Arcs
// arc(x, y, radius, startAngle, endAngle, anticlockwise)
ctx.beginPath();
ctx.arc(200, 200, 60, 0, Math.PI * 2); // full circle
ctx.fillStyle = "#2ecc71";
ctx.fill();
// Half circle (pie slice)
ctx.beginPath();
ctx.arc(200, 200, 60, 0, Math.PI); // 0 to π = bottom half
ctx.strokeStyle = "#27ae60";
ctx.lineWidth = 4;
ctx.stroke();// Canvas shows a green filled circle // with a darker green arc covering the bottom half
Text
ctx.font = "bold 24px Arial";
ctx.fillStyle = "#2c3e50";
ctx.fillText("Hello Canvas!", 50, 50);
ctx.font = "italic 18px Georgia";
ctx.strokeStyle = "#8e44ad";
ctx.lineWidth = 0.5;
ctx.strokeText("Outlined text", 50, 90);
// Measure text width
const metrics = ctx.measureText("Hello Canvas!");
console.log(metrics.width);// Canvas shows filled dark text and outlined purple text 131.6 // approximate pixel width
Images
// Canvas shows the image at full size, scaled, and cropped variants
Gradients
// Linear gradient
const linear = ctx.createLinearGradient(0, 0, 400, 0);
linear.addColorStop(0, "#e74c3c");
linear.addColorStop(0.5, "#f39c12");
linear.addColorStop(1, "#2ecc71");
ctx.fillStyle = linear;
ctx.fillRect(0, 0, 400, 60);
// Radial gradient
const radial = ctx.createRadialGradient(200, 180, 10, 200, 180, 80);
radial.addColorStop(0, "white");
radial.addColorStop(1, "#3498db");
ctx.fillStyle = radial;
ctx.beginPath();
ctx.arc(200, 180, 80, 0, Math.PI * 2);
ctx.fill();// Canvas shows a red-to-orange-to-green horizontal gradient bar // and a white-to-blue radial gradient circle
Transformations
ctx.save(); // save current transform state
ctx.translate(200, 150); // move origin
ctx.rotate(Math.PI / 6); // rotate 30 degrees
ctx.scale(1.5, 1.5); // scale up 50%
ctx.fillStyle = "#e74c3c";
ctx.fillRect(-40, -20, 80, 40); // draw around new origin
ctx.restore(); // revert to saved state// Canvas shows a red rectangle rotated 30° and scaled 1.5x, // centered at (200,150). State is reset after restore().
save()andrestore()work like a stack — eachsave()pushes the state, eachrestore()pops it. Always pair them.
Animation with requestAnimationFrame
let x = 0;
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // wipe previous frame
ctx.fillStyle = "#3498db";
ctx.beginPath();
ctx.arc(x, 150, 20, 0, Math.PI * 2);
ctx.fill();
x = (x + 2) % canvas.width; // move right, wrap around
requestAnimationFrame(animate); // schedule next frame (~60fps)
}
animate();// A blue circle smoothly moves from left to right across the canvas, // wrapping back to the start. Runs at ~60 frames per second.
requestAnimationFrameis far better thansetIntervalfor animation — it syncs to the display refresh rate and pauses when the tab is hidden.
Pixel Manipulation
// Canvas colours are inverted (white → black, red → cyan, etc.)
Canvas vs SVG
| Canvas | SVG | |
|---|---|---|
| Rendering | Raster (pixels) | Vector (shapes) |
| Scalability | Blurs when scaled | Crisp at any size |
| Performance | Fast for many objects | Slower with 1000s of elements |
| Interactivity | Manual hit-testing | Built-in event listeners on elements |
| Best for | Games, image processing, charts | Icons, logos, diagrams |
When to Use Canvas
- Games — precise per-frame rendering, sprite animation
- Data visualisations — charts with thousands of data points
- Image filters — pixel manipulation, filters, webcam effects
- PDF/image export — capture and export the canvas as a PNG
- Signature pads — capture user drawings
Common Mistakes
- Forgetting
beginPath()— without it, previous paths accumulate and you get unexpected fills/strokes. - Setting canvas size in CSS only — CSS scales a small canvas up, causing blurriness. Set
width/heightattributes. - Not clearing the canvas each frame — calling
clearRectis essential in animation loops. - Missing
img.onload— drawing an image before it loads renders nothing. - Not using
save()/restore()— transform state bleeds between draw calls. - Forgetting
closePath()— shapes that should be closed will have a gap.
Interview Questions
Q1. What does getContext("2d") return?
It returns aCanvasRenderingContext2Dobject — the drawing interface with all methods and properties for 2D graphics. Returnsnullif the canvas is not supported.
Q2. What is the difference between fill() and stroke()?
fill()paints the interior of the current path withfillStyle.stroke()outlines the path withstrokeStyleandlineWidth. You can call both on the same path.
Q3. Why use requestAnimationFrame instead of setInterval for animation?
requestAnimationFramesynchronises with the browser's display refresh (typically 60fps), produces smoother animations, and automatically pauses when the tab is not visible — saving CPU.setIntervalruns at a fixed rate regardless of display sync or tab visibility.
Q4. How do you draw a circle on canvas?
Usectx.arc(x, y, radius, 0, Math.PI * 2)followed byctx.fill()orctx.stroke(). Always callbeginPath()first.
Q5. What is getImageData used for?
It reads the raw RGBA pixel data of a region of the canvas into a Uint8ClampedArray. Used for image processing, filters, colour pickers, and pixel-level effects.Q6. How do you export a canvas as a PNG image?
``js const url = canvas.toDataURL("image/png"); const a = document.createElement("a"); a.href = url; a.download = "drawing.png"; a.click(); ``Q7. What does ctx.save() / ctx.restore() do?
save()pushes the current drawing state (transforms, styles, clipping) onto a stack.restore()pops and reapplies the last saved state. This lets you apply temporary transforms without affecting subsequent drawing operations.
Q8. What causes blurry canvas output on high-DPI (Retina) screens?
The canvas physical size is specified in CSS pixels, but Retina screens have 2× (or more) device pixels. Fix by scaling the canvas todevicePixelRatio: ``js const dpr = window.devicePixelRatio || 1; canvas.width = 400 * dpr; canvas.height = 300 * dpr; canvas.style.width = "400px"; canvas.style.height = "300px"; ctx.scale(dpr, dpr);``
Key Takeaways
- Canvas operates on pixels — drawing is immediate and non-interactive (no built-in click events on shapes).
- Always call
beginPath()before drawing new shapes to avoid path accumulation. - Use
save()/restore()to isolate transform and style changes. requestAnimationFrameis the correct tool for canvas animation loops.- For text rendering, icons, and scalable graphics, SVG is often a better choice; Canvas shines for high-frequency rendering (games, real-time data).
toDataURL()lets you export the canvas content as an image.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Canvas API in JavaScript — Complete Drawing & Animation Guide.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this JavaScript Master Course topic.
Search Terms
javascript-complete-guide, javascript master course, javascript, complete, guide, browser, apis, canvas
Related JavaScript Master Course Topics