Editor has no reference image backdrop — user tracing a hand-drawn sketch on the canvas has no way to load the sketch as a backdrop, the editor canvas is always blank (or shows the path being drawn) #245

Closed
opened 2026-10-04 02:38:00 +00:00 by Mark · 1 comment
Owner

Finding

src/components/editor/EditorCanvas.tsx renders paths on a blank canvas. There's no:

  • onDrop handler (per my earlier scan: grep -n 'onDrop' src/components/editor/EditorCanvas.tsx returns 0)
  • "Load reference image" button in the toolbar
  • Backdrop state in the editor's state

grep -n 'referenceImage\|traceImage\|backdrop' src/components/editor/ returns 0.

A user who wants to digitize a hand-drawn sketch:

  • Scans the sketch (or takes a phone photo)
  • The sketch is on their disk
  • The editor's canvas is blank
  • They have to switch to the Workspace, upload the sketch, run auto-digitize, get the result, then go back to the Editor to tweak the result
  • If they want to TUNE the auto-digitize output, they're stuck — they can only see the vector output, not the original

Standard vector editors (Illustrator, Inkscape, Figma) all have a "trace image" or "reference image" affordance: load an image, place it on the canvas, lock it (so clicks pass through to the vectors), use it as a visual reference.

Where

  • Editor canvas: src/components/editor/EditorCanvas.tsx (no image loading)
  • Editor toolbar: src/components/editor/EditorToolbar.tsx (no "Load reference" button)
  • Editor state: src/pages/Editor.tsx (no reference image state)

Suggested fix shape

  1. State: add referenceImage: { src: string; opacity: number; visible: boolean } | null to the editor's state.

  2. UI: add a "Load reference image..." button to the editor toolbar (next to the existing file actions):

<button
  onClick={onLoadReferenceImage}
  title="Load a reference image (sketch, photo) as a backdrop"
>
  <ImagePlus size={14} />
  Reference
</button>

onLoadReferenceImage opens a file picker, accepts PNG/JPG/SVG/BMP, reads as data URL, sets referenceImage.

  1. Rendering: in canvasRenderer.ts, draw referenceImage first (behind the paths), with opacity: referenceImage.opacity and a "lock" mode where pointer events pass through to the paths.

  2. Right panel: add a "Reference Image" section with:

  • Opacity slider (0-100%)
  • Lock toggle (lock the image so clicks pass through; otherwise the image is the target)
  • Remove button
  1. Drag-drop: the editor canvas's onDrop accepts a file and treats it as a reference image (vs. the workspace's "load as design" semantics).

Severity

Medium. The auto-digitize path doesn't help users who want to tune the output. Power users with hand-drawn references notice.

Discovered by

