# components/canvas/ — Canvas-Engine Der Canvas ist das Herzstück von LemonSpace. Er basiert auf `@xyflow/react` (React Flow) und synchronisiert seinen Zustand bidirektional mit Convex. --- ## Architektur ``` app/(app)/canvas/[canvasId]/page.tsx └── ← components/canvas/canvas-shell.tsx ├── Resizable Sidebar/Main Layout ← shadcn `resizable` ├── ← collapsible Rail/Fulllayout └── ← components/canvas/canvas.tsx ├── │ └── ← Haupt-Komponente (~1800 Zeilen) │ ├── Convex useQuery ← Realtime-Sync │ ├── nodeTypes Map ← node-types.ts │ ├── localStorage Cache ← canvas-local-persistence.ts │ ├── Interaction-Hooks ← canvas-*.ts Helper │ └── Panel-Komponenten └── Context Providers ``` **`canvas.tsx`** ist weiterhin die zentrale Orchestrierungsdatei. Viel Low-Level-Logik wurde in dedizierte Module ausgelagert, aber Mutations-Flow, Event-Wiring und Render-Composition liegen weiterhin hier. ### Interne Module von `canvas.tsx` | Datei | Zweck | |------|-------| | `canvas-helpers.ts` | Shared Utility-Layer (Optimistic IDs, Node-Merge, Compare-Resolution, Edge/Hit-Helpers, Konstante Defaults) | | `canvas-presets-context.tsx` | Shared Preset-Provider für Adjustment-Nodes; bündelt `presets.list` zu einer einzigen Query | | `canvas-node-change-helpers.ts` | Dimensions-/Resize-Transformationen für `asset` und `ai-image` Nodes | | `canvas-generation-failures.ts` | Hook für AI-Generation-Error-Tracking mit Schwellenwert-Toast (unterstützt `ai-image` und `ai-video`) | | `canvas-scissors.ts` | Hook für Scherenmodus (K/Esc Toggle, Click-Cut, Stroke-Cut) | | `canvas-delete-handlers.ts` | Hook für `onBeforeDelete`, `onNodesDelete`, `onEdgesDelete` inkl. Bridge-Edges | | `canvas-reconnect.ts` | Hook für Edge-Reconnect (`onReconnectStart`, `onReconnect`, `onReconnectEnd`) | | `canvas-media-utils.ts` | Media-Helfer wie `getImageDimensions(file)` | | `use-canvas-data.ts` | Hook: Bündelt Canvas-Graph-Query, Storage-URL-Auflösung und Auth-State in einer einzigen Abstraktion | | `canvas-graph-query-cache.ts` | Optimistic Store Helper für `canvasGraph.get` (getNodes, getEdges, setNodes, setEdges) | --- ## Node-Taxonomie (Phase 1) Alle verfügbaren Node-Typen sind in `lib/canvas-node-catalog.ts` definiert: ### Kategorien | Kategorie | Nodes | Beschreibung | |-----------|-------|-------------| | **source** (Quelle) | `image`, `text`, `video`, `asset`, `color` | Input-Quellen für den Workflow | | **ai-output** (KI-Ausgabe) | `prompt`, `video-prompt`, `ai-text`, `ai-video`, `agent-output` | KI-generierte Inhalte | | **transform** (Transformation) | `crop`, `bg-remove`, `upscale` | Bildbearbeitung-Transformationen | | **image-edit** (Bildbearbeitung) | `curves`, `color-adjust`, `light-adjust`, `detail-adjust` | Preset-basierte Adjustments | | **control** (Steuerung & Flow) | `condition`, `loop`, `parallel`, `switch` | Kontrollfluss-Elemente | | **layout** (Canvas & Layout) | `group`, `frame`, `note`, `compare` | Layout-Elemente | ### Node-Typen im Detail | Typ | Phase | Implementiert | Kategorie | Handles | |-----|-------|---------------|-----------|---------| | `image` | 1 | ✅ | source | source (default), target (default) | | `text` | 1 | ✅ | source | source (default), target (default) | | `video` | 1 | ✅ | source | source (default), target (default) | | `asset` | 1 | ✅ | source | source (default), target (default) | | `prompt` | 1 | ✅ | ai-output | source: `prompt-out`, target: `image-in` | | `video-prompt` | 2 | ✅ | ai-output | source: `video-prompt-out`, target: `video-prompt-in` | | `ai-text` | 2 | 🔲 | ai-output | source: `text-out`, target: `text-in` | | `ai-video` | 2 | ✅ (systemOutput) | ai-output | source: `video-out`, target: `video-in` | | `agent-output` | 3 | 🔲 | ai-output | systemOutput: true | | `crop` | 2 | 🔲 | transform | 🔲 | | `bg-remove` | 2 | 🔲 | transform | 🔲 | | `upscale` | 2 | 🔲 | transform | 🔲 | | `curves` | 1 | ✅ | image-edit | Preset-basiert (nicht standalone) | | `color-adjust` | 1 | ✅ | image-edit | Preset-basiert | | `light-adjust` | 1 | ✅ | image-edit | Preset-basiert | | `detail-adjust` | 1 | ✅ | image-edit | Preset-basiert | | `group` | 1 | ✅ | layout | source (default), target (default) | | `frame` | 1 | ✅ | layout | source: `frame-out`, target: `frame-in` | | `note` | 1 | ✅ | layout | source (default), target (default) | | `compare` | 1 | ✅ | layout | source: `compare-out`, targets: `left`, `right` | > `implemented: false` (🔲) bedeutet Phase-2/3 Node, der noch nicht implementiert ist. **Hinweis:** Phase-2/3 Nodes müssen im Schema (`convex/node_type_validator.ts`) vordeklariert werden, damit das System nicht bei jeder Phasenübergang neu migriert werden muss. Die UI filtert Nodes nach Phase. **SystemOutput Nodes** (`ai-video`, `ai-text`, `agent-output`): Wird typischerweise vom KI-System erzeugt — nicht aus Palette/DnD anlegbar. `ai-video` wird automatisch durch `createNodeConnectedFromSource` beim Klick auf "Video generieren" erzeugt. --- ## KI-Video-Node-Flow Zweistufiger Node-Flow analog `prompt → ai-image`: 1. **`video-prompt`** (Steuernode, Palette-sichtbar): Prompt-Textarea, Modell-Selector, Dauer-Selector (5s/10s), Credit-Kosten-Anzeige, "Video generieren"-Button 2. **`ai-video`** (Output-Node, systemOutput): Wird automatisch rechts vom video-prompt erzeugt. Zeigt Status (executing/done/error), fertiges Video als `