HTML Graphics
HTML Canvas Basics
The HTML <canvas> element is a blank rectangle of pixels that you paint on with JavaScript. Unlike SVG, there are no shape elements - you get a 2D drawing context and issue commands like "fill a rectangle here" or "stroke this path." Canvas is immediate-mode: once something is drawn it becomes plain pixels with no memory of the shape. That makes Canvas ideal for games, data-heavy visualisations, image manipulation and animation. This page walks through getting a context and drawing rectangles, paths, arcs, text, gradients and images, with a complete runnable HTML document for each.
What is Canvas?
A <canvas> is an empty bitmap you control from JavaScript. You place the element in HTML, grab it in script, ask it for a drawing context, and then call methods on that context to paint. Nothing appears until your JavaScript runs, and the result is a flat grid of pixels - the browser does not remember that you drew a circle, only that certain pixels are now blue.
The <canvas> Element and getContext('2d')
Always set the canvas width and height as HTML attributes (not just CSS), because those attributes define the pixel resolution of the drawing surface. Then call getContext('2d') to obtain the CanvasRenderingContext2D object - your paintbrush. Every drawing call goes through that context.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>My First Canvas</title></head>
<body style="background:#0f172a;display:grid;place-items:center;min-height:100vh;margin:0;">
<canvas id="c" width="300" height="200" style="background:#1e293b;border-radius:8px;"></canvas>
<script>
const ctx = document.getElementById('c').getContext('2d');
ctx.fillStyle = '#38bdf8';
ctx.fillRect(50, 40, 200, 120);
ctx.fillStyle = '#f8fafc';
ctx.font = '20px Arial';
ctx.fillText('Hello Canvas!', 80, 105);
</script>
</body>
</html>Setting size with CSS (style="width:300px") only stretches the bitmap and makes it blurry. Set the pixel resolution with the HTML width and height attributes.
The Coordinate System
Canvas uses the same coordinate system as SVG: the origin (0, 0) is the top-left corner, x increases to the right, and y increases downward. A canvas that is 300 wide and 200 tall has its bottom-right corner at (300, 200).
Drawing Rectangles
Rectangles are the only shape with dedicated one-call methods: fillRect(x, y, w, h) paints a filled box, strokeRect(x, y, w, h) draws just the outline, and clearRect(x, y, w, h) erases a region back to transparent. Set fillStyle and strokeStyle before drawing.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Canvas Rectangles</title></head>
<body style="background:#f1f5f9;text-align:center;">
<canvas id="c" width="360" height="160" style="background:#fff;"></canvas>
<script>
const ctx = document.getElementById('c').getContext('2d');
ctx.fillStyle = '#6366f1';
ctx.fillRect(20, 30, 100, 100);
ctx.strokeStyle = '#ec4899';
ctx.lineWidth = 8;
ctx.strokeRect(140, 30, 100, 100);
ctx.fillStyle = '#22c55e';
ctx.fillRect(260, 30, 100, 100);
ctx.clearRect(285, 55, 50, 50);
</script>
</body>
</html>Paths and Lines
For anything other than rectangles you build a path. Call beginPath() to start, moveTo(x, y) to lift the pen to a point, lineTo(x, y) to draw a segment, then closePath() to join back to the start. Finish with stroke() to draw the outline or fill() to flood the interior.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Canvas Paths</title></head>
<body style="background:#0f172a;text-align:center;">
<canvas id="c" width="360" height="180" style="background:#020617;"></canvas>
<script>
const ctx = document.getElementById('c').getContext('2d');
// zig-zag line
ctx.beginPath();
ctx.moveTo(20, 150);
ctx.lineTo(60, 40);
ctx.lineTo(100, 150);
ctx.lineTo(140, 40);
ctx.lineTo(180, 150);
ctx.strokeStyle = '#38bdf8';
ctx.lineWidth = 5;
ctx.stroke();
// filled triangle
ctx.beginPath();
ctx.moveTo(280, 40);
ctx.lineTo(340, 150);
ctx.lineTo(220, 150);
ctx.closePath();
ctx.fillStyle = '#f472b6';
ctx.fill();
</script>
</body>
</html>Arcs and Circles
There is no circle method - you draw circles and arcs with arc(x, y, radius, startAngle, endAngle). Angles are in radians, so a full circle is 0 to Math.PI * 2. Call arc() inside a path, then fill() or stroke().
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Canvas Arcs</title></head>
<body style="background:#f8fafc;text-align:center;">
<canvas id="c" width="360" height="180" style="background:#fff;"></canvas>
<script>
const ctx = document.getElementById('c').getContext('2d');
// full circle
ctx.beginPath();
ctx.arc(70, 90, 50, 0, Math.PI * 2);
ctx.fillStyle = '#0ea5e9';
ctx.fill();
// ring (stroked circle)
ctx.beginPath();
ctx.arc(180, 90, 50, 0, Math.PI * 2);
ctx.strokeStyle = '#a855f7';
ctx.lineWidth = 12;
ctx.stroke();
// pac-man wedge
ctx.beginPath();
ctx.moveTo(290, 90);
ctx.arc(290, 90, 50, 0.25 * Math.PI, 1.75 * Math.PI);
ctx.closePath();
ctx.fillStyle = '#facc15';
ctx.fill();
</script>
</body>
</html>To convert degrees to radians: radians = degrees * Math.PI / 180. So 90 degrees is Math.PI / 2.
Drawing Text
Set the font property (same syntax as CSS font), then call fillText(text, x, y) for solid characters or strokeText(text, x, y) for outlines. textAlign and textBaseline control positioning around the given point.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Canvas Text</title></head>
<body style="background:#111827;text-align:center;">
<canvas id="c" width="360" height="150" style="background:#1f2937;"></canvas>
<script>
const ctx = document.getElementById('c').getContext('2d');
ctx.textAlign = 'center';
ctx.font = 'bold 46px Arial';
ctx.fillStyle = '#facc15';
ctx.fillText('Canvas', 180, 70);
ctx.strokeStyle = '#38bdf8';
ctx.lineWidth = 1.5;
ctx.font = 'bold 30px Arial';
ctx.strokeText('outlined text', 180, 115);
</script>
</body>
</html>Gradients
Canvas gradients are objects you create with createLinearGradient(x0, y0, x1, y1) or createRadialGradient(...). Add colours with addColorStop(offset, colour) where offset runs 0 to 1, then assign the gradient to fillStyle or strokeStyle.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Canvas Gradients</title></head>
<body style="background:#020617;text-align:center;">
<canvas id="c" width="360" height="200" style="background:#000;"></canvas>
<script>
const ctx = document.getElementById('c').getContext('2d');
// linear gradient rectangle
const lin = ctx.createLinearGradient(20, 0, 190, 0);
lin.addColorStop(0, '#f97316');
lin.addColorStop(0.5, '#ec4899');
lin.addColorStop(1, '#8b5cf6');
ctx.fillStyle = lin;
ctx.fillRect(20, 40, 150, 120);
// radial gradient circle
const rad = ctx.createRadialGradient(270, 100, 8, 270, 100, 70);
rad.addColorStop(0, '#fff7ed');
rad.addColorStop(1, '#f59e0b');
ctx.fillStyle = rad;
ctx.beginPath();
ctx.arc(270, 100, 70, 0, Math.PI * 2);
ctx.fill();
</script>
</body>
</html>Drawing an Image
You can paint any loaded image onto the canvas with drawImage(image, x, y). Because images load asynchronously, wait for the load event before drawing. This example generates a small SVG data-URL image so it runs with no external files.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Canvas drawImage</title></head>
<body style="background:#f1f5f9;text-align:center;">
<canvas id="c" width="320" height="200" style="background:#fff;"></canvas>
<script>
const ctx = document.getElementById('c').getContext('2d');
const img = new Image();
img.onload = function () {
ctx.drawImage(img, 60, 30, 200, 120);
ctx.fillStyle = '#334155';
ctx.font = '16px Arial';
ctx.textAlign = 'center';
ctx.fillText('drawn with drawImage()', 160, 180);
};
// an inline SVG image as a data URL - no external file needed
img.src = 'data:image/svg+xml,' + encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" width="200" height="120">' +
'<rect width="200" height="120" fill="#6366f1"/>' +
'<circle cx="100" cy="60" r="40" fill="#facc15"/></svg>'
);
</script>
</body>
</html>Canvas vs SVG
| Aspect | Canvas | SVG |
|---|---|---|
| Type | Immediate-mode pixels | Retained-mode DOM elements |
| Drawn with | JavaScript context calls | XML markup (+ optional JS/CSS) |
| After drawing | Flat pixels, no shape memory | Every shape is still an element |
| Interactivity | Manual hit-testing in JS | Click / hover / CSS per shape |
| Scaling | Fixed resolution; redraw to resize | Sharp at any size automatically |
| Strength | Thousands of objects, games, effects | Charts, icons, diagrams, crisp UI |
Key Takeaways
- Canvas is a pixel bitmap you paint on with JavaScript via getContext('2d').
- Set resolution with the width/height HTML attributes, not CSS.
- Rectangles have direct methods: fillRect, strokeRect, clearRect.
- Everything else is a path: beginPath, moveTo, lineTo, arc, then fill or stroke.
- arc() draws circles and arcs using radians (a full circle is 0 to Math.PI * 2).
- fillText/strokeText draw text; createLinearGradient/createRadialGradient add gradients.
- drawImage paints images, but wait for the image load event first.
- Choose Canvas for pixel-heavy, high-count, animated graphics; choose SVG for crisp, interactive vector UI.
