← Back to Tutorials Chapter 12

Graphics

JavaScript provides two primary ways to create graphics in the browser: Canvas (pixel-based, imperative) and SVG (vector-based, declarative). This chapter covers both with practical drawing examples.

HTML Canvas

The <canvas> element provides a bitmap drawing surface. You access its 2D rendering context through JavaScript and issue drawing commands.

Getting the Context

<canvas id="myCanvas" width="400" height="300"></canvas>
<script>
  const canvas = document.getElementById('myCanvas');
  const ctx = canvas.getContext('2d');
</script>

Drawing Shapes

// Rectangle
ctx.fillStyle = '#3b82f6';
ctx.fillRect(20, 20, 150, 100);
ctx.strokeStyle = '#1e293b';
ctx.lineWidth = 3;
ctx.strokeRect(20, 20, 150, 100);

// Circle (arc)
ctx.beginPath();
ctx.arc(300, 70, 40, 0, Math.PI * 2);
ctx.fillStyle = '#22c55e';
ctx.fill();
ctx.stroke();

Paths

ctx.beginPath();
ctx.moveTo(50, 200);
ctx.lineTo(200, 250);
ctx.lineTo(100, 280);
ctx.closePath();
ctx.fillStyle = '#eab308';
ctx.fill();

Text

ctx.font = 'bold 24px Arial';
ctx.fillStyle = '#0f172a';
ctx.fillText('Hello Canvas!', 50, 50);
ctx.strokeText('Hello Canvas!', 50, 90);

Colors & Gradients

const gradient = ctx.createLinearGradient(0, 0, 400, 0);
gradient.addColorStop(0, '#ff0000');
gradient.addColorStop(1, '#0000ff');
ctx.fillStyle = gradient;
ctx.fillRect(0, 200, 400, 50);

SVG (Scalable Vector Graphics)

SVG describes 2D graphics using XML markup. Elements are part of the DOM and can be styled with CSS and manipulated with JavaScript.

Inline SVG Shapes

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <rect x="10" y="10" width="80" height="80" fill="#3b82f6" rx="8" />
  <circle cx="150" cy="50" r="40" fill="#22c55e" />
  <polygon points="100,150 50,190 150,190" fill="#eab308" />
</svg>

SVG Groups & Transforms

<svg width="300" height="200" xmlns="http://www.w3.org/2000/svg">
  <g transform="translate(20, 20)">
    <rect width="100" height="60" fill="#f59e0b" />
    <text x="50" y="35" text-anchor="middle" fill="white">Group</text>
  </g>
  <g transform="rotate(45, 200, 80)">
    <rect x="150" y="40" width="80" height="80" fill="#ef4444" />
  </g>
</svg>
Canvas and SVG graphics examples

Drawing Examples

Bar Chart (Canvas)

const data = [30, 85, 55, 70, 45];
const barWidth = 50;
const gap = 20;
ctx.fillStyle = '#3b82f6';
data.forEach((val, i) => {
  const x = 30 + i * (barWidth + gap);
  const h = val * 2;
  ctx.fillRect(x, 250 - h, barWidth, h);
});

Smiley Face (Canvas)

// Face
ctx.beginPath();
ctx.arc(200, 150, 80, 0, Math.PI * 2);
ctx.fillStyle = '#fef9c3';
ctx.fill();
ctx.stroke();
// Eyes
ctx.fillStyle = '#1e293b';
ctx.beginPath(); ctx.arc(170, 130, 8, 0, Math.PI * 2); ctx.fill();
ctx.beginPath(); ctx.arc(230, 130, 8, 0, Math.PI * 2); ctx.fill();
// Smile
ctx.beginPath();
ctx.arc(200, 150, 50, 0.1 * Math.PI, 0.9 * Math.PI);
ctx.stroke();

Clock (Canvas)

function drawClock() {
  const now = new Date();
  const sec = now.getSeconds() * (Math.PI / 30);
  const min = now.getMinutes() * (Math.PI / 30);
  const hr = now.getHours() * (Math.PI / 6);

  ctx.clearRect(0, 0, 400, 400);
  ctx.beginPath();
  ctx.arc(200, 200, 150, 0, Math.PI * 2);
  ctx.stroke();

  // Hour hand, minute hand, second hand
  ctx.beginPath(); ctx.moveTo(200, 200); ctx.lineTo(200 + 80 * Math.sin(hr), 200 - 80 * Math.cos(hr)); ctx.stroke();
  ctx.beginPath(); ctx.moveTo(200, 200); ctx.lineTo(200 + 120 * Math.sin(min), 200 - 120 * Math.cos(min)); ctx.stroke();
  ctx.beginPath(); ctx.moveTo(200, 200); ctx.lineTo(200 + 140 * Math.sin(sec), 200 - 140 * Math.cos(sec)); ctx.stroke();
}

Canvas vs SVG Comparison

AspectCanvasSVG
RenderingPixel-basedVector-based
DOM integrationNoneFull DOM tree
PerformanceFast for many elementsBest for fewer, interactive elements
AccessibilityNot accessibleAccessible via ARIA
Use caseGames, image processingDiagrams, icons, charts

Exercise: Animated Bouncing Ball

Use the Canvas API to create a bouncing ball animation. The ball should start at the top-left corner and bounce off the edges of the canvas. Use requestAnimationFrame() for smooth animation. Add a second ball with a different colour and speed.