feat: implement Phase 10 - Shape Tools
Add comprehensive shape drawing system with support for 7 shape types: rectangle, ellipse, line, arrow, polygon, star, and triangle. Features: - Created types/shape.ts with ShapeType and ShapeSettings interfaces - Implemented lib/shape-utils.ts with drawing algorithms for all shapes: * Rectangle with optional corner radius * Ellipse with independent x/y radii * Line with stroke support * Arrow with configurable head size and angle * Polygon with adjustable sides (3-20) * Star with points and inner radius control * Triangle (equilateral style) - Created store/shape-store.ts for shape state management - Implemented tools/shape-tool.ts as unified tool handling all shapes - Built components/shapes/shape-panel.tsx with comprehensive UI: * Grid selector for all 7 shape types * Fill/stroke toggles with color pickers * Dynamic properties panel (corner radius, sides, inner radius, etc.) * Real-time stroke width adjustment - Integrated ShapeTool into canvas-with-tools.tsx - Added ShapePanel to editor-layout.tsx sidebar - Removed duplicate ShapeType/ShapeSettings from types/tool.ts All shapes support: - Fill with color selection - Stroke with color and width controls - Shape-specific properties (corners, sides, arrow heads, etc.) - Undo/redo via DrawCommand integration Build Status: ✓ Successful (1290ms) 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -6,3 +6,4 @@ export * from './history-store';
|
||||
export * from './color-store';
|
||||
export * from './selection-store';
|
||||
export * from './transform-store';
|
||||
export * from './shape-store';
|
||||
|
||||
80
store/shape-store.ts
Normal file
80
store/shape-store.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { create } from 'zustand';
|
||||
import type { ShapeSettings, ShapeType, ShapeStore as IShapeStore } from '@/types/shape';
|
||||
|
||||
const DEFAULT_SETTINGS: ShapeSettings = {
|
||||
type: 'rectangle',
|
||||
fill: true,
|
||||
fillColor: '#000000',
|
||||
stroke: true,
|
||||
strokeColor: '#000000',
|
||||
strokeWidth: 2,
|
||||
cornerRadius: 0,
|
||||
sides: 5,
|
||||
innerRadius: 0.5,
|
||||
arrowHeadSize: 20,
|
||||
arrowHeadAngle: 30,
|
||||
};
|
||||
|
||||
export const useShapeStore = create<IShapeStore>((set) => ({
|
||||
settings: { ...DEFAULT_SETTINGS },
|
||||
|
||||
setShapeType: (type) =>
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, type },
|
||||
})),
|
||||
|
||||
setFill: (fill) =>
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, fill },
|
||||
})),
|
||||
|
||||
setFillColor: (fillColor) =>
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, fillColor },
|
||||
})),
|
||||
|
||||
setStroke: (stroke) =>
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, stroke },
|
||||
})),
|
||||
|
||||
setStrokeColor: (strokeColor) =>
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, strokeColor },
|
||||
})),
|
||||
|
||||
setStrokeWidth: (strokeWidth) =>
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, strokeWidth: Math.max(1, Math.min(100, strokeWidth)) },
|
||||
})),
|
||||
|
||||
setCornerRadius: (cornerRadius) =>
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, cornerRadius: Math.max(0, Math.min(100, cornerRadius)) },
|
||||
})),
|
||||
|
||||
setSides: (sides) =>
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, sides: Math.max(3, Math.min(20, sides)) },
|
||||
})),
|
||||
|
||||
setInnerRadius: (innerRadius) =>
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, innerRadius: Math.max(0.1, Math.min(0.9, innerRadius)) },
|
||||
})),
|
||||
|
||||
setArrowHeadSize: (arrowHeadSize) =>
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, arrowHeadSize: Math.max(5, Math.min(100, arrowHeadSize)) },
|
||||
})),
|
||||
|
||||
setArrowHeadAngle: (arrowHeadAngle) =>
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, arrowHeadAngle: Math.max(10, Math.min(60, arrowHeadAngle)) },
|
||||
})),
|
||||
|
||||
updateSettings: (settings) =>
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, ...settings },
|
||||
})),
|
||||
}));
|
||||
Reference in New Issue
Block a user