diff --git a/app/src/App.tsx b/app/src/App.tsx index 13ab741..8569544 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -1,5 +1,7 @@ -import { useState } from 'react'; +import { useCallback, useRef, useState } from 'react'; +import type Konva from 'konva'; import type { TraceMetadata } from './types/engine'; +import { useCanvasState } from './hooks/useCanvasState'; import ImportConvert from './views/ImportConvert'; import DesignCanvas from './views/DesignCanvas'; import './App.css'; @@ -10,6 +12,13 @@ function App() { const [view, setView] = useState('import'); const [svgResult, setSvgResult] = useState(null); const [traceMetadata, setTraceMetadata] = useState(null); + const [pngDataUrl, setPngDataUrl] = useState(null); + + // Lifted canvas state โ€” shared between View 2 (DesignCanvas) and View 3 (ExportView) + const canvasState = useCanvasState(traceMetadata); + + // Stage ref created here so View 3 can capture PNG from View 2's Konva stage + const stageRef = useRef(null); const handleUseThis = (svgOutput: string, metadata: TraceMetadata) => { setSvgResult(svgOutput); @@ -17,13 +26,40 @@ function App() { setView('canvas'); }; + const handleExport = useCallback(() => { + // Capture PNG data URL from the Konva stage before navigating away + if (stageRef.current) { + const dataUrl = stageRef.current.toDataURL({ pixelRatio: 2 }); + setPngDataUrl(dataUrl); + } + setView('export'); + }, []); + + const handleBackToCanvas = useCallback(() => { + setView('canvas'); + }, []); + return (
{view === 'import' && } {view === 'canvas' && ( - + + )} + {view === 'export' && ( +
+

View 3: Export (placeholder)

+

PNG preview captured: {pngDataUrl ? 'Yes' : 'No'}

+

Objects: {canvasState.state.objects.length}

+ +
)} - {view === 'export' &&
View 3: Export
}
); } diff --git a/app/src/views/DesignCanvas.tsx b/app/src/views/DesignCanvas.tsx index 3cae09f..64990d6 100644 --- a/app/src/views/DesignCanvas.tsx +++ b/app/src/views/DesignCanvas.tsx @@ -8,9 +8,8 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import type Konva from 'konva'; -import type { TraceMetadata } from '../types/engine'; import type { ArtboardConfig, CanvasObject, ImageObject } from '../types/canvas'; -import { useCanvasState } from '../hooks/useCanvasState'; +import type { UseCanvasStateReturn } from '../hooks/useCanvasState'; import ArtboardSetup from '../components/canvas/ArtboardSetup'; import KonvaStage from '../components/canvas/KonvaStage'; import type { CanvasTool } from '../components/canvas/KonvaStage'; @@ -21,31 +20,33 @@ import ShapeProperties from '../components/canvas/ShapeProperties'; import { toPx } from '../utils/artboardShapes'; import styles from './DesignCanvas.module.css'; -interface DesignCanvasProps { +export interface DesignCanvasProps extends UseCanvasStateReturn { svgData: string | null; - traceMetadata: TraceMetadata | null; + /** Ref to the Konva Stage, created in App.tsx for cross-view access (PNG export). */ + stageRef: React.RefObject; + /** Called when user clicks Export โ€” App.tsx navigates to View 3. */ + onExport: () => void; } export default function DesignCanvas({ svgData, - traceMetadata, + state, + addObject, + removeObject, + updateObject, + selectObjects, + deselectAll, + reorderObject, + toggleVisibility, + toggleLock, + setArtboard, + undo, + redo, + canUndo, + canRedo, + stageRef, + onExport, }: DesignCanvasProps) { - const { - state, - addObject, - removeObject, - updateObject, - selectObjects, - deselectAll, - reorderObject, - toggleVisibility, - toggleLock, - setArtboard, - undo, - redo, - canUndo, - canRedo, - } = useCanvasState(traceMetadata); const [activeTool, setActiveTool] = useState('pointer'); const [showArtboardSetup, setShowArtboardSetup] = useState(true); @@ -53,7 +54,6 @@ export default function DesignCanvas({ const [showGrid, setShowGrid] = useState(false); const [zoomLevel, setZoomLevel] = useState(1); - const stageRef = useRef(null); const canvasContainerRef = useRef(null); const [stageSize, setStageSize] = useState({ width: 800, height: 600 }); @@ -265,6 +265,15 @@ export default function DesignCanvas({ onZoomOut={handleZoomOut} onZoomFit={handleZoomFit} /> + {/* Main area: canvas + right panel */}