Phase 3 · Browser DevelopmentModule 22~42 min read

Canvas, Media & Rich Interfaces

Create graphics and work responsibly with browser media capabilities.

What you'll learn

Canvas and media APIs unlock custom graphics, animation, audio, video, and capture. They also demand explicit sizing, scheduling, permission, and cleanup decisions.

By the end of this lesson, you'll be able to:

  • Draw resolution-aware canvas graphics
  • Animate with requestAnimationFrame
  • Manage media and object-URL lifecycles

Core mental model

Use this decision table as a compact reference. Focus on what each tool means and when it earns its place in production code.

ConceptWhat it meansDecision rule
Canvas bitmapDrawing surface has intrinsic and CSS sizesScale for devicePixelRatio when sharpness matters
Animation frameCallback scheduled before browser paintUse for visual animation, not setInterval
Media streamTrack collection from devices or networkStop every track after use

Professional workflow

Build the behavior in small, observable steps. Each step should leave something you can inspect or test.

  1. Describe the rich media lifecycle boundary: inputs, outputs, state, timing, and expected failures.
  2. Implement the smallest correct path with names that expose intent.
  3. Add edge cases and failure handling before introducing abstractions.
  4. Verify behavior with realistic data and one deliberately adversarial example.
  5. Refactor only after the observable behavior is protected.

Make behavior observable

Before optimizing or abstracting, make inputs, outputs, state changes, timing, and failure paths visible. JavaScript becomes much easier to reason about when hidden work is exposed.

Guided code lab

Draw a progress ring

The canvas uses a stable coordinate system and redraws from state.

progress-ring.js
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
function draw(progress) {
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.beginPath();
  context.arc(60, 60, 45, -Math.PI / 2, -Math.PI / 2 + Math.PI * 2 * progress);
  context.stroke();
}
draw(0.75);

Schedule and cancel animation

The returned frame ID gives the feature a cleanup handle.

animation.js
let frameId;
function tick(time) {
  const progress = (time % 2000) / 2000;
  draw(progress);
  frameId = requestAnimationFrame(tick);
}
frameId = requestAnimationFrame(tick);
// cancelAnimationFrame(frameId) during teardown

Production practice

Contract

Keep the rich media lifecycle API explicit: accepted state, emitted events, DOM ownership, and cleanup.

Verification

Test with keyboard input, missing elements, repeated initialization, and teardown—not only a mouse happy path.

Operations

Measure user-visible latency and remove listeners, observers, object URLs, or media tracks when the feature ends.

Common failure mode

Leaving animation loops, MediaStream tracks, or object URLs alive after navigation wastes CPU, camera access, and memory.

Independent workshop

Build a keyboard-controlled canvas progress timer with pause and reduced-motion support.

Your finished workshop must include:

  • requestAnimationFrame scheduling
  • A cancellation path
  • A text alternative synchronized with the graphic

Definition of done

Demonstrate the happy path and at least two edge cases, keep responsibilities separated, and add a short note explaining one design choice.

Recap & quick check

Key takeaways

  • Canvas is bitmap-based
  • Animation frames align with rendering
  • Media access is permission gated
  • Rich-media resources require cleanup

Quick check

1. Which scheduler fits visual animation?

2. How do you release camera use?

3. Does canvas supply semantic content automatically?

Keep the workshop. Later modules deliberately build on these decisions, so each exercise can become part of your final portfolio architecture.