feat: Lifted useCanvasState() from DesignCanvas to App.tsx, threaded al…
- "app/src/App.tsx" - "app/src/views/DesignCanvas.tsx" GSD-Task: S01/T02
This commit is contained in:
parent
6c8c31e13b
commit
62c866be84
2 changed files with 70 additions and 25 deletions
|
|
@ -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<ViewState>('import');
|
||||
const [svgResult, setSvgResult] = useState<string | null>(null);
|
||||
const [traceMetadata, setTraceMetadata] = useState<TraceMetadata | null>(null);
|
||||
const [pngDataUrl, setPngDataUrl] = useState<string | null>(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<Konva.Stage | null>(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 (
|
||||
<div id="app">
|
||||
{view === 'import' && <ImportConvert onUseThis={handleUseThis} />}
|
||||
{view === 'canvas' && (
|
||||
<DesignCanvas svgData={svgResult} traceMetadata={traceMetadata} />
|
||||
<DesignCanvas
|
||||
svgData={svgResult}
|
||||
stageRef={stageRef}
|
||||
onExport={handleExport}
|
||||
{...canvasState}
|
||||
/>
|
||||
)}
|
||||
{view === 'export' && (
|
||||
<div className="placeholder-view" data-testid="export-view">
|
||||
<p>View 3: Export (placeholder)</p>
|
||||
<p>PNG preview captured: {pngDataUrl ? 'Yes' : 'No'}</p>
|
||||
<p>Objects: {canvasState.state.objects.length}</p>
|
||||
<button type="button" onClick={handleBackToCanvas}>
|
||||
← Back to Design
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{view === 'export' && <div className="placeholder-view">View 3: Export</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,16 +20,16 @@ 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<Konva.Stage | null>;
|
||||
/** Called when user clicks Export — App.tsx navigates to View 3. */
|
||||
onExport: () => void;
|
||||
}
|
||||
|
||||
export default function DesignCanvas({
|
||||
svgData,
|
||||
traceMetadata,
|
||||
}: DesignCanvasProps) {
|
||||
const {
|
||||
state,
|
||||
addObject,
|
||||
removeObject,
|
||||
|
|
@ -45,7 +44,9 @@ export default function DesignCanvas({
|
|||
redo,
|
||||
canUndo,
|
||||
canRedo,
|
||||
} = useCanvasState(traceMetadata);
|
||||
stageRef,
|
||||
onExport,
|
||||
}: DesignCanvasProps) {
|
||||
|
||||
const [activeTool, setActiveTool] = useState<CanvasTool>('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<Konva.Stage | null>(null);
|
||||
const canvasContainerRef = useRef<HTMLDivElement | null>(null);
|
||||
const [stageSize, setStageSize] = useState({ width: 800, height: 600 });
|
||||
|
||||
|
|
@ -265,6 +265,15 @@ export default function DesignCanvas({
|
|||
onZoomOut={handleZoomOut}
|
||||
onZoomFit={handleZoomFit}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="canvas-tool-btn"
|
||||
onClick={onExport}
|
||||
title="Export design"
|
||||
data-testid="export-btn"
|
||||
>
|
||||
⤓ Export
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Main area: canvas + right panel */}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue