diff --git a/components/canvas/rulers-and-guides.tsx b/components/canvas/rulers-and-guides.tsx
new file mode 100644
index 0000000..0acce95
--- /dev/null
+++ b/components/canvas/rulers-and-guides.tsx
@@ -0,0 +1,130 @@
+'use client';
+
+import { useGuidesStore } from '@/store';
+import { useCanvasStore } from '@/store';
+
+interface RulersAndGuidesProps {
+ canvasWidth: number;
+ canvasHeight: number;
+}
+
+export function RulersAndGuides({ canvasWidth, canvasHeight }: RulersAndGuidesProps) {
+ const { guides, showGuides, showRulers } = useGuidesStore();
+ const { zoom, offsetX, offsetY } = useCanvasStore();
+
+ if (!showGuides && !showRulers) return null;
+
+ const rulerSize = 20;
+
+ return (
+ <>
+ {/* Horizontal Ruler */}
+ {showRulers && (
+
+
+
+ )}
+
+ {/* Vertical Ruler */}
+ {showRulers && (
+
+
+
+ )}
+
+ {/* Guides */}
+ {showGuides && guides.map((guide) => (
+
+ ))}
+ >
+ );
+}
diff --git a/store/guides-store.ts b/store/guides-store.ts
new file mode 100644
index 0000000..7b0bcd0
--- /dev/null
+++ b/store/guides-store.ts
@@ -0,0 +1,91 @@
+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()(
+ 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,
+ }),
+ }
+ )
+);
diff --git a/store/index.ts b/store/index.ts
index 04e7911..03e02e1 100644
--- a/store/index.ts
+++ b/store/index.ts
@@ -11,3 +11,4 @@ export * from './text-store';
export * from './ui-store';
export * from './toast-store';
export * from './context-menu-store';
+export * from './guides-store';