Details & Tips
How Undo/Redo actually works: before each committed drawing action (a completed pen or eraser stroke, a committed rectangle or circle, or a placed piece of text), the tool takes a full snapshot of the canvas using `canvas.toDataURL()` and pushes it onto a history stack — this captures exactly what the canvas looked like *before* that action started. Clicking Undo pushes the canvas's *current* state onto a separate redo stack, then pops the most recent entry off the history stack and redraws the canvas back to it. Clicking Redo does the reverse: it pushes the current state onto history and restores the most recent entry popped off the redo stack. Starting any *new* drawing action after an undo clears the redo stack completely — this is standard, expected undo/redo behaviour: once you've drawn something new, the version you'd previously undone past is gone, the same way it works in any text editor or design tool. The history stack is capped at 30 entries; once full, adding a new one silently drops the single oldest entry first, so the tool never accumulates unbounded memory even through a very long drawing session.
Rectangles and circles are drawn with a live preview: while you drag, the in-progress shape is rendered on a separate, invisible overlay canvas stacked exactly on top of the main one, so you can see exactly where it'll land before committing. Releasing the pointer draws the final shape onto the real canvas and clears the overlay. A shape smaller than 3 pixels in either dimension (an accidental click rather than a deliberate drag) is discarded rather than committed, so a stray tap doesn't leave a tiny invisible mark or waste an undo step.
The Text tool works differently from the others: clicking a point on the canvas opens a simple prompt for you to type into, and the typed text is immediately drawn onto the canvas at that point using the current color, with its size controlled by the same stroke-width control used for Pen and Eraser (2px stroke draws small 12px text, 16px stroke draws large 96px text — a deliberate reuse of one control rather than adding a separate font-size slider). The moment text is placed, it is pixels like everything else on the canvas — there's no later "double-click to edit this text" step, which is an accepted, expected limitation for a freehand whiteboard rather than a document editor.
Autosave: after every committed action, the canvas is also saved as a data URL to this browser's `localStorage`, and restored automatically the next time you open this page. Because `localStorage` has a browser-enforced size limit (typically 5-10MB per site, shared across everything else the site stores there), the autosave checks the size of the encoded image first and silently skips saving — no error shown — if it would exceed roughly 4MB, since a giant, extremely detailed drawing that no longer fits comfortably is better left un-autosaved than risking breaking storage for the rest of the site. This autosave is strictly local to this one browser on this one device: it is never uploaded anywhere, it is not synced between devices or browsers, and clearing your browser's site data (or using a different browser or private/incognito window) will not show a previously autosaved drawing.
Worked example tracing the undo/redo logic exactly: draw shape A (history becomes [blank-canvas]), draw shape B (history becomes [blank-canvas, A]). Click Undo: the canvas now shows A, and redo stack holds [A+B]. Now draw shape C instead of redoing: history becomes [blank-canvas, A] again (the pre-C state, A, gets pushed) and — critically — the redo stack is cleared the moment a new action is drawn, so clicking Redo at this point does nothing, exactly as expected, since B no longer exists in any future the tool can restore.