The Board Model and Pointer-Based Dragging
AnyTool Sticky Notes Board keeps a single board object as its source of truth: a notes array, where each note carries an id, its text, a colour key, an x/y position, a width and height, a z stacking order and a pinned flag. Notes are rendered as absolutely-positioned cards on a large scrollable corkboard, layered by their z value. All movement uses Pointer Events rather than a drag library, so the same code handles mouse, touch and pen: pressing the note’s top bar captures the pointer and records the offset between the cursor and the note’s top-left corner, pointermove sets the note’s x/y to the cursor position minus that offset (clamped to the board), and pointerup releases the capture. A corner handle resizes the same way by tracking the start size and growing width/height by the cursor delta down to sensible minimums. Focusing or pressing a note raises its z above the others, a pinned note opts out of dragging, resizing and editing, and the board auto-grows to fit the furthest note so it never runs out of room.
- Board = { notes: Note[] }; Note = { id, text, color, x, y, w, h, z, pinned } — positions are stored, not derived
- Dragging uses Pointer Events (mouse / touch / pen): capture, record cursor-to-corner offset, update x/y on move
- A corner handle resizes by growing w/h from the cursor delta, clamped to minimum dimensions
- Focusing or pressing a note raises its z to the front; a pinned note can’t be dragged, resized or edited
- The board auto-grows to fit the furthest note; double-clicking empty space adds a note at that point
