Web APIs Cheatsheet
Canvas
Use this Web APIs reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Getting the Context
const canvas = document.getElementById('c'); const ctx = canvas.getContext('2d'); // HiDPI / Retina const dpr = window.devicePixelRatio || 1; canvas.width = canvas.offsetWidth * dpr; canvas.height = canvas.offsetHeight * dpr; ctx.scale(dpr, dpr); // WebGL const gl = canvas.getContext('webgl2'); // WebGL 2 const gl1 = canvas.getContext('webgl'); // WebGL 1 fallback // Context attributes canvas.getContext('2d', { alpha: false, desynchronized: true, colorSpace: 'display-p3' }); canvas.getContext('webgl2', { antialias: true, depth: true, powerPreference: 'high-performance' });
Canvas Properties
| Property | Description |
|---|---|
canvas.width | Buffer width in pixels (CSS pixels × DPR) |
canvas.height | Buffer height in pixels |
ctx.canvas | Back-reference to the canvas element |
Drawing State (save / restore)
ctx.save(); // push state: transforms, clip, all style properties ctx.restore(); // pop state // Stackable ctx.save(); ctx.translate(50, 50); ctx.save(); ctx.rotate(Math.PI / 4); ctx.fillRect(-20, -20, 40, 40); ctx.restore(); ctx.restore();
Transforms
ctx.translate(x, y); ctx.rotate(angleRad); // clockwise ctx.scale(sx, sy); // Set transform matrix directly (replaces current) ctx.setTransform(a, b, c, d, e, f); // [a c e / b d f / 0 0 1] ctx.setTransform(new DOMMatrix()); // Multiply into current transform ctx.transform(a, b, c, d, e, f); // Read current transform const m = ctx.getTransform(); // DOMMatrix ctx.resetTransform(); // identity
Rectangles
ctx.fillRect(x, y, w, h); ctx.strokeRect(x, y, w, h); ctx.clearRect(x, y, w, h); // erase to transparent
Paths
ctx.beginPath(); // clear current path ctx.moveTo(x, y); ctx.lineTo(x, y); ctx.arc(cx, cy, radius, startAngle, endAngle, anticlockwise); ctx.arcTo(x1, y1, x2, y2, radius); // rounded corner ctx.ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, anticlockwise); ctx.rect(x, y, w, h); ctx.roundRect(x, y, w, h, radii); // CSS-style border-radius (modern) ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); // cubic Bézier ctx.quadraticCurveTo(cpx, cpy, x, y); // quadratic Bézier ctx.closePath(); // line back to start ctx.fill('nonzero'); // 'nonzero' (default) | 'evenodd' ctx.stroke(); ctx.clip('nonzero'); // clip to path ctx.isPointInPath(x, y); // boolean ctx.isPointInStroke(x, y); // boolean
Path2D
const p = new Path2D(); p.arc(50, 50, 30, 0, Math.PI * 2); p.addPath(otherPath, new DOMMatrix().translate(100, 0)); const svgPath = new Path2D('M 10 10 L 90 90'); ctx.fill(p); ctx.stroke(p); ctx.clip(p); ctx.isPointInPath(p, x, y);
Fill and Stroke Styles
ctx.fillStyle = 'red'; ctx.fillStyle = '#ff0000'; ctx.fillStyle = 'rgba(255, 0, 0, 0.5)'; ctx.fillStyle = ctx.createLinearGradient(x0, y0, x1, y1); ctx.fillStyle = ctx.createRadialGradient(x0, y0, r0, x1, y1, r1); ctx.fillStyle = ctx.createConicGradient(startAngle, x, y); ctx.fillStyle = ctx.createPattern(image, 'repeat'); // 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat' ctx.strokeStyle = /* same options as fillStyle */; // Gradients const g = ctx.createLinearGradient(0, 0, 200, 0); g.addColorStop(0, 'red'); g.addColorStop(0.5, 'yellow'); g.addColorStop(1, 'blue'); ctx.fillStyle = g;
Line Style Properties
| Property | Values | Default |
|---|---|---|
ctx.lineWidth | number | 1 |
ctx.lineCap | 'butt' 'round' 'square' | 'butt' |
ctx.lineJoin | 'miter' 'round' 'bevel' | 'miter' |
ctx.miterLimit | number | 10 |
ctx.setLineDash([5, 3]) | — | — |
ctx.getLineDash() | number[] | [] |
ctx.lineDashOffset | number | 0 |
Shadows
ctx.shadowOffsetX = 4; ctx.shadowOffsetY = 4; ctx.shadowBlur = 8; ctx.shadowColor = 'rgba(0,0,0,0.5)'; // Disable: set blur and offsets back to 0 ctx.shadowColor = 'transparent';
Text
ctx.font = 'bold 16px sans-serif'; // CSS font shorthand ctx.textAlign = 'left'; // 'left' | 'right' | 'center' | 'start' | 'end' ctx.textBaseline = 'alphabetic'; // 'top' | 'hanging' | 'middle' | 'alphabetic' | 'ideographic' | 'bottom' ctx.direction = 'ltr'; // 'ltr' | 'rtl' | 'inherit' ctx.letterSpacing = '2px'; // CSS string (modern) ctx.wordSpacing = '4px'; // CSS string (modern) ctx.fillText('Hello', x, y, maxWidth?); ctx.strokeText('Hello', x, y, maxWidth?); const m = ctx.measureText('Hello'); m.width; m.actualBoundingBoxAscent; m.actualBoundingBoxDescent; m.fontBoundingBoxAscent; m.fontBoundingBoxDescent;
Images and Pixels
// drawImage(source, dx, dy) ctx.drawImage(img, 0, 0); // drawImage(source, dx, dy, dw, dh) ctx.drawImage(img, 0, 0, 200, 200); // drawImage(source, sx, sy, sw, sh, dx, dy, dw, dh) — crop + scale ctx.drawImage(video, sx, sy, sw, sh, dx, dy, dw, dh); // Source types: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement, // ImageBitmap, OffscreenCanvas, VideoFrame // Pixel data const imageData = ctx.getImageData(x, y, w, h); const { data, width, height } = imageData; // data is Uint8ClampedArray: [R, G, B, A, R, G, B, A, ...] for (let i = 0; i < data.length; i += 4) { data[i] // R data[i + 1] // G data[i + 2] // B data[i + 3] // A (0–255) } ctx.putImageData(imageData, dx, dy); ctx.putImageData(imageData, dx, dy, sx, sy, sw, sh); // dirty rect // Create blank ImageData const blank = ctx.createImageData(w, h); const copy = ctx.createImageData(existingImageData);
Compositing
ctx.globalAlpha = 0.5; // 0–1 ctx.globalCompositeOperation = 'source-over'; // default // Values: 'source-over' | 'source-in' | 'source-out' | 'source-atop' // 'destination-over' | 'destination-in' | 'destination-out' | 'destination-atop' // 'lighter' | 'copy' | 'xor' // 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' // 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' // 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity'
Filters
ctx.filter = 'blur(4px) brightness(0.8) contrast(120%) grayscale(50%)'; ctx.filter = 'none'; // reset // Full CSS filter syntax supported
OffscreenCanvas
// Main thread const offscreen = new OffscreenCanvas(800, 600); const ctx = offscreen.getContext('2d'); ctx.fillRect(0, 0, 100, 100); const bitmap = await offscreen.transferToImageBitmap(); // Draw to on-screen canvas mainCtx.drawImage(bitmap, 0, 0); // Transfer to Worker (zero-copy) const canvas = document.getElementById('c'); const offscreen2 = canvas.transferControlToOffscreen(); worker.postMessage({ canvas: offscreen2 }, [offscreen2]); // Inside worker onmessage = e => { const ctx = e.data.canvas.getContext('2d'); // draw — commits directly to screen };
Export / toDataURL / toBlob
canvas.toDataURL('image/png'); // base64 PNG canvas.toDataURL('image/jpeg', 0.8); // JPEG quality 0–1 canvas.toDataURL('image/webp', 0.9); // WebP canvas.toBlob(blob => { const url = URL.createObjectURL(blob); a.href = url; a.download = 'image.png'; a.click(); }, 'image/png'); // OffscreenCanvas const blob = await offscreen.convertToBlob({ type: 'image/webp', quality: 0.9 });
Animation Loop
let rafId; function loop(timestamp) { ctx.clearRect(0, 0, canvas.width, canvas.height); draw(timestamp); rafId = requestAnimationFrame(loop); } rafId = requestAnimationFrame(loop); // Stop cancelAnimationFrame(rafId);
ImageBitmap
const bitmap = await createImageBitmap(blob, { resizeWidth: 200, resizeHeight: 200 }); const bitmap2 = await createImageBitmap(img, sx, sy, sw, sh); ctx.drawImage(bitmap, 0, 0); bitmap.close(); // free memory