Drawing is the freeform medium: sketching, annotation, whiteboards, signatures. The input is a pen, a finger, or a mouse, and the output is whatever you render. It is the medium that feels most like a physical tool, so latency and pressure fidelity decide whether it feels good.
The 2D canvas API is small, but the input layer around it (Pointer Events, coalesced events, pressure, palm rejection) is where the craft is.
Each is one way to build it. None of them is the medium.
Draw, annotate, whiteboard. reference/Sketchpad.ts
Hand-drawn style whiteboard; the state of the art for collaborative sketching.
Pressure-sensitive stroke outlines from pointer input. The math behind brushes that feel right.
Infinite canvas SDK with a full editor on top.
--- name: medium-drawing description: "Build freeform drawing, annotation, and whiteboard surfaces on the web with Pointer Events and 2D canvas. Use when adding sketching, markup, or signatures. For data-driven node-link graphs and charts use medium-visualization instead." --- # Drawing as a medium ## What this medium does to the person Drawing makes the app a surface the hand thinks on. Latency and pressure fidelity decide whether it feels like a tool or a form; structure gets out of the way of the gesture. ## When to reach for this medium Choose drawing when people need to mark, point, sketch, or sign, and when structure would slow the gesture down. If the picture is computed from data rather than drawn by a hand, that is visualization, not drawing. ## Core browser APIs - Pointer Events (`pointerdown`/`move`/`up`) with `setPointerCapture` and `getCoalescedEvents()` - `pressure`, `tiltX`/`tiltY`, and `pointerType` for pen-aware rendering - 2D canvas with a `devicePixelRatio`-scaled backing store; `ResizeObserver` to refit ## UX rules that always apply - Strokes appear under the pointer with no visible lag; render incrementally, redraw fully only on undo or resize. - Pressure changes the width on pen and touch; mouse gets a steady width. - Undo and Clear are always visible. Undo removes the last stroke, not the last pixel. - Keep strokes as data so resize, export, and sync are replays. ## Reference instances Each is one way to speak this medium, cited as evidence. None of them is the medium. `reference/Sketchpad.ts` — pressure-aware brush, coalesced-event smoothing, swatches and size, undo and clear from a stroke list, DPR-correct backing store. It uses a few layout class names from the pool's stylesheet (`row`, `btn`, `status`, `frame`); without that stylesheet the logic still runs and the controls are unstyled. ## Gotchas - `touch-action: none` on the surface or the page scrolls. - Without DPR scaling everything looks blurry. - Never store only pixels; you lose undo and resolution.