Gap analysis (2026-10-02) of editor image affordances.

  • The Workspace has the source image as a backdrop (per the useWorkspace state). The editor doesn't.
  • The Gallery has an upload affordance for designs (per #148). The editor's reference image is the parallel affordance.
  • The "load different design" flow (#228) is a different surface (load a saved design, not a raw image).
## Finding `src/components/editor/EditorCanvas.tsx` renders paths on a blank canvas. There's no: - `onDrop` handler (per my earlier scan: `grep -n 'onDrop' src/components/editor/EditorCanvas.tsx` returns 0) - "Load reference image" button in the toolbar - Backdrop state in the editor's state `grep -n 'referenceImage\|traceImage\|backdrop' src/components/editor/` returns 0. A user who wants to digitize a hand-drawn sketch: - Scans the sketch (or takes a phone photo) - The sketch is on their disk - The editor's canvas is blank - They have to switch to the Workspace, upload the sketch, run auto-digitize, get the result, then go back to the Editor to tweak the result - If they want to TUNE the auto-digitize output, they're stuck — they can only see the vector output, not the original Standard vector editors (Illustrator, Inkscape, Figma) all have a "trace image" or "reference image" affordance: load an image, place it on the canvas, lock it (so clicks pass through to the vectors), use it as a visual reference. ## Where - Editor canvas: `src/components/editor/EditorCanvas.tsx` (no image loading) - Editor toolbar: `src/components/editor/EditorToolbar.tsx` (no "Load reference" button) - Editor state: `src/pages/Editor.tsx` (no reference image state) ## Suggested fix shape 1. **State**: add `referenceImage: { src: string; opacity: number; visible: boolean } | null` to the editor's state. 2. **UI**: add a "Load reference image..." button to the editor toolbar (next to the existing file actions): ```tsx <button onClick={onLoadReferenceImage} title="Load a reference image (sketch, photo) as a backdrop" > <ImagePlus size={14} /> Reference </button> ``` `onLoadReferenceImage` opens a file picker, accepts PNG/JPG/SVG/BMP, reads as data URL, sets `referenceImage`. 3. **Rendering**: in `canvasRenderer.ts`, draw `referenceImage` first (behind the paths), with `opacity: referenceImage.opacity` and a "lock" mode where pointer events pass through to the paths. 4. **Right panel**: add a "Reference Image" section with: - Opacity slider (0-100%) - Lock toggle (lock the image so clicks pass through; otherwise the image is the target) - Remove button 5. **Drag-drop**: the editor canvas's `onDrop` accepts a file and treats it as a reference image (vs. the workspace's "load as design" semantics). ## Severity Medium. The auto-digitize path doesn't help users who want to tune the output. Power users with hand-drawn references notice. ## Discovered by Gap analysis (2026-10-02) of editor image affordances. ## Related - The Workspace has the source image as a backdrop (per the `useWorkspace` state). The editor doesn't. - The Gallery has an upload affordance for designs (per #148). The editor's reference image is the parallel affordance. - The "load different design" flow (#228) is a different surface (load a saved design, not a raw image).
Author
Owner

Fix landed on origin/main; closing it out (watcher for kanban t_ebec167c).

Two commits deliver the Editor reference-image affordance:

  • c074f86 fix(#245): Editor reference image hooks — file picker + draw + type re-export
  • a4391f1 test(#245): pin Editor reference-image affordance (toolbar Reference button + referenceImage helpers)

A prerequisite CI fix was also linked here:

  • dffc31e fix(ci): restore ImagePolyfill + suppress TS6133 on indirectly-used members

Surface added (c074f86):

  • File picker plumbing: hidden + visible 'Reference' toolbar button that proxies the click (gated by onLoadReferenceImage prop so existing toolbars are unaffected).
  • canvasRenderer.drawReferenceImage entry point with getCachedReferenceImage decoder warm-up so the first draw doesn't stall.
  • ReferenceImage type re-exported from EditorCanvas / EditorToolbar / Editor.
  • Editor.tsx onLoadReferenceImage hook — builds the bitmap via buildReferenceImage (FileReader, offline-safe, no network fetch).

Test pinning (a4391f1): 13/13 vitest passing in src/pages/issue-245.test.tsx covering toolbar Reference button + referenceImage helpers. Lint clean across touched files.

Both c074f86 and a4391f1 verified as ancestors of origin/main at git merge-base --is-ancestor. The kilo-gsd run that produced these commits died mid-flow after pushing but before closing; the watcher is closing now since the fix is complete and on main.

Fix landed on origin/main; closing it out (watcher for kanban t_ebec167c). Two commits deliver the Editor reference-image affordance: - c074f86 fix(#245): Editor reference image hooks — file picker + draw + type re-export - a4391f1 test(#245): pin Editor reference-image affordance (toolbar Reference button + referenceImage helpers) A prerequisite CI fix was also linked here: - dffc31e fix(ci): restore ImagePolyfill + suppress TS6133 on indirectly-used members Surface added (c074f86): - File picker plumbing: hidden <input type='file'> + visible 'Reference' toolbar button that proxies the click (gated by onLoadReferenceImage prop so existing toolbars are unaffected). - canvasRenderer.drawReferenceImage entry point with getCachedReferenceImage decoder warm-up so the first draw doesn't stall. - ReferenceImage type re-exported from EditorCanvas / EditorToolbar / Editor. - Editor.tsx onLoadReferenceImage hook — builds the bitmap via buildReferenceImage (FileReader, offline-safe, no network fetch). Test pinning (a4391f1): 13/13 vitest passing in src/pages/issue-245.test.tsx covering toolbar Reference button + referenceImage helpers. Lint clean across touched files. Both c074f86 and a4391f1 verified as ancestors of origin/main at git merge-base --is-ancestor. The kilo-gsd run that produced these commits died mid-flow after pushing but before closing; the watcher is closing now since the fix is complete and on main.
Mark 2026-10-05 08:11:32 +00:00
Sign in to join this conversation.
No description provided.