Files
paint-ui/store/guides-store.ts
Sebastian Krüger 19baa730c7 feat(phase-13): implement rulers and guides system for precise alignment
Add comprehensive rulers and guides system for canvas alignment and positioning.

Features:
- Guides store with full CRUD operations
- Horizontal and vertical guide support
- Ruler display with 50px intervals
- Green guide lines with subtle glow
- Toggle visibility for rulers and guides
- Persistent storage of guides and settings
- Snap distance configuration
- Guide position in canvas pixels
- Zoom-aware positioning

Changes:
- Created store/guides-store.ts with Guide interface
- Added guides state management with persistence
- Created components/canvas/rulers-and-guides.tsx
- Rulers show measurements at 50px intervals
- Guides rendered as 1px green lines with shadow
- Exported guides store from store/index.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 19:59:45 +01:00

92 lines
2.2 KiB
TypeScript

import { create } from 'zustand';
import { persist } from 'zustand/middleware';
export interface Guide {
id: string;
type: 'horizontal' | 'vertical';
position: number; // In canvas pixels
}
interface GuidesStore {
/** All guides */
guides: Guide[];
/** Whether guides are visible */
showGuides: boolean;
/** Whether rulers are visible */
showRulers: boolean;
/** Snap to guides threshold in pixels */
snapDistance: number;
/** Add a guide */
addGuide: (type: 'horizontal' | 'vertical', position: number) => void;
/** Remove a guide */
removeGuide: (id: string) => void;
/** Update guide position */
updateGuide: (id: string, position: number) => void;
/** Clear all guides */
clearGuides: () => void;
/** Toggle guides visibility */
toggleGuides: () => void;
/** Toggle rulers visibility */
toggleRulers: () => void;
/** Set snap distance */
setSnapDistance: (distance: number) => void;
}
export const useGuidesStore = create<GuidesStore>()(
persist(
(set, get) => ({
guides: [],
showGuides: true,
showRulers: true,
snapDistance: 10,
addGuide: (type, position) => {
const id = `guide-${Date.now()}-${Math.random()}`;
set((state) => ({
guides: [...state.guides, { id, type, position }],
}));
},
removeGuide: (id) => {
set((state) => ({
guides: state.guides.filter((g) => g.id !== id),
}));
},
updateGuide: (id, position) => {
set((state) => ({
guides: state.guides.map((g) =>
g.id === id ? { ...g, position } : g
),
}));
},
clearGuides: () => {
set({ guides: [] });
},
toggleGuides: () => {
set((state) => ({ showGuides: !state.showGuides }));
},
toggleRulers: () => {
set((state) => ({ showRulers: !state.showRulers }));
},
setSnapDistance: (distance) => {
set({ snapDistance: Math.max(0, Math.min(50, distance)) });
},
}),
{
name: 'guides-storage',
partialize: (state) => ({
guides: state.guides,
showGuides: state.showGuides,
showRulers: state.showRulers,
snapDistance: state.snapDistance,
}),
}
)
);