← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Canvas API — 2D Drawing

javascript HTML5 Intermediate

Also Known As

Canvas API HTML canvas 2D context CanvasRenderingContext2D

TL;DR

The HTML Canvas API provides a 2D drawing surface via JavaScript — used for charts, image manipulation, games, data visualisations, and any pixel-level rendering that DOM elements cannot efficiently handle.

Explanation

A <canvas> element provides a bitmap drawing surface. JavaScript obtains a 2D rendering context via canvas.getContext('2d') and draws using methods like fillRect(), arc(), drawImage(), and fillText(). Canvas is immediate mode — you draw commands execute immediately and the result is just pixels; there is no retained object graph like SVG. This makes Canvas fast for many operations but means you must redraw everything on each frame for animations. The CanvasRenderingContext2D API includes path drawing (beginPath, moveTo, lineTo, arc), fill and stroke styles (colours, gradients, patterns), text rendering, image compositing, and transformations (translate, rotate, scale). For 3D, use WebGL or WebGPU via getContext('webgl2') instead.

Common Misconception

Canvas and SVG are interchangeable. Canvas is pixel-based and immediate — good for many moving objects (games, particle systems). SVG is vector-based and retained — good for interactive diagrams with mouse events per element, accessibility, and scaling at any resolution. Choose based on the use case.

Why It Matters

Canvas is the foundation of chart libraries (Chart.js, D3 SVG/canvas modes), image editors, game engines (Phaser, PixiJS), and QR code generators in the browser. Understanding Canvas lets you implement custom visualisations that CSS and SVG cannot efficiently handle, and debug or optimise rendering in libraries that wrap it.

Common Mistakes

  • Not accounting for devicePixelRatio — canvas renders blurry on retina screens; multiply width/height by devicePixelRatio and scale the context.
  • Forgetting ctx.beginPath() before drawing paths — paths accumulate; without beginPath(), new shapes join the previous path, producing unexpected fills.
  • Setting canvas size with CSS instead of the width/height attributes — CSS scales the bitmap (blurry); the attributes set the actual resolution.
  • Doing heavy computation inside the animation loop — move data processing outside requestAnimationFrame and only draw inside it.

Code Examples

✗ Vulnerable
// ❌ Leaking context state, not clearing between frames
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');

ctx.fillStyle = 'red'; // Never reset — affects all subsequent draws
ctx.translate(100, 100); // Cumulative! Each frame moves 100px further

function draw() {
    // Missing: ctx.clearRect(0, 0, canvas.width, canvas.height)
    ctx.fillRect(0, 0, 50, 50); // Draws over previous frame
    requestAnimationFrame(draw);
}
✓ Fixed
// ✅ Proper canvas animation loop
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');

let x = 0;

function draw() {
    // Clear the entire canvas each frame
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // Save/restore to isolate state changes
    ctx.save();
    ctx.fillStyle = 'royalblue';
    ctx.translate(x, 100);
    ctx.fillRect(-25, -25, 50, 50); // Centred rect
    ctx.restore(); // fillStyle and translate are gone

    x = (x + 2) % canvas.width; // Loop across canvas
    requestAnimationFrame(draw);
}

// Set canvas resolution to match device pixel ratio (crisp on retina)
const dpr = window.devicePixelRatio || 1;
canvas.width  = canvas.offsetWidth  * dpr;
canvas.height = canvas.offsetHeight * dpr;
ctx.scale(dpr, dpr);

draw();

Added 23 Mar 2026
Edited 5 Apr 2026
Views 23
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 2 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
Amazonbot 8 Perplexity 5 ChatGPT 1 Majestic 1 Google 1 Ahrefs 1
crawler 17
DEV INTEL Tools & Severity
⚙ Fix effort: Medium
⚡ Quick Fix
Always call ctx.save() before and ctx.restore() after applying transformations or style changes you don't want to leak — the canvas context is global state.
📦 Applies To
javascript HTML5 web

✓ schema.org compliant