Implements the core canvas editor with react-konva: - Added dependencies: react-konva, konva, use-image - DesignCanvas component: 300×300px Stage with T-shirt SVG overlay - TShirtSVG component: Visual t-shirt outline with print zone indicator - ImageElement: Draggable/resizable image with Transformer handles - TextElement: Draggable/resizable text with Transformer handles - useDesignEditor hook: Element CRUD, selection, reordering - Keyboard shortcut: Delete/Backspace removes selected element - Test image added on mount for Phase 2 verification Canvas info bar shows: "Design Area: 15" × 15" • Export: 4500 × 4500px @ 300 DPI" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
60 lines
1.4 KiB
JavaScript
60 lines
1.4 KiB
JavaScript
export function TShirtSVG({ size = 300 }) {
|
|
const padding = size * 0.1;
|
|
const innerSize = size - padding * 2;
|
|
|
|
return (
|
|
<svg
|
|
width={size}
|
|
height={size}
|
|
viewBox={`0 0 ${size} ${size}`}
|
|
style={{
|
|
position: 'absolute',
|
|
top: '50%',
|
|
left: '50%',
|
|
transform: 'translate(-50%, -50%)',
|
|
pointerEvents: 'none',
|
|
zIndex: 0,
|
|
}}
|
|
>
|
|
{/* T-shirt outline */}
|
|
<path
|
|
d={`
|
|
M ${padding} ${padding + innerSize * 0.15}
|
|
L ${padding + innerSize * 0.15} ${padding}
|
|
L ${size - padding - innerSize * 0.15} ${padding}
|
|
L ${size - padding} ${padding + innerSize * 0.15}
|
|
L ${size - padding} ${size - padding}
|
|
L ${padding} ${size - padding}
|
|
Z
|
|
`}
|
|
fill="none"
|
|
stroke="var(--border)"
|
|
strokeWidth="2"
|
|
strokeDasharray="4,4"
|
|
/>
|
|
{/* Chest area indicator (design zone) */}
|
|
<rect
|
|
x={size * 0.3}
|
|
y={size * 0.25}
|
|
width={size * 0.4}
|
|
height={size * 0.35}
|
|
fill="none"
|
|
stroke="var(--accent)"
|
|
strokeWidth="1.5"
|
|
opacity="0.5"
|
|
/>
|
|
{/* Label */}
|
|
<text
|
|
x={size / 2}
|
|
y={size * 0.45}
|
|
textAnchor="middle"
|
|
fill="var(--text-muted)"
|
|
fontSize="10"
|
|
fontFamily="var(--font-mono)"
|
|
>
|
|
Print Zone
|
|
</text>
|
|
</svg>
|
|
);
|
|
}
|