feat: embed surface — export in-canvas affordances + transparent/faint-ink viewer support

Lets a host mount the editor's real editing experience on a bare <Viewer>
without the full <Editor> shell.

editor: export Grid, NodeArrowHandles, MoveTool, ToolManager — the selection
handles, the kind-owned mover, the build-tool host, and the drafting grid that
feeds tools their grid:* pointer events. See the doc comment in index.tsx for
how they cooperate with host camera controls and selection.

viewer: two opt-in, non-persisted presentation flags (both default off, so the
editor and every other consumer are unchanged):
- transparentBackground / <Viewer transparent>: emit premultiplied RGBA masked
  by geometry + outline alpha (outputColorTransform off on that path) so the
  scene can float on any page background. ACES tone-mapping makes a true-white
  opaque background impossible, hence transparency.
- inkOpacity: override the per-mode ink-edge opacity.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aymeric Rabot
2026-06-17 11:07:43 -04:00
committed by Wassim SAMAD
co-authored by Claude Opus 4.8
parent 8775734aa8
commit 3cb37c98cd
4 changed files with 83 additions and 6 deletions
+13
View File
@@ -75,6 +75,13 @@ type ViewerState = {
showGrid: boolean
setShowGrid: (show: boolean) => void
transparentBackground: boolean
setTransparentBackground: (transparent: boolean) => void
// Embed-controlled ink-edge opacity override (null = use the per-mode default).
inkOpacity: number | null
setInkOpacity: (opacity: number | null) => void
projectId: string | null
setProjectId: (id: string | null) => void
projectPreferences: Record<
@@ -283,6 +290,12 @@ const useViewer = create<ViewerState>()(
return { showGrid: show, projectPreferences }
}),
transparentBackground: false,
setTransparentBackground: (transparent) => set({ transparentBackground: transparent }),
inkOpacity: null,
setInkOpacity: (opacity) => set({ inkOpacity: opacity }),
projectId: null,
setProjectId: (id) =>
set((state) => {