Canvas API
Drawing 2D graphics in the browser — shapes, text, images, animations, and pixel manipulation with the HTML5 Canvas.
A canvas has two sizes: the size CSS displays it at, and its drawing surface, set by the width and height attributes (300 × 150 if you leave them out). Size a canvas only with CSS and your drawing commands still work in the 300 × 150 surface, which is then stretched to fit. Shapes land in the wrong place or disappear past the edge, and everything looks blurry.
// <canvas id="chart" style="width: 600px; height: 300px"></canvas> <- size set only in CSS
const canvas = document.getElementById("chart");
const ctx = canvas.getContext("2d");
console.log(canvas.width, canvas.height); // the real drawing surface
ctx.fillStyle = "royalblue";
ctx.fillRect(500, 100, 50, 50); // meant for the right-hand side
console.log(ctx.getImageData(520, 120, 1, 1).data[3]); // alpha of a pixel inside that square
// 300 150
// 0 <- nothing there: x = 500 is outside a 300-pixel-wide surfaceDrawing on the web
The Canvas API gives you a blank drawing surface in the browser. Unlike HTML elements, canvas has no DOM nodes for each shape — you issue drawing commands and pixels appear. This makes it much faster for things that change constantly, like animations and games.
Setup
<!-- HTML: -->
<canvas id="myCanvas" width="400" height="300"></canvas>
// JavaScript:
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d"); // 2D rendering context
// Canvas coordinate system:
// (0, 0) is top-left
// x increases to the right
// y increases downwardThe setup above avoids this by putting width and height on the <canvas> tag itself. When CSS decides the size (a responsive layout, say), copy the displayed size onto the drawing surface in JavaScript, multiplied by devicePixelRatio so it stays sharp on high-density screens. Then scale the context, so you can keep drawing in CSS pixels:
const canvas = document.getElementById("chart");
const ctx = canvas.getContext("2d");
const dpr = window.devicePixelRatio || 1;
const rect = canvas.getBoundingClientRect(); // the size CSS gave it: 600 x 300
canvas.width = rect.width * dpr; // match the drawing surface to it
canvas.height = rect.height * dpr;
ctx.scale(dpr, dpr); // keep drawing in CSS pixels
console.log(canvas.width, canvas.height);
ctx.fillStyle = "royalblue";
ctx.fillRect(500, 100, 50, 50);
console.log(ctx.getImageData(520 * dpr, 120 * dpr, 1, 1).data[3]); // getImageData uses surface pixels
// 600 300 (1200 600 on a 2x screen)
// 255Shapes
// Filled rectangle: x, y, width, height
ctx.fillStyle = "royalblue";
ctx.fillRect(10, 10, 100, 50);
// Stroked (outlined) rectangle:
ctx.strokeStyle = "coral";
ctx.lineWidth = 2;
ctx.strokeRect(130, 10, 100, 50);
// Clear a rectangle (erases to transparent):
ctx.clearRect(50, 25, 20, 20);
// Circle using arc():
ctx.fillStyle = "gold";
ctx.beginPath();
ctx.arc(
250, 35, // center x, y
25, // radius
0, // start angle (radians)
Math.PI * 2 // end angle (full circle = 2π)
);
ctx.fill(); // or ctx.stroke() for outlinedPaths — for complex shapes
// Always beginPath() before drawing, then fill() or stroke():
ctx.fillStyle = "mediumseagreen";
ctx.beginPath();
ctx.moveTo(100, 100); // starting point
ctx.lineTo(200, 100); // line to...
ctx.lineTo(150, 180); // line to...
ctx.closePath(); // line back to start
ctx.fill(); // fill the shape
// Curves:
ctx.strokeStyle = "purple";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(20, 200);
ctx.bezierCurveTo(80, 130, 160, 270, 220, 200); // cp1x, cp1y, cp2x, cp2y, endX, endY
ctx.stroke();Text and images
// Text:
ctx.fillStyle = "#333";
ctx.font = "bold 24px Arial";
ctx.textAlign = "center"; // "left", "center", "right"
ctx.textBaseline = "middle"; // "top", "middle", "bottom"
ctx.fillText("Hello Canvas!", canvas.width / 2, canvas.height / 2);
// Measure text width (for layout):
const metrics = ctx.measureText("Hello Canvas!");
console.log("Text width:", metrics.width);
// Image:
const img = new Image();
img.onload = () => {
ctx.drawImage(img, 10, 10); // draw at (10,10)
ctx.drawImage(img, 10, 10, 100, 80); // draw and resize to 100x80
};Official Sources
- MDN Web Docs — Canvas API
- MDN Web Docs — Canvas tutorial
- MDN Web Docs — OffscreenCanvas
- MDN Web Docs — WebGL API
The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.