Question presented to candidate:
"Build a simple drawing board, like a whiteboard: the user draws freehand on a <canvas> with a mouse, pen or finger, picks a colour and a brush size, can switch to an eraser, and has Undo, Redo and Clear buttons plus Ctrl+Z / Ctrl+Shift+Z. Finally they can export the drawing as a PNG. Walk me through how you store the drawing so that undo works."
Requirements:
- A canvas that stays sharp on high-density screens and scales with its container.
- Freehand strokes with Pointer Events (mouse, pen, touch); a tap draws a dot.
- Colour swatches, a size slider (2 to 40 px) and an eraser.
- Undo, Redo and Clear, where Clear itself can be undone; a new stroke after an undo discards the redo history.
- Keyboard shortcuts Ctrl/Cmd+Z and Ctrl/Cmd+Shift+Z (or Ctrl+Y).
- Export to PNG on a white background, offered as a download link.
What a strong answer should cover:
- Strokes stored as data (colour, size, tool, points) rather than pixel snapshots, and why that makes undo, redo and redraw cheap and exact.
- Two stacks (done / undone) and the rule that any new action clears redo; Clear modelled as an action.
- Drawing the live stroke incrementally from a ref or plain variable (no re-render per
pointermove), then a full repaint from data on commit, undo or redo. setPointerCapture,touch-action: none,getCoalescedEvents()for smooth fast strokes, and mapping client coordinates to canvas coordinates.devicePixelRatioscaling,destination-outfor the eraser, and compositing on white for export.- Trade-offs: replay cost for very long histories (snapshots or an offscreen cache), and memory if you stored
ImageDatainstead.
Clarifying questions expected:
- "How long can a session get? Thousands of strokes changes the redraw strategy."
- "Should the drawing survive a reload, or be shared live with other users?"
- "Does the eraser need to erase to transparent or to the background colour?"
Code / implementation expected: Yes. A working board with pointer drawing, stroke history with undo / redo / clear, tools and export.