SketchFlow
A freeform canvas drawing and whiteboard application with hand-drawn aesthetics
SketchFlow is a browser-based drawing tool that combines the charm of hand-drawn illustrations with the precision of digital tools. Inspired by Excalidraw, the goal was to build a whiteboard experience that feels natural and organic rather than sterile and mechanical.
The application uses Rough.js to render shapes with a sketchy, hand-drawn quality, and perfect-freehand to capture pressure-sensitive strokes from pen and touch input. The result is a drawing tool where even simple rectangles and arrows look like they were drawn by hand on paper.
Everything runs client-side in the browser using the Canvas API. There's no server component — drawings can be exported to PNG for sharing. The architecture is designed around an immutable element state, making undo/redo trivial to implement.
The rendering pipeline has two layers: a static canvas for committed elements and a dynamic canvas for the element currently being drawn. This dual-canvas approach means only the active stroke needs per-frame rendering, while the background canvas is only repainted when the element list changes.
Element state is stored as an immutable array. Each user action produces a new array reference pushed onto a history stack. Undo pops the stack and restores the previous state; redo re-applies from a parallel redo stack. This pattern eliminates complex mutation tracking.
Pointer events are normalized across mouse, touch, and pen inputs using the Pointer Events API. For freehand strokes, raw pointer data is fed through perfect-freehand's algorithm, which outputs SVG path data rendered onto the canvas. Shape elements use Rough.js's generator to produce randomized path data that mimics hand drawing.