@fieldnotes/core 0.8.1 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/event-bus.ts","../src/core/state-serializer.ts","../src/core/snap.ts","../src/core/auto-save.ts","../src/canvas/camera.ts","../src/canvas/background.ts","../src/canvas/input-handler.ts","../src/elements/element-store.ts","../src/elements/arrow-geometry.ts","../src/elements/arrow-binding.ts","../src/elements/stroke-smoothing.ts","../src/elements/grid-renderer.ts","../src/elements/element-renderer.ts","../src/elements/note-editor.ts","../src/tools/tool-manager.ts","../src/history/history-stack.ts","../src/history/commands.ts","../src/history/history-recorder.ts","../src/elements/create-id.ts","../src/elements/element-factory.ts","../src/canvas/export-image.ts","../src/layers/layer-manager.ts","../src/canvas/viewport.ts","../src/tools/hand-tool.ts","../src/tools/pencil-tool.ts","../src/tools/eraser-tool.ts","../src/tools/arrow-handles.ts","../src/tools/select-tool.ts","../src/tools/arrow-tool.ts","../src/tools/note-tool.ts","../src/tools/text-tool.ts","../src/tools/image-tool.ts","../src/tools/shape-tool.ts","../src/history/layer-commands.ts"],"sourcesContent":["export const VERSION = '0.8.1';\n\nexport { EventBus } from './core/event-bus';\nexport type { Point, StrokePoint, Size, Bounds } from './core/types';\nexport { exportState, parseState } from './core/state-serializer';\nexport { snapPoint } from './core/snap';\nexport type { CanvasState } from './core/state-serializer';\nexport { AutoSave } from './core/auto-save';\nexport type { AutoSaveOptions } from './core/auto-save';\n\nexport { Camera } from './canvas/camera';\nexport type { CameraOptions } from './canvas/camera';\nexport { Background } from './canvas/background';\nexport type { BackgroundOptions, BackgroundPattern } from './canvas/background';\nexport { InputHandler } from './canvas/input-handler';\nexport { Viewport } from './canvas/viewport';\nexport type { ViewportOptions } from './canvas/viewport';\nexport { exportImage } from './canvas/export-image';\nexport type { ExportImageOptions } from './canvas/export-image';\n\nexport { ElementStore } from './elements/element-store';\nexport type { ElementUpdateEvent } from './elements/element-store';\nexport { ElementRenderer } from './elements/element-renderer';\nexport { NoteEditor } from './elements/note-editor';\nexport { createId } from './elements/create-id';\nexport {\n createStroke,\n createNote,\n createArrow,\n createImage,\n createHtmlElement,\n createText,\n createShape,\n createGrid,\n} from './elements/element-factory';\nexport {\n getArrowControlPoint,\n getArrowMidpoint,\n getBendFromPoint,\n getArrowTangentAngle,\n isNearBezier,\n getArrowBounds,\n} from './elements/arrow-geometry';\nexport {\n isBindable,\n getElementCenter,\n getElementBounds,\n getEdgeIntersection,\n findBindTarget,\n findBoundArrows,\n updateBoundArrow,\n clearStaleBindings,\n unbindArrow,\n} from './elements/arrow-binding';\nexport type {\n Binding,\n CanvasElement,\n ElementType,\n StrokeElement,\n NoteElement,\n ArrowElement,\n ImageElement,\n HtmlElement,\n TextElement,\n ShapeElement,\n ShapeKind,\n GridElement,\n HexOrientation,\n} from './elements/types';\n\nexport type { Command } from './history/types';\nexport {\n AddElementCommand,\n RemoveElementCommand,\n UpdateElementCommand,\n BatchCommand,\n} from './history/commands';\nexport { HistoryStack } from './history/history-stack';\nexport type { HistoryStackOptions } from './history/history-stack';\nexport { HistoryRecorder } from './history/history-recorder';\n\nexport { ToolManager } from './tools/tool-manager';\nexport { HandTool } from './tools/hand-tool';\nexport { PencilTool } from './tools/pencil-tool';\nexport type { PencilToolOptions } from './tools/pencil-tool';\nexport { EraserTool } from './tools/eraser-tool';\nexport type { EraserToolOptions } from './tools/eraser-tool';\nexport { SelectTool } from './tools/select-tool';\nexport { ArrowTool } from './tools/arrow-tool';\nexport type { ArrowToolOptions } from './tools/arrow-tool';\nexport { NoteTool } from './tools/note-tool';\nexport type { NoteToolOptions } from './tools/note-tool';\nexport { TextTool } from './tools/text-tool';\nexport type { TextToolOptions } from './tools/text-tool';\nexport { ImageTool } from './tools/image-tool';\nexport type { ImageToolOptions } from './tools/image-tool';\nexport { ShapeTool } from './tools/shape-tool';\nexport type { ShapeToolOptions } from './tools/shape-tool';\nexport type { Tool, ToolContext, PointerState, ToolName } from './tools/types';\n\nexport { LayerManager } from './layers/layer-manager';\nexport type { Layer } from './layers/types';\nexport {\n CreateLayerCommand,\n RemoveLayerCommand,\n UpdateLayerCommand,\n} from './history/layer-commands';\n","type Listener<T> = (data: T) => void;\n\nexport class EventBus<TEvents extends { [K in keyof TEvents]: TEvents[K] }> {\n private listeners = new Map<keyof TEvents, Set<Listener<never>>>();\n\n on<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): () => void {\n const existing = this.listeners.get(event);\n if (existing) {\n existing.add(listener as Listener<never>);\n } else {\n const set = new Set<Listener<never>>([listener as Listener<never>]);\n this.listeners.set(event, set);\n }\n return () => this.off(event, listener);\n }\n\n off<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): void {\n this.listeners.get(event)?.delete(listener as Listener<never>);\n }\n\n emit<K extends keyof TEvents>(event: K, data: TEvents[K]): void {\n this.listeners.get(event)?.forEach((listener) => listener(data as never));\n }\n\n clear(): void {\n this.listeners.clear();\n }\n}\n","import type { CanvasElement } from '../elements/types';\r\nimport type { Point } from './types';\r\nimport type { Layer } from '../layers/types';\r\n\r\nexport interface CanvasState {\r\n version: number;\r\n camera: {\r\n position: Point;\r\n zoom: number;\r\n };\r\n elements: CanvasElement[];\r\n layers?: Layer[];\r\n}\r\n\r\nconst CURRENT_VERSION = 2;\r\n\r\nexport function exportState(\r\n elements: CanvasElement[],\r\n camera: { position: Point; zoom: number },\r\n layers: Layer[] = [],\r\n): CanvasState {\r\n return {\r\n version: CURRENT_VERSION,\r\n camera: {\r\n position: { ...camera.position },\r\n zoom: camera.zoom,\r\n },\r\n elements: elements.map((el) => structuredClone(el)),\r\n layers: layers.map((l) => ({ ...l })),\r\n };\r\n}\r\n\r\nexport function parseState(json: string): CanvasState {\r\n const data: unknown = JSON.parse(json);\r\n validateState(data);\r\n return data;\r\n}\r\n\r\nfunction validateState(data: unknown): asserts data is CanvasState {\r\n if (!data || typeof data !== 'object') {\r\n throw new Error('Invalid state: expected an object');\r\n }\r\n\r\n const obj = data as Record<string, unknown>;\r\n\r\n if (typeof obj['version'] !== 'number') {\r\n throw new Error('Invalid state: missing or invalid version');\r\n }\r\n\r\n if (!obj['camera'] || typeof obj['camera'] !== 'object') {\r\n throw new Error('Invalid state: missing camera');\r\n }\r\n\r\n const cam = obj['camera'] as Record<string, unknown>;\r\n if (!cam['position'] || typeof cam['position'] !== 'object') {\r\n throw new Error('Invalid state: missing camera.position');\r\n }\r\n\r\n const pos = cam['position'] as Record<string, unknown>;\r\n if (typeof pos['x'] !== 'number' || typeof pos['y'] !== 'number') {\r\n throw new Error('Invalid state: camera.position must have x and y numbers');\r\n }\r\n\r\n if (typeof cam['zoom'] !== 'number') {\r\n throw new Error('Invalid state: missing camera.zoom');\r\n }\r\n\r\n if (!Array.isArray(obj['elements'])) {\r\n throw new Error('Invalid state: elements must be an array');\r\n }\r\n\r\n for (const el of obj['elements'] as unknown[]) {\r\n validateElement(el);\r\n migrateElement(el as unknown as Record<string, unknown>);\r\n }\r\n\r\n cleanBindings(obj['elements'] as Record<string, unknown>[]);\r\n\r\n const layers = obj['layers'];\r\n if (!Array.isArray(layers) || layers.length === 0) {\r\n obj['layers'] = [\r\n {\r\n id: 'default-layer',\r\n name: 'Layer 1',\r\n visible: true,\r\n locked: false,\r\n order: 0,\r\n opacity: 1.0,\r\n },\r\n ];\r\n }\r\n}\r\n\r\nconst VALID_TYPES = new Set(['stroke', 'note', 'arrow', 'image', 'html', 'text', 'shape', 'grid']);\r\n\r\nfunction validateElement(el: unknown): asserts el is CanvasElement {\r\n if (!el || typeof el !== 'object') {\r\n throw new Error('Invalid element: expected an object');\r\n }\r\n\r\n const obj = el as Record<string, unknown>;\r\n\r\n if (typeof obj['id'] !== 'string') {\r\n throw new Error('Invalid element: missing id');\r\n }\r\n\r\n if (typeof obj['type'] !== 'string' || !VALID_TYPES.has(obj['type'])) {\r\n throw new Error(`Invalid element: unknown type \"${String(obj['type'])}\"`);\r\n }\r\n\r\n if (typeof obj['zIndex'] !== 'number') {\r\n throw new Error('Invalid element: missing zIndex');\r\n }\r\n}\r\n\r\nfunction cleanBindings(elements: Record<string, unknown>[]): void {\r\n const ids = new Set(elements.map((el) => el['id'] as string));\r\n\r\n for (const el of elements) {\r\n if (el['type'] !== 'arrow') continue;\r\n\r\n const fromBinding = el['fromBinding'] as Record<string, unknown> | undefined;\r\n if (fromBinding && !ids.has(fromBinding['elementId'] as string)) {\r\n el['fromBinding'] = undefined;\r\n }\r\n\r\n const toBinding = el['toBinding'] as Record<string, unknown> | undefined;\r\n if (toBinding && !ids.has(toBinding['elementId'] as string)) {\r\n el['toBinding'] = undefined;\r\n }\r\n }\r\n}\r\n\r\nfunction migrateElement(obj: Record<string, unknown>): void {\r\n if (typeof obj['layerId'] !== 'string') {\r\n obj['layerId'] = 'default-layer';\r\n }\r\n\r\n if (obj['type'] === 'arrow' && typeof obj['bend'] !== 'number') {\r\n obj['bend'] = 0;\r\n }\r\n\r\n if (obj['type'] === 'stroke' && Array.isArray(obj['points'])) {\r\n for (const pt of obj['points'] as Record<string, unknown>[]) {\r\n if (typeof pt['pressure'] !== 'number') {\r\n pt['pressure'] = 0.5;\r\n }\r\n }\r\n }\r\n\r\n if (obj['type'] === 'shape' && typeof obj['shape'] !== 'string') {\r\n obj['shape'] = 'rectangle';\r\n }\r\n\r\n if (obj['type'] === 'note' && typeof obj['textColor'] !== 'string') {\r\n obj['textColor'] = '#000000';\r\n }\r\n}\r\n","import type { Point } from './types';\r\n\r\nexport function snapPoint(point: Point, gridSize: number): Point {\r\n return {\r\n x: Math.round(point.x / gridSize) * gridSize || 0,\r\n y: Math.round(point.y / gridSize) * gridSize || 0,\r\n };\r\n}\r\n","import type { ElementStore } from '../elements/element-store';\r\nimport type { Camera } from '../canvas/camera';\r\nimport type { LayerManager } from '../layers/layer-manager';\r\nimport { exportState, parseState } from './state-serializer';\r\nimport type { CanvasState } from './state-serializer';\r\n\r\nexport interface AutoSaveOptions {\r\n key?: string;\r\n debounceMs?: number;\r\n layerManager?: LayerManager;\r\n}\r\n\r\nconst DEFAULT_KEY = 'fieldnotes-autosave';\r\nconst DEFAULT_DEBOUNCE_MS = 1000;\r\n\r\nexport class AutoSave {\r\n private readonly key: string;\r\n private readonly debounceMs: number;\r\n private readonly layerManager?: LayerManager;\r\n private timerId: ReturnType<typeof setTimeout> | null = null;\r\n private unsubscribers: (() => void)[] = [];\r\n\r\n constructor(\r\n private readonly store: ElementStore,\r\n private readonly camera: Camera,\r\n options: AutoSaveOptions = {},\r\n ) {\r\n this.key = options.key ?? DEFAULT_KEY;\r\n this.debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;\r\n this.layerManager = options.layerManager;\r\n }\r\n\r\n start(): void {\r\n const schedule = () => this.scheduleSave();\r\n\r\n this.unsubscribers = [\r\n this.store.on('add', schedule),\r\n this.store.on('remove', schedule),\r\n this.store.on('update', schedule),\r\n this.camera.onChange(schedule),\r\n ];\r\n if (this.layerManager) {\r\n this.unsubscribers.push(this.layerManager.on('change', schedule));\r\n }\r\n }\r\n\r\n stop(): void {\r\n this.cancelPending();\r\n this.unsubscribers.forEach((fn) => fn());\r\n this.unsubscribers = [];\r\n }\r\n\r\n load(): CanvasState | null {\r\n if (typeof localStorage === 'undefined') return null;\r\n\r\n const json = localStorage.getItem(this.key);\r\n if (!json) return null;\r\n\r\n try {\r\n return parseState(json);\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n clear(): void {\r\n if (typeof localStorage === 'undefined') return;\r\n localStorage.removeItem(this.key);\r\n }\r\n\r\n private scheduleSave(): void {\r\n this.cancelPending();\r\n this.timerId = setTimeout(() => this.save(), this.debounceMs);\r\n }\r\n\r\n private cancelPending(): void {\r\n if (this.timerId !== null) {\r\n clearTimeout(this.timerId);\r\n this.timerId = null;\r\n }\r\n }\r\n\r\n private save(): void {\r\n if (typeof localStorage === 'undefined') return;\r\n\r\n const layers = this.layerManager?.snapshot() ?? [];\r\n const state = exportState(this.store.snapshot(), this.camera, layers);\r\n try {\r\n localStorage.setItem(this.key, JSON.stringify(state));\r\n } catch {\r\n console.warn('Auto-save failed: storage quota exceeded. State too large for localStorage.');\r\n }\r\n }\r\n}\r\n","import type { Point } from '../core/types';\n\nexport interface CameraOptions {\n minZoom?: number;\n maxZoom?: number;\n}\n\nconst DEFAULT_MIN_ZOOM = 0.1;\nconst DEFAULT_MAX_ZOOM = 10;\n\nexport class Camera {\n private x = 0;\n private y = 0;\n private z = 1;\n private readonly minZoom: number;\n private readonly maxZoom: number;\n private changeListeners = new Set<() => void>();\n\n constructor(options: CameraOptions = {}) {\n this.minZoom = options.minZoom ?? DEFAULT_MIN_ZOOM;\n this.maxZoom = options.maxZoom ?? DEFAULT_MAX_ZOOM;\n }\n\n get position(): Point {\n return { x: this.x, y: this.y };\n }\n\n get zoom(): number {\n return this.z;\n }\n\n pan(dx: number, dy: number): void {\n this.x += dx;\n this.y += dy;\n this.notifyChange();\n }\n\n moveTo(x: number, y: number): void {\n this.x = x;\n this.y = y;\n this.notifyChange();\n }\n\n setZoom(level: number): void {\n this.z = Math.min(this.maxZoom, Math.max(this.minZoom, level));\n this.notifyChange();\n }\n\n zoomAt(level: number, screenPoint: Point): void {\n const before = this.screenToWorld(screenPoint);\n this.z = Math.min(this.maxZoom, Math.max(this.minZoom, level));\n const after = this.screenToWorld(screenPoint);\n this.x += (after.x - before.x) * this.z;\n this.y += (after.y - before.y) * this.z;\n this.notifyChange();\n }\n\n screenToWorld(screen: Point): Point {\n return {\n x: (screen.x - this.x) / this.z,\n y: (screen.y - this.y) / this.z,\n };\n }\n\n worldToScreen(world: Point): Point {\n return {\n x: world.x * this.z + this.x,\n y: world.y * this.z + this.y,\n };\n }\n\n toCSSTransform(): string {\n return `translate3d(${this.x}px, ${this.y}px, 0) scale(${this.z})`;\n }\n\n onChange(listener: () => void): () => void {\n this.changeListeners.add(listener);\n return () => this.changeListeners.delete(listener);\n }\n\n private notifyChange(): void {\n this.changeListeners.forEach((fn) => fn());\n }\n}\n","import type { Camera } from './camera';\r\n\r\nexport type BackgroundPattern = 'dots' | 'grid' | 'none';\r\n\r\nexport interface BackgroundOptions {\r\n pattern?: BackgroundPattern;\r\n spacing?: number;\r\n color?: string;\r\n dotRadius?: number;\r\n lineWidth?: number;\r\n}\r\n\r\nconst MIN_PATTERN_SPACING = 16;\r\n\r\nconst DEFAULTS = {\r\n pattern: 'dots' as BackgroundPattern,\r\n spacing: 24,\r\n color: '#d0d0d0',\r\n dotRadius: 1,\r\n lineWidth: 0.5,\r\n};\r\n\r\nexport class Background {\r\n private readonly pattern: BackgroundPattern;\r\n private readonly spacing: number;\r\n private readonly color: string;\r\n private readonly dotRadius: number;\r\n private readonly lineWidth: number;\r\n\r\n constructor(options: BackgroundOptions = {}) {\r\n this.pattern = options.pattern ?? DEFAULTS.pattern;\r\n this.spacing = options.spacing ?? DEFAULTS.spacing;\r\n this.color = options.color ?? DEFAULTS.color;\r\n this.dotRadius = options.dotRadius ?? DEFAULTS.dotRadius;\r\n this.lineWidth = options.lineWidth ?? DEFAULTS.lineWidth;\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera): void {\r\n const { width, height } = ctx.canvas;\r\n const dpr = typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;\r\n const cssWidth = width / dpr;\r\n const cssHeight = height / dpr;\r\n ctx.save();\r\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\r\n ctx.clearRect(0, 0, cssWidth, cssHeight);\r\n\r\n if (this.pattern === 'dots') {\r\n this.renderDots(ctx, camera, cssWidth, cssHeight);\r\n } else if (this.pattern === 'grid') {\r\n this.renderGrid(ctx, camera, cssWidth, cssHeight);\r\n }\r\n\r\n ctx.restore();\r\n }\r\n\r\n private adaptSpacing(baseSpacing: number, zoom: number): number {\r\n let spacing = baseSpacing * zoom;\r\n while (spacing < MIN_PATTERN_SPACING) {\r\n spacing *= 2;\r\n }\r\n return spacing;\r\n }\r\n\r\n private renderDots(\r\n ctx: CanvasRenderingContext2D,\r\n camera: Camera,\r\n width: number,\r\n height: number,\r\n ): void {\r\n const spacing = this.adaptSpacing(this.spacing, camera.zoom);\r\n const offsetX = camera.position.x % spacing;\r\n const offsetY = camera.position.y % spacing;\r\n const radius = this.dotRadius * Math.min(camera.zoom, 2);\r\n\r\n ctx.fillStyle = this.color;\r\n ctx.beginPath();\r\n\r\n for (let x = offsetX; x < width; x += spacing) {\r\n for (let y = offsetY; y < height; y += spacing) {\r\n ctx.moveTo(x + radius, y);\r\n ctx.arc(x, y, radius, 0, Math.PI * 2);\r\n }\r\n }\r\n\r\n ctx.fill();\r\n }\r\n\r\n private renderGrid(\r\n ctx: CanvasRenderingContext2D,\r\n camera: Camera,\r\n width: number,\r\n height: number,\r\n ): void {\r\n const spacing = this.adaptSpacing(this.spacing, camera.zoom);\r\n const offsetX = camera.position.x % spacing;\r\n const offsetY = camera.position.y % spacing;\r\n const lineW = this.lineWidth * Math.min(camera.zoom, 2);\r\n\r\n ctx.fillStyle = this.color;\r\n\r\n for (let x = offsetX; x < width; x += spacing) {\r\n ctx.fillRect(x, 0, lineW, height);\r\n }\r\n\r\n for (let y = offsetY; y < height; y += spacing) {\r\n ctx.fillRect(0, y, width, lineW);\r\n }\r\n }\r\n}\r\n","import type { Camera } from './camera';\r\nimport type { ToolManager } from '../tools/tool-manager';\r\nimport type { ToolContext, PointerState } from '../tools/types';\r\nimport type { SelectTool } from '../tools/select-tool';\r\nimport type { HistoryRecorder } from '../history/history-recorder';\r\nimport type { HistoryStack } from '../history/history-stack';\r\n\r\nconst ZOOM_SENSITIVITY = 0.001;\r\nconst MIDDLE_BUTTON = 1;\r\n\r\nexport interface InputHandlerOptions {\r\n toolManager?: ToolManager;\r\n toolContext?: ToolContext;\r\n historyRecorder?: HistoryRecorder;\r\n historyStack?: HistoryStack;\r\n}\r\n\r\nexport class InputHandler {\r\n private isPanning = false;\r\n private lastPointer = { x: 0, y: 0 };\r\n private spaceHeld = false;\r\n private activePointers = new Map<number, { x: number; y: number }>();\r\n private lastPinchDistance = 0;\r\n private lastPinchCenter = { x: 0, y: 0 };\r\n private toolManager: ToolManager | null;\r\n private toolContext: ToolContext | null;\r\n private historyRecorder: HistoryRecorder | null;\r\n private historyStack: HistoryStack | null;\r\n private isToolActive = false;\r\n private readonly abortController = new AbortController();\r\n\r\n constructor(\r\n private readonly element: HTMLElement,\r\n private readonly camera: Camera,\r\n options: InputHandlerOptions = {},\r\n ) {\r\n this.toolManager = options.toolManager ?? null;\r\n this.toolContext = options.toolContext ?? null;\r\n this.historyRecorder = options.historyRecorder ?? null;\r\n this.historyStack = options.historyStack ?? null;\r\n this.element.style.touchAction = 'none';\r\n this.bind();\r\n }\r\n\r\n setToolManager(toolManager: ToolManager, toolContext: ToolContext): void {\r\n this.toolManager = toolManager;\r\n this.toolContext = toolContext;\r\n }\r\n\r\n destroy(): void {\r\n this.abortController.abort();\r\n }\r\n\r\n private bind(): void {\r\n const opts = { signal: this.abortController.signal };\r\n\r\n this.element.addEventListener('wheel', this.onWheel, { ...opts, passive: false });\r\n this.element.addEventListener('pointerdown', this.onPointerDown, opts);\r\n this.element.addEventListener('pointermove', this.onPointerMove, opts);\r\n this.element.addEventListener('pointerup', this.onPointerUp, opts);\r\n this.element.addEventListener('pointerleave', this.onPointerUp, opts);\r\n this.element.addEventListener('pointercancel', this.onPointerUp, opts);\r\n window.addEventListener('keydown', this.onKeyDown, opts);\r\n window.addEventListener('keyup', this.onKeyUp, opts);\r\n }\r\n\r\n private onWheel = (e: WheelEvent): void => {\r\n e.preventDefault();\r\n const rect = this.element.getBoundingClientRect();\r\n const zoomFactor = 1 - e.deltaY * ZOOM_SENSITIVITY;\r\n const newZoom = this.camera.zoom * zoomFactor;\r\n this.camera.zoomAt(newZoom, {\r\n x: e.clientX - rect.left,\r\n y: e.clientY - rect.top,\r\n });\r\n };\r\n\r\n private onPointerDown = (e: PointerEvent): void => {\r\n this.activePointers.set(e.pointerId, { x: e.clientX, y: e.clientY });\r\n\r\n this.element.setPointerCapture?.(e.pointerId);\r\n\r\n if (this.activePointers.size === 2) {\r\n this.startPinch();\r\n this.cancelToolIfActive(e);\r\n return;\r\n }\r\n\r\n if (e.button === MIDDLE_BUTTON || (e.button === 0 && this.spaceHeld)) {\r\n this.isPanning = true;\r\n this.lastPointer = { x: e.clientX, y: e.clientY };\r\n return;\r\n }\r\n\r\n if (this.activePointers.size === 1 && e.button === 0) {\r\n this.dispatchToolDown(e);\r\n }\r\n };\r\n\r\n private onPointerMove = (e: PointerEvent): void => {\r\n if (this.activePointers.has(e.pointerId)) {\r\n this.activePointers.set(e.pointerId, { x: e.clientX, y: e.clientY });\r\n }\r\n\r\n if (this.activePointers.size === 2) {\r\n this.handlePinchMove();\r\n return;\r\n }\r\n\r\n if (this.isPanning) {\r\n const dx = e.clientX - this.lastPointer.x;\r\n const dy = e.clientY - this.lastPointer.y;\r\n this.lastPointer = { x: e.clientX, y: e.clientY };\r\n this.camera.pan(dx, dy);\r\n return;\r\n }\r\n\r\n if (this.isToolActive) {\r\n this.dispatchToolMove(e);\r\n } else if (this.activePointers.size === 0) {\r\n this.dispatchToolHover(e);\r\n }\r\n };\r\n\r\n private onPointerUp = (e: PointerEvent): void => {\r\n this.activePointers.delete(e.pointerId);\r\n\r\n if (this.activePointers.size < 2) {\r\n this.lastPinchDistance = 0;\r\n }\r\n\r\n if (this.isPanning && this.activePointers.size === 0) {\r\n this.isPanning = false;\r\n }\r\n\r\n if (this.isToolActive) {\r\n this.dispatchToolUp(e);\r\n this.isToolActive = false;\r\n }\r\n };\r\n\r\n private onKeyDown = (e: KeyboardEvent): void => {\r\n if ((e.target as HTMLElement)?.isContentEditable) return;\r\n\r\n if (e.key === ' ') {\r\n this.spaceHeld = true;\r\n }\r\n if (e.key === 'Delete' || e.key === 'Backspace') {\r\n this.deleteSelected();\r\n }\r\n if ((e.ctrlKey || e.metaKey) && e.key === 'z' && !e.shiftKey) {\r\n e.preventDefault();\r\n this.handleUndo();\r\n }\r\n if ((e.ctrlKey || e.metaKey) && (e.key === 'y' || (e.key === 'z' && e.shiftKey))) {\r\n e.preventDefault();\r\n this.handleRedo();\r\n }\r\n };\r\n\r\n private onKeyUp = (e: KeyboardEvent): void => {\r\n if (e.key === ' ') {\r\n this.spaceHeld = false;\r\n }\r\n };\r\n\r\n private startPinch(): void {\r\n this.isPanning = true;\r\n const [a, b] = this.getPinchPoints();\r\n this.lastPinchDistance = this.distance(a, b);\r\n this.lastPinchCenter = this.midpoint(a, b);\r\n this.lastPointer = { ...this.lastPinchCenter };\r\n }\r\n\r\n private handlePinchMove(): void {\r\n const [a, b] = this.getPinchPoints();\r\n const dist = this.distance(a, b);\r\n const center = this.midpoint(a, b);\r\n\r\n if (this.lastPinchDistance > 0) {\r\n const scale = dist / this.lastPinchDistance;\r\n const newZoom = this.camera.zoom * scale;\r\n this.camera.zoomAt(newZoom, center);\r\n }\r\n\r\n const dx = center.x - this.lastPointer.x;\r\n const dy = center.y - this.lastPointer.y;\r\n this.camera.pan(dx, dy);\r\n\r\n this.lastPinchDistance = dist;\r\n this.lastPinchCenter = center;\r\n this.lastPointer = { ...center };\r\n }\r\n\r\n private getPinchPoints(): [{ x: number; y: number }, { x: number; y: number }] {\r\n const pts = [...this.activePointers.values()];\r\n return [pts[0] ?? { x: 0, y: 0 }, pts[1] ?? { x: 0, y: 0 }];\r\n }\r\n\r\n private distance(a: { x: number; y: number }, b: { x: number; y: number }): number {\r\n const dx = a.x - b.x;\r\n const dy = a.y - b.y;\r\n return Math.sqrt(dx * dx + dy * dy);\r\n }\r\n\r\n private midpoint(\r\n a: { x: number; y: number },\r\n b: { x: number; y: number },\r\n ): { x: number; y: number } {\r\n return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\r\n }\r\n\r\n private toPointerState(e: PointerEvent): PointerState {\r\n const rect = this.element.getBoundingClientRect();\r\n return {\r\n x: e.clientX - rect.left,\r\n y: e.clientY - rect.top,\r\n pressure: e.pressure,\r\n };\r\n }\r\n\r\n private dispatchToolDown(e: PointerEvent): void {\r\n if (!this.toolManager || !this.toolContext) return;\r\n this.historyRecorder?.begin();\r\n this.isToolActive = true;\r\n this.toolManager.handlePointerDown(this.toPointerState(e), this.toolContext);\r\n }\r\n\r\n private dispatchToolMove(e: PointerEvent): void {\r\n if (!this.toolManager || !this.toolContext) return;\r\n this.toolManager.handlePointerMove(this.toPointerState(e), this.toolContext);\r\n }\r\n\r\n private dispatchToolHover(e: PointerEvent): void {\r\n if (!this.toolManager?.activeTool || !this.toolContext) return;\r\n const tool = this.toolManager.activeTool;\r\n if (tool.onHover) {\r\n tool.onHover(this.toPointerState(e), this.toolContext);\r\n }\r\n }\r\n\r\n private dispatchToolUp(e: PointerEvent): void {\r\n if (!this.toolManager || !this.toolContext) return;\r\n this.toolManager.handlePointerUp(this.toPointerState(e), this.toolContext);\r\n this.historyRecorder?.commit();\r\n }\r\n\r\n private deleteSelected(): void {\r\n if (!this.toolManager || !this.toolContext) return;\r\n const tool = this.toolManager.activeTool;\r\n if (tool?.name !== 'select') return;\r\n const selectTool = tool as SelectTool;\r\n const ids = selectTool.selectedIds;\r\n if (ids.length === 0) return;\r\n this.historyRecorder?.begin();\r\n for (const id of ids) {\r\n this.toolContext.store.remove(id);\r\n }\r\n this.historyRecorder?.commit();\r\n this.toolContext.requestRender();\r\n }\r\n\r\n private handleUndo(): void {\r\n if (!this.historyStack || !this.toolContext) return;\r\n this.historyRecorder?.pause();\r\n this.historyStack.undo(this.toolContext.store);\r\n this.historyRecorder?.resume();\r\n this.toolContext.requestRender();\r\n }\r\n\r\n private handleRedo(): void {\r\n if (!this.historyStack || !this.toolContext) return;\r\n this.historyRecorder?.pause();\r\n this.historyStack.redo(this.toolContext.store);\r\n this.historyRecorder?.resume();\r\n this.toolContext.requestRender();\r\n }\r\n\r\n private cancelToolIfActive(e: PointerEvent): void {\r\n if (this.isToolActive) {\r\n this.dispatchToolUp(e);\r\n this.isToolActive = false;\r\n }\r\n }\r\n}\r\n","import { EventBus } from '../core/event-bus';\r\nimport type { CanvasElement, ElementType } from './types';\r\n\r\nexport interface ElementUpdateEvent {\r\n previous: CanvasElement;\r\n current: CanvasElement;\r\n}\r\n\r\ninterface ElementStoreEvents {\r\n add: CanvasElement;\r\n remove: CanvasElement;\r\n update: ElementUpdateEvent;\r\n clear: null;\r\n}\r\n\r\nexport class ElementStore {\r\n private elements = new Map<string, CanvasElement>();\r\n private bus = new EventBus<ElementStoreEvents>();\r\n private layerOrderMap = new Map<string, number>();\r\n\r\n get count(): number {\r\n return this.elements.size;\r\n }\r\n\r\n setLayerOrder(order: Map<string, number>): void {\r\n this.layerOrderMap = new Map(order);\r\n }\r\n\r\n getAll(): CanvasElement[] {\r\n return [...this.elements.values()].sort((a, b) => {\r\n const layerA = this.layerOrderMap.get(a.layerId) ?? 0;\r\n const layerB = this.layerOrderMap.get(b.layerId) ?? 0;\r\n if (layerA !== layerB) return layerA - layerB;\r\n return a.zIndex - b.zIndex;\r\n });\r\n }\r\n\r\n getById(id: string): CanvasElement | undefined {\r\n return this.elements.get(id);\r\n }\r\n\r\n getElementsByType<T extends ElementType>(type: T): Extract<CanvasElement, { type: T }>[] {\r\n return this.getAll().filter(\r\n (el): el is Extract<CanvasElement, { type: T }> => el.type === type,\r\n );\r\n }\r\n\r\n add(element: CanvasElement): void {\r\n this.elements.set(element.id, element);\r\n this.bus.emit('add', element);\r\n }\r\n\r\n update(id: string, partial: Partial<CanvasElement>): void {\r\n const existing = this.elements.get(id);\r\n if (!existing) return;\r\n\r\n const updated = { ...existing, ...partial, id: existing.id, type: existing.type };\r\n this.elements.set(id, updated as CanvasElement);\r\n this.bus.emit('update', { previous: existing, current: updated as CanvasElement });\r\n }\r\n\r\n remove(id: string): void {\r\n const element = this.elements.get(id);\r\n if (!element) return;\r\n\r\n this.elements.delete(id);\r\n this.bus.emit('remove', element);\r\n }\r\n\r\n clear(): void {\r\n this.elements.clear();\r\n this.bus.emit('clear', null);\r\n }\r\n\r\n snapshot(): CanvasElement[] {\r\n return this.getAll().map((el) => ({ ...el }));\r\n }\r\n\r\n loadSnapshot(elements: CanvasElement[]): void {\r\n this.elements.clear();\r\n for (const el of elements) {\r\n this.elements.set(el.id, el);\r\n }\r\n }\r\n\r\n on<K extends keyof ElementStoreEvents>(\r\n event: K,\r\n listener: (data: ElementStoreEvents[K]) => void,\r\n ): () => void {\r\n return this.bus.on(event, listener);\r\n }\r\n}\r\n","import type { Point } from '../core/types';\r\n\r\nexport interface Rect {\r\n x: number;\r\n y: number;\r\n w: number;\r\n h: number;\r\n}\r\n\r\nexport function getArrowControlPoint(from: Point, to: Point, bend: number): Point {\r\n const midX = (from.x + to.x) / 2;\r\n const midY = (from.y + to.y) / 2;\r\n\r\n if (bend === 0) return { x: midX, y: midY };\r\n\r\n const dx = to.x - from.x;\r\n const dy = to.y - from.y;\r\n const len = Math.sqrt(dx * dx + dy * dy);\r\n\r\n if (len === 0) return { x: midX, y: midY };\r\n\r\n const perpX = -dy / len;\r\n const perpY = dx / len;\r\n\r\n return {\r\n x: midX + perpX * bend,\r\n y: midY + perpY * bend,\r\n };\r\n}\r\n\r\nexport function getArrowMidpoint(from: Point, to: Point, bend: number): Point {\r\n const cp = getArrowControlPoint(from, to, bend);\r\n return {\r\n x: 0.25 * from.x + 0.5 * cp.x + 0.25 * to.x,\r\n y: 0.25 * from.y + 0.5 * cp.y + 0.25 * to.y,\r\n };\r\n}\r\n\r\nexport function getBendFromPoint(from: Point, to: Point, dragPoint: Point): number {\r\n const midX = (from.x + to.x) / 2;\r\n const midY = (from.y + to.y) / 2;\r\n\r\n const dx = to.x - from.x;\r\n const dy = to.y - from.y;\r\n const len = Math.sqrt(dx * dx + dy * dy);\r\n\r\n if (len === 0) return 0;\r\n\r\n const perpX = -dy / len;\r\n const perpY = dx / len;\r\n\r\n return (dragPoint.x - midX) * perpX + (dragPoint.y - midY) * perpY;\r\n}\r\n\r\nexport function getArrowTangentAngle(from: Point, to: Point, bend: number, t: number): number {\r\n const cp = getArrowControlPoint(from, to, bend);\r\n\r\n const tangentX = 2 * (1 - t) * (cp.x - from.x) + 2 * t * (to.x - cp.x);\r\n const tangentY = 2 * (1 - t) * (cp.y - from.y) + 2 * t * (to.y - cp.y);\r\n\r\n return Math.atan2(tangentY, tangentX);\r\n}\r\n\r\nexport function isNearBezier(\r\n point: Point,\r\n from: Point,\r\n to: Point,\r\n bend: number,\r\n threshold: number,\r\n): boolean {\r\n if (bend === 0) return isNearLine(point, from, to, threshold);\r\n\r\n const cp = getArrowControlPoint(from, to, bend);\r\n const segments = 20;\r\n\r\n for (let i = 0; i < segments; i++) {\r\n const t0 = i / segments;\r\n const t1 = (i + 1) / segments;\r\n const a = bezierPoint(from, cp, to, t0);\r\n const b = bezierPoint(from, cp, to, t1);\r\n if (isNearLine(point, a, b, threshold)) return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function getArrowBounds(from: Point, to: Point, bend: number): Rect {\r\n if (bend === 0) {\r\n const minX = Math.min(from.x, to.x);\r\n const minY = Math.min(from.y, to.y);\r\n return {\r\n x: minX,\r\n y: minY,\r\n w: Math.abs(to.x - from.x),\r\n h: Math.abs(to.y - from.y),\r\n };\r\n }\r\n\r\n const cp = getArrowControlPoint(from, to, bend);\r\n const steps = 20;\r\n let minX = Math.min(from.x, to.x);\r\n let minY = Math.min(from.y, to.y);\r\n let maxX = Math.max(from.x, to.x);\r\n let maxY = Math.max(from.y, to.y);\r\n\r\n for (let i = 1; i < steps; i++) {\r\n const t = i / steps;\r\n const p = bezierPoint(from, cp, to, t);\r\n if (p.x < minX) minX = p.x;\r\n if (p.y < minY) minY = p.y;\r\n if (p.x > maxX) maxX = p.x;\r\n if (p.y > maxY) maxY = p.y;\r\n }\r\n\r\n return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };\r\n}\r\n\r\nfunction bezierPoint(from: Point, cp: Point, to: Point, t: number): Point {\r\n const mt = 1 - t;\r\n return {\r\n x: mt * mt * from.x + 2 * mt * t * cp.x + t * t * to.x,\r\n y: mt * mt * from.y + 2 * mt * t * cp.y + t * t * to.y,\r\n };\r\n}\r\n\r\nfunction isNearLine(point: Point, a: Point, b: Point, threshold: number): boolean {\r\n const dx = b.x - a.x;\r\n const dy = b.y - a.y;\r\n const lenSq = dx * dx + dy * dy;\r\n\r\n if (lenSq === 0) {\r\n return Math.hypot(point.x - a.x, point.y - a.y) <= threshold;\r\n }\r\n\r\n const t = Math.max(0, Math.min(1, ((point.x - a.x) * dx + (point.y - a.y) * dy) / lenSq));\r\n const projX = a.x + t * dx;\r\n const projY = a.y + t * dy;\r\n return Math.hypot(point.x - projX, point.y - projY) <= threshold;\r\n}\r\n","import type { Point } from '../core/types';\r\nimport type { ArrowElement, CanvasElement } from './types';\r\nimport type { ElementStore } from './element-store';\r\nimport { getArrowTangentAngle } from './arrow-geometry';\r\nimport type { Rect } from './arrow-geometry';\r\n\r\nconst BINDABLE_TYPES = new Set(['note', 'text', 'image', 'html', 'shape']);\r\n\r\nexport function isBindable(element: CanvasElement): boolean {\r\n return BINDABLE_TYPES.has(element.type);\r\n}\r\n\r\nexport function getElementCenter(element: CanvasElement): Point {\r\n if (!('size' in element)) {\r\n throw new Error(`getElementCenter: element type \"${element.type}\" has no size`);\r\n }\r\n return {\r\n x: element.position.x + element.size.w / 2,\r\n y: element.position.y + element.size.h / 2,\r\n };\r\n}\r\n\r\nexport function getElementBounds(element: CanvasElement): Rect | null {\r\n if (!('size' in element)) return null;\r\n return {\r\n x: element.position.x,\r\n y: element.position.y,\r\n w: element.size.w,\r\n h: element.size.h,\r\n };\r\n}\r\n\r\nexport function getEdgeIntersection(bounds: Rect, outsidePoint: Point): Point {\r\n const cx = bounds.x + bounds.w / 2;\r\n const cy = bounds.y + bounds.h / 2;\r\n const dx = outsidePoint.x - cx;\r\n const dy = outsidePoint.y - cy;\r\n\r\n if (dx === 0 && dy === 0) return { x: cx, y: cy };\r\n\r\n const halfW = bounds.w / 2;\r\n const halfH = bounds.h / 2;\r\n\r\n const scaleX = dx !== 0 ? halfW / Math.abs(dx) : Infinity;\r\n const scaleY = dy !== 0 ? halfH / Math.abs(dy) : Infinity;\r\n const scale = Math.min(scaleX, scaleY);\r\n\r\n return {\r\n x: cx + dx * scale,\r\n y: cy + dy * scale,\r\n };\r\n}\r\n\r\nexport function findBindTarget(\r\n point: Point,\r\n store: ElementStore,\r\n threshold: number,\r\n excludeId?: string,\r\n filter?: (el: CanvasElement) => boolean,\r\n): CanvasElement | null {\r\n let closest: CanvasElement | null = null;\r\n let closestDist = Infinity;\r\n\r\n for (const el of store.getAll()) {\r\n if (!isBindable(el)) continue;\r\n if (excludeId && el.id === excludeId) continue;\r\n if (filter && !filter(el)) continue;\r\n\r\n const bounds = getElementBounds(el);\r\n if (!bounds) continue;\r\n\r\n const dist = distToBounds(point, bounds);\r\n if (dist <= threshold && dist < closestDist) {\r\n closest = el;\r\n closestDist = dist;\r\n }\r\n }\r\n\r\n return closest;\r\n}\r\n\r\nfunction distToBounds(point: Point, bounds: Rect): number {\r\n const clampedX = Math.max(bounds.x, Math.min(point.x, bounds.x + bounds.w));\r\n const clampedY = Math.max(bounds.y, Math.min(point.y, bounds.y + bounds.h));\r\n return Math.hypot(point.x - clampedX, point.y - clampedY);\r\n}\r\n\r\nexport function findBoundArrows(elementId: string, store: ElementStore): ArrowElement[] {\r\n return store\r\n .getElementsByType('arrow')\r\n .filter((a) => a.fromBinding?.elementId === elementId || a.toBinding?.elementId === elementId);\r\n}\r\n\r\nexport function updateBoundArrow(\r\n arrow: ArrowElement,\r\n store: ElementStore,\r\n): Partial<ArrowElement> | null {\r\n if (!arrow.fromBinding && !arrow.toBinding) return null;\r\n\r\n const updates: Partial<ArrowElement> = {};\r\n\r\n if (arrow.fromBinding) {\r\n const el = store.getById(arrow.fromBinding.elementId);\r\n if (el) {\r\n const center = getElementCenter(el);\r\n updates.from = center;\r\n updates.position = center;\r\n }\r\n }\r\n\r\n if (arrow.toBinding) {\r\n const el = store.getById(arrow.toBinding.elementId);\r\n if (el) {\r\n updates.to = getElementCenter(el);\r\n }\r\n }\r\n\r\n return Object.keys(updates).length > 0 ? updates : null;\r\n}\r\n\r\nexport function clearStaleBindings(\r\n arrow: ArrowElement,\r\n store: ElementStore,\r\n): Partial<ArrowElement> | null {\r\n const updates: Partial<ArrowElement> = {};\r\n let hasUpdates = false;\r\n\r\n if (arrow.fromBinding && !store.getById(arrow.fromBinding.elementId)) {\r\n updates.fromBinding = undefined;\r\n hasUpdates = true;\r\n }\r\n\r\n if (arrow.toBinding && !store.getById(arrow.toBinding.elementId)) {\r\n updates.toBinding = undefined;\r\n hasUpdates = true;\r\n }\r\n\r\n return hasUpdates ? updates : null;\r\n}\r\n\r\nexport function unbindArrow(arrow: ArrowElement, store: ElementStore): Partial<ArrowElement> {\r\n const updates: Partial<ArrowElement> = {};\r\n\r\n if (arrow.fromBinding) {\r\n const el = store.getById(arrow.fromBinding.elementId);\r\n const bounds = el ? getElementBounds(el) : null;\r\n if (bounds) {\r\n const angle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 0);\r\n const rayTarget = {\r\n x: arrow.from.x + Math.cos(angle) * 1000,\r\n y: arrow.from.y + Math.sin(angle) * 1000,\r\n };\r\n const edge = getEdgeIntersection(bounds, rayTarget);\r\n updates.from = edge;\r\n updates.position = edge;\r\n }\r\n updates.fromBinding = undefined;\r\n }\r\n\r\n if (arrow.toBinding) {\r\n const el = store.getById(arrow.toBinding.elementId);\r\n const bounds = el ? getElementBounds(el) : null;\r\n if (bounds) {\r\n const angle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 1);\r\n // Reverse tangent direction — tangent at t=1 points away from curve body\r\n const rayTarget = {\r\n x: arrow.to.x - Math.cos(angle) * 1000,\r\n y: arrow.to.y - Math.sin(angle) * 1000,\r\n };\r\n updates.to = getEdgeIntersection(bounds, rayTarget);\r\n }\r\n updates.toBinding = undefined;\r\n }\r\n\r\n return updates;\r\n}\r\n","import type { Point, StrokePoint } from '../core/types';\r\n\r\nexport interface CurveSegment {\r\n start: StrokePoint;\r\n cp1: Point;\r\n cp2: Point;\r\n end: StrokePoint;\r\n}\r\n\r\nconst MIN_PRESSURE_SCALE = 0.2;\r\n\r\nexport function pressureToWidth(pressure: number, baseWidth: number): number {\r\n return baseWidth * (MIN_PRESSURE_SCALE + (1 - MIN_PRESSURE_SCALE) * pressure);\r\n}\r\n\r\nexport function simplifyPoints(points: StrokePoint[], tolerance: number): StrokePoint[] {\r\n if (points.length <= 2) return points.slice();\r\n return rdp(points, 0, points.length - 1, tolerance);\r\n}\r\n\r\nfunction rdp(points: StrokePoint[], start: number, end: number, tolerance: number): StrokePoint[] {\r\n const first = points[start];\r\n const last = points[end];\r\n if (!first || !last) return [];\r\n\r\n if (end - start <= 1) return [first, last];\r\n\r\n let maxDist = 0;\r\n let maxIndex = start;\r\n\r\n for (let i = start + 1; i < end; i++) {\r\n const pt = points[i];\r\n if (!pt) continue;\r\n const dist = perpendicularDistance(pt, first, last);\r\n if (dist > maxDist) {\r\n maxDist = dist;\r\n maxIndex = i;\r\n }\r\n }\r\n\r\n if (maxDist <= tolerance) return [first, last];\r\n\r\n const left = rdp(points, start, maxIndex, tolerance);\r\n const right = rdp(points, maxIndex, end, tolerance);\r\n\r\n return left.concat(right.slice(1));\r\n}\r\n\r\nfunction perpendicularDistance(pt: Point, lineStart: Point, lineEnd: Point): number {\r\n const dx = lineEnd.x - lineStart.x;\r\n const dy = lineEnd.y - lineStart.y;\r\n const lenSq = dx * dx + dy * dy;\r\n\r\n if (lenSq === 0) {\r\n const ex = pt.x - lineStart.x;\r\n const ey = pt.y - lineStart.y;\r\n return Math.sqrt(ex * ex + ey * ey);\r\n }\r\n\r\n const num = Math.abs(dy * pt.x - dx * pt.y + lineEnd.x * lineStart.y - lineEnd.y * lineStart.x);\r\n return num / Math.sqrt(lenSq);\r\n}\r\n\r\nexport function smoothToSegments(points: StrokePoint[]): CurveSegment[] {\r\n if (points.length < 2) return [];\r\n\r\n if (points.length === 2) {\r\n const p0 = points[0];\r\n const p1 = points[1];\r\n if (!p0 || !p1) return [];\r\n const mx = (p0.x + p1.x) / 2;\r\n const my = (p0.y + p1.y) / 2;\r\n return [{ start: p0, cp1: { x: mx, y: my }, cp2: { x: mx, y: my }, end: p1 }];\r\n }\r\n\r\n const segments: CurveSegment[] = [];\r\n const n = points.length;\r\n\r\n for (let i = 0; i < n - 1; i++) {\r\n const p0 = points[Math.max(0, i - 1)];\r\n const p1 = points[i];\r\n const p2 = points[i + 1];\r\n const p3 = points[Math.min(n - 1, i + 2)];\r\n if (!p0 || !p1 || !p2 || !p3) continue;\r\n\r\n const cp1: Point = {\r\n x: p1.x + (p2.x - p0.x) / 6,\r\n y: p1.y + (p2.y - p0.y) / 6,\r\n };\r\n const cp2: Point = {\r\n x: p2.x - (p3.x - p1.x) / 6,\r\n y: p2.y - (p3.y - p1.y) / 6,\r\n };\r\n\r\n segments.push({ start: p1, cp1, cp2, end: p2 });\r\n }\r\n\r\n return segments;\r\n}\r\n","import type { HexOrientation } from './types';\r\n\r\nexport interface VisibleBounds {\r\n minX: number;\r\n minY: number;\r\n maxX: number;\r\n maxY: number;\r\n}\r\n\r\nexport interface SquareGridLines {\r\n verticals: number[];\r\n horizontals: number[];\r\n}\r\n\r\nexport function getSquareGridLines(bounds: VisibleBounds, cellSize: number): SquareGridLines {\r\n if (cellSize <= 0) return { verticals: [], horizontals: [] };\r\n\r\n const verticals: number[] = [];\r\n const startX = Math.floor(bounds.minX / cellSize) * cellSize;\r\n const endX = Math.ceil(bounds.maxX / cellSize) * cellSize;\r\n for (let x = startX; x <= endX; x += cellSize) {\r\n verticals.push(x);\r\n }\r\n\r\n const horizontals: number[] = [];\r\n const startY = Math.floor(bounds.minY / cellSize) * cellSize;\r\n const endY = Math.ceil(bounds.maxY / cellSize) * cellSize;\r\n for (let y = startY; y <= endY; y += cellSize) {\r\n horizontals.push(y);\r\n }\r\n\r\n return { verticals, horizontals };\r\n}\r\n\r\nexport interface HexVertex {\r\n x: number;\r\n y: number;\r\n}\r\n\r\nexport function getHexVertices(\r\n cx: number,\r\n cy: number,\r\n circumradius: number,\r\n orientation: HexOrientation,\r\n): HexVertex[] {\r\n const vertices: HexVertex[] = [];\r\n const angleOffset = orientation === 'pointy' ? -Math.PI / 2 : 0;\r\n for (let i = 0; i < 6; i++) {\r\n const angle = (Math.PI / 3) * i + angleOffset;\r\n vertices.push({\r\n x: cx + circumradius * Math.cos(angle),\r\n y: cy + circumradius * Math.sin(angle),\r\n });\r\n }\r\n return vertices;\r\n}\r\n\r\nexport function getHexCenters(\r\n bounds: VisibleBounds,\r\n circumradius: number,\r\n orientation: HexOrientation,\r\n): HexVertex[] {\r\n if (circumradius <= 0) return [];\r\n\r\n const centers: HexVertex[] = [];\r\n\r\n if (orientation === 'pointy') {\r\n const hexW = Math.sqrt(3) * circumradius;\r\n const hexH = 2 * circumradius;\r\n const rowH = hexH * 0.75;\r\n\r\n const startRow = Math.floor((bounds.minY - circumradius) / rowH);\r\n const endRow = Math.ceil((bounds.maxY + circumradius) / rowH);\r\n const startCol = Math.floor((bounds.minX - hexW) / hexW);\r\n const endCol = Math.ceil((bounds.maxX + hexW) / hexW);\r\n\r\n for (let row = startRow; row <= endRow; row++) {\r\n const offsetX = row % 2 !== 0 ? hexW / 2 : 0;\r\n for (let col = startCol; col <= endCol; col++) {\r\n centers.push({\r\n x: col * hexW + offsetX,\r\n y: row * rowH,\r\n });\r\n }\r\n }\r\n } else {\r\n const hexW = 2 * circumradius;\r\n const hexH = Math.sqrt(3) * circumradius;\r\n const colW = hexW * 0.75;\r\n\r\n const startCol = Math.floor((bounds.minX - circumradius) / colW);\r\n const endCol = Math.ceil((bounds.maxX + circumradius) / colW);\r\n const startRow = Math.floor((bounds.minY - hexH) / hexH);\r\n const endRow = Math.ceil((bounds.maxY + hexH) / hexH);\r\n\r\n for (let col = startCol; col <= endCol; col++) {\r\n const offsetY = col % 2 !== 0 ? hexH / 2 : 0;\r\n for (let row = startRow; row <= endRow; row++) {\r\n centers.push({\r\n x: col * colW,\r\n y: row * hexH + offsetY,\r\n });\r\n }\r\n }\r\n }\r\n\r\n return centers;\r\n}\r\n\r\nexport function renderSquareGrid(\r\n ctx: CanvasRenderingContext2D,\r\n bounds: VisibleBounds,\r\n cellSize: number,\r\n strokeColor: string,\r\n strokeWidth: number,\r\n opacity: number,\r\n): void {\r\n if (cellSize <= 0) return;\r\n\r\n const { verticals, horizontals } = getSquareGridLines(bounds, cellSize);\r\n\r\n ctx.save();\r\n ctx.strokeStyle = strokeColor;\r\n ctx.lineWidth = strokeWidth;\r\n ctx.globalAlpha = opacity;\r\n ctx.beginPath();\r\n\r\n for (const x of verticals) {\r\n ctx.moveTo(x, bounds.minY);\r\n ctx.lineTo(x, bounds.maxY);\r\n }\r\n for (const y of horizontals) {\r\n ctx.moveTo(bounds.minX, y);\r\n ctx.lineTo(bounds.maxX, y);\r\n }\r\n\r\n ctx.stroke();\r\n ctx.restore();\r\n}\r\n\r\nexport function renderHexGrid(\r\n ctx: CanvasRenderingContext2D,\r\n bounds: VisibleBounds,\r\n cellSize: number,\r\n orientation: HexOrientation,\r\n strokeColor: string,\r\n strokeWidth: number,\r\n opacity: number,\r\n): void {\r\n if (cellSize <= 0) return;\r\n\r\n const centers = getHexCenters(bounds, cellSize, orientation);\r\n\r\n ctx.save();\r\n ctx.strokeStyle = strokeColor;\r\n ctx.lineWidth = strokeWidth;\r\n ctx.globalAlpha = opacity;\r\n ctx.beginPath();\r\n\r\n for (const center of centers) {\r\n const verts = getHexVertices(center.x, center.y, cellSize, orientation);\r\n const first = verts[0];\r\n if (!first) continue;\r\n ctx.moveTo(first.x, first.y);\r\n for (let i = 1; i < verts.length; i++) {\r\n const v = verts[i];\r\n if (!v) continue;\r\n ctx.lineTo(v.x, v.y);\r\n }\r\n ctx.closePath();\r\n }\r\n\r\n ctx.stroke();\r\n ctx.restore();\r\n}\r\n","import type {\r\n CanvasElement,\r\n StrokeElement,\r\n ArrowElement,\r\n ShapeElement,\r\n ImageElement,\r\n GridElement,\r\n} from './types';\r\nimport { getArrowControlPoint, getArrowTangentAngle } from './arrow-geometry';\r\nimport { getElementBounds, getEdgeIntersection } from './arrow-binding';\r\nimport { smoothToSegments, pressureToWidth } from './stroke-smoothing';\r\nimport type { ElementStore } from './element-store';\r\nimport { renderSquareGrid, renderHexGrid } from './grid-renderer';\r\nimport type { Camera } from '../canvas/camera';\r\n\r\nconst DOM_ELEMENT_TYPES = new Set(['note', 'html', 'text']);\r\nconst ARROWHEAD_LENGTH = 12;\r\nconst ARROWHEAD_ANGLE = Math.PI / 6;\r\n\r\nexport class ElementRenderer {\r\n private store: ElementStore | null = null;\r\n private imageCache = new Map<string, HTMLImageElement>();\r\n private onImageLoad: (() => void) | null = null;\r\n private camera: Camera | null = null;\r\n private canvasSize: { w: number; h: number } | null = null;\r\n\r\n setStore(store: ElementStore): void {\r\n this.store = store;\r\n }\r\n\r\n setOnImageLoad(callback: () => void): void {\r\n this.onImageLoad = callback;\r\n }\r\n\r\n setCamera(camera: Camera): void {\r\n this.camera = camera;\r\n }\r\n\r\n setCanvasSize(w: number, h: number): void {\r\n this.canvasSize = { w, h };\r\n }\r\n\r\n isDomElement(element: CanvasElement): boolean {\r\n return DOM_ELEMENT_TYPES.has(element.type);\r\n }\r\n\r\n renderCanvasElement(ctx: CanvasRenderingContext2D, element: CanvasElement): void {\r\n switch (element.type) {\r\n case 'stroke':\r\n this.renderStroke(ctx, element);\r\n break;\r\n case 'arrow':\r\n this.renderArrow(ctx, element);\r\n break;\r\n case 'shape':\r\n this.renderShape(ctx, element);\r\n break;\r\n case 'image':\r\n this.renderImage(ctx, element);\r\n break;\r\n case 'grid':\r\n this.renderGrid(ctx, element);\r\n break;\r\n }\r\n }\r\n\r\n private renderStroke(ctx: CanvasRenderingContext2D, stroke: StrokeElement): void {\r\n if (stroke.points.length < 2) return;\r\n\r\n ctx.save();\r\n ctx.translate(stroke.position.x, stroke.position.y);\r\n ctx.strokeStyle = stroke.color;\r\n ctx.lineCap = 'round';\r\n ctx.lineJoin = 'round';\r\n ctx.globalAlpha = stroke.opacity;\r\n\r\n const segments = smoothToSegments(stroke.points);\r\n for (const seg of segments) {\r\n const w =\r\n (pressureToWidth(seg.start.pressure, stroke.width) +\r\n pressureToWidth(seg.end.pressure, stroke.width)) /\r\n 2;\r\n ctx.lineWidth = w;\r\n ctx.beginPath();\r\n ctx.moveTo(seg.start.x, seg.start.y);\r\n ctx.bezierCurveTo(seg.cp1.x, seg.cp1.y, seg.cp2.x, seg.cp2.y, seg.end.x, seg.end.y);\r\n ctx.stroke();\r\n }\r\n\r\n ctx.restore();\r\n }\r\n\r\n private renderArrow(ctx: CanvasRenderingContext2D, arrow: ArrowElement): void {\r\n const { visualFrom, visualTo } = this.getVisualEndpoints(arrow);\r\n\r\n ctx.save();\r\n ctx.strokeStyle = arrow.color;\r\n ctx.lineWidth = arrow.width;\r\n ctx.lineCap = 'round';\r\n\r\n if (arrow.fromBinding || arrow.toBinding) {\r\n ctx.setLineDash([8, 4]);\r\n }\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(visualFrom.x, visualFrom.y);\r\n\r\n if (arrow.bend !== 0) {\r\n const cp = getArrowControlPoint(arrow.from, arrow.to, arrow.bend);\r\n ctx.quadraticCurveTo(cp.x, cp.y, visualTo.x, visualTo.y);\r\n } else {\r\n ctx.lineTo(visualTo.x, visualTo.y);\r\n }\r\n ctx.stroke();\r\n\r\n this.renderArrowhead(ctx, arrow, visualTo);\r\n ctx.restore();\r\n }\r\n\r\n private renderArrowhead(\r\n ctx: CanvasRenderingContext2D,\r\n arrow: ArrowElement,\r\n tip: { x: number; y: number },\r\n ): void {\r\n const angle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 1);\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(tip.x, tip.y);\r\n ctx.lineTo(\r\n tip.x - ARROWHEAD_LENGTH * Math.cos(angle - ARROWHEAD_ANGLE),\r\n tip.y - ARROWHEAD_LENGTH * Math.sin(angle - ARROWHEAD_ANGLE),\r\n );\r\n ctx.lineTo(\r\n tip.x - ARROWHEAD_LENGTH * Math.cos(angle + ARROWHEAD_ANGLE),\r\n tip.y - ARROWHEAD_LENGTH * Math.sin(angle + ARROWHEAD_ANGLE),\r\n );\r\n ctx.closePath();\r\n ctx.fillStyle = arrow.color;\r\n ctx.fill();\r\n }\r\n\r\n private getVisualEndpoints(arrow: ArrowElement): {\r\n visualFrom: { x: number; y: number };\r\n visualTo: { x: number; y: number };\r\n } {\r\n let visualFrom = arrow.from;\r\n let visualTo = arrow.to;\r\n\r\n if (!this.store) return { visualFrom, visualTo };\r\n\r\n if (arrow.fromBinding) {\r\n const el = this.store.getById(arrow.fromBinding.elementId);\r\n if (el) {\r\n const bounds = getElementBounds(el);\r\n if (bounds) {\r\n const tangentAngle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 0);\r\n const rayTarget = {\r\n x: arrow.from.x + Math.cos(tangentAngle) * 1000,\r\n y: arrow.from.y + Math.sin(tangentAngle) * 1000,\r\n };\r\n visualFrom = getEdgeIntersection(bounds, rayTarget);\r\n }\r\n }\r\n }\r\n\r\n if (arrow.toBinding) {\r\n const el = this.store.getById(arrow.toBinding.elementId);\r\n if (el) {\r\n const bounds = getElementBounds(el);\r\n if (bounds) {\r\n const tangentAngle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 1);\r\n // Reverse tangent — at t=1 tangent points away from curve body,\r\n // but we need the ray from center back toward the curve\r\n const rayTarget = {\r\n x: arrow.to.x - Math.cos(tangentAngle) * 1000,\r\n y: arrow.to.y - Math.sin(tangentAngle) * 1000,\r\n };\r\n visualTo = getEdgeIntersection(bounds, rayTarget);\r\n }\r\n }\r\n }\r\n\r\n return { visualFrom, visualTo };\r\n }\r\n\r\n private renderShape(ctx: CanvasRenderingContext2D, shape: ShapeElement): void {\r\n ctx.save();\r\n\r\n if (shape.fillColor !== 'none') {\r\n ctx.fillStyle = shape.fillColor;\r\n this.fillShapePath(ctx, shape);\r\n }\r\n\r\n if (shape.strokeWidth > 0) {\r\n ctx.strokeStyle = shape.strokeColor;\r\n ctx.lineWidth = shape.strokeWidth;\r\n this.strokeShapePath(ctx, shape);\r\n }\r\n\r\n ctx.restore();\r\n }\r\n\r\n private fillShapePath(ctx: CanvasRenderingContext2D, shape: ShapeElement): void {\r\n switch (shape.shape) {\r\n case 'rectangle':\r\n ctx.fillRect(shape.position.x, shape.position.y, shape.size.w, shape.size.h);\r\n break;\r\n case 'ellipse': {\r\n const cx = shape.position.x + shape.size.w / 2;\r\n const cy = shape.position.y + shape.size.h / 2;\r\n ctx.beginPath();\r\n ctx.ellipse(cx, cy, shape.size.w / 2, shape.size.h / 2, 0, 0, Math.PI * 2);\r\n ctx.fill();\r\n break;\r\n }\r\n }\r\n }\r\n\r\n private strokeShapePath(ctx: CanvasRenderingContext2D, shape: ShapeElement): void {\r\n switch (shape.shape) {\r\n case 'rectangle':\r\n ctx.strokeRect(shape.position.x, shape.position.y, shape.size.w, shape.size.h);\r\n break;\r\n case 'ellipse': {\r\n const cx = shape.position.x + shape.size.w / 2;\r\n const cy = shape.position.y + shape.size.h / 2;\r\n ctx.beginPath();\r\n ctx.ellipse(cx, cy, shape.size.w / 2, shape.size.h / 2, 0, 0, Math.PI * 2);\r\n ctx.stroke();\r\n break;\r\n }\r\n }\r\n }\r\n\r\n private renderGrid(ctx: CanvasRenderingContext2D, grid: GridElement): void {\r\n if (!this.canvasSize) return;\r\n\r\n const cam = this.camera;\r\n if (!cam) return;\r\n\r\n const topLeft = cam.screenToWorld({ x: 0, y: 0 });\r\n const bottomRight = cam.screenToWorld({\r\n x: this.canvasSize.w,\r\n y: this.canvasSize.h,\r\n });\r\n const bounds = {\r\n minX: topLeft.x,\r\n minY: topLeft.y,\r\n maxX: bottomRight.x,\r\n maxY: bottomRight.y,\r\n };\r\n\r\n if (grid.gridType === 'hex') {\r\n renderHexGrid(\r\n ctx,\r\n bounds,\r\n grid.cellSize,\r\n grid.hexOrientation,\r\n grid.strokeColor,\r\n grid.strokeWidth,\r\n grid.opacity,\r\n );\r\n } else {\r\n renderSquareGrid(\r\n ctx,\r\n bounds,\r\n grid.cellSize,\r\n grid.strokeColor,\r\n grid.strokeWidth,\r\n grid.opacity,\r\n );\r\n }\r\n }\r\n\r\n private renderImage(ctx: CanvasRenderingContext2D, image: ImageElement): void {\r\n const img = this.getImage(image.src);\r\n if (!img) return;\r\n ctx.drawImage(img, image.position.x, image.position.y, image.size.w, image.size.h);\r\n }\r\n\r\n private getImage(src: string): HTMLImageElement | null {\r\n const cached = this.imageCache.get(src);\r\n if (cached) return cached.complete ? cached : null;\r\n\r\n const img = new Image();\r\n img.src = src;\r\n this.imageCache.set(src, img);\r\n img.onload = () => this.onImageLoad?.();\r\n return null;\r\n }\r\n}\r\n","import type { ElementStore } from './element-store';\r\n\r\nexport class NoteEditor {\r\n private editingId: string | null = null;\r\n private editingNode: HTMLDivElement | null = null;\r\n private blurHandler: (() => void) | null = null;\r\n private keyHandler: ((e: KeyboardEvent) => void) | null = null;\r\n private pointerHandler: ((e: PointerEvent) => void) | null = null;\r\n private pendingEditId: string | null = null;\r\n private onStopCallback: ((elementId: string) => void) | null = null;\r\n\r\n get isEditing(): boolean {\r\n return this.editingId !== null;\r\n }\r\n\r\n get editingElementId(): string | null {\r\n return this.editingId;\r\n }\r\n\r\n setOnStop(callback: (elementId: string) => void): void {\r\n this.onStopCallback = callback;\r\n }\r\n\r\n startEditing(node: HTMLDivElement, elementId: string, store: ElementStore): void {\r\n if (this.editingId === elementId) return;\r\n\r\n if (this.editingId) {\r\n this.stopEditing(store);\r\n }\r\n\r\n this.pendingEditId = elementId;\r\n\r\n requestAnimationFrame(() => {\r\n if (this.pendingEditId !== elementId) return;\r\n this.pendingEditId = null;\r\n this.activateEditing(node, elementId, store);\r\n });\r\n }\r\n\r\n stopEditing(store: ElementStore): void {\r\n this.pendingEditId = null;\r\n\r\n if (!this.editingId || !this.editingNode) return;\r\n\r\n const text = this.editingNode.textContent ?? '';\r\n store.update(this.editingId, { text });\r\n\r\n this.editingNode.contentEditable = 'false';\r\n Object.assign(this.editingNode.style, {\r\n userSelect: 'none',\r\n cursor: 'default',\r\n });\r\n\r\n if (this.blurHandler) {\r\n this.editingNode.removeEventListener('blur', this.blurHandler);\r\n }\r\n if (this.keyHandler) {\r\n this.editingNode.removeEventListener('keydown', this.keyHandler);\r\n }\r\n if (this.pointerHandler) {\r\n this.editingNode.removeEventListener('pointerdown', this.pointerHandler);\r\n }\r\n\r\n if (this.editingId && this.onStopCallback) {\r\n this.onStopCallback(this.editingId);\r\n }\r\n\r\n this.editingId = null;\r\n this.editingNode = null;\r\n this.blurHandler = null;\r\n this.keyHandler = null;\r\n this.pointerHandler = null;\r\n }\r\n\r\n destroy(store: ElementStore): void {\r\n this.pendingEditId = null;\r\n if (this.isEditing) {\r\n this.stopEditing(store);\r\n }\r\n }\r\n\r\n private activateEditing(node: HTMLDivElement, elementId: string, store: ElementStore): void {\r\n this.editingId = elementId;\r\n this.editingNode = node;\r\n\r\n node.contentEditable = 'true';\r\n Object.assign(node.style, {\r\n userSelect: 'text',\r\n cursor: 'text',\r\n outline: 'none',\r\n });\r\n node.focus();\r\n\r\n const selection = window.getSelection?.();\r\n if (selection) {\r\n const range = document.createRange();\r\n range.selectNodeContents(node);\r\n range.collapse(false);\r\n selection.removeAllRanges();\r\n selection.addRange(range);\r\n }\r\n\r\n this.blurHandler = () => this.stopEditing(store);\r\n this.keyHandler = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n node.blur();\r\n }\r\n e.stopPropagation();\r\n };\r\n this.pointerHandler = (e: PointerEvent) => {\r\n e.stopPropagation();\r\n };\r\n\r\n node.addEventListener('blur', this.blurHandler);\r\n node.addEventListener('keydown', this.keyHandler);\r\n node.addEventListener('pointerdown', this.pointerHandler);\r\n }\r\n}\r\n","import type { Tool, ToolContext, PointerState } from './types';\r\n\r\nexport class ToolManager {\r\n private tools = new Map<string, Tool>();\r\n private current: Tool | null = null;\r\n private changeListeners = new Set<(name: string) => void>();\r\n\r\n get activeTool(): Tool | null {\r\n return this.current;\r\n }\r\n\r\n get toolNames(): string[] {\r\n return [...this.tools.keys()];\r\n }\r\n\r\n register(tool: Tool): void {\r\n this.tools.set(tool.name, tool);\r\n }\r\n\r\n getTool<T extends Tool = Tool>(name: string): T | undefined {\r\n return this.tools.get(name) as T | undefined;\r\n }\r\n\r\n setTool(name: string, ctx: ToolContext): void {\r\n const tool = this.tools.get(name);\r\n if (!tool) return;\r\n\r\n this.current?.onDeactivate?.(ctx);\r\n this.current = tool;\r\n this.current.onActivate?.(ctx);\r\n this.changeListeners.forEach((fn) => fn(name));\r\n }\r\n\r\n handlePointerDown(state: PointerState, ctx: ToolContext): void {\r\n this.current?.onPointerDown(state, ctx);\r\n }\r\n\r\n handlePointerMove(state: PointerState, ctx: ToolContext): void {\r\n this.current?.onPointerMove(state, ctx);\r\n }\r\n\r\n handlePointerUp(state: PointerState, ctx: ToolContext): void {\r\n this.current?.onPointerUp(state, ctx);\r\n }\r\n\r\n onChange(listener: (name: string) => void): () => void {\r\n this.changeListeners.add(listener);\r\n return () => this.changeListeners.delete(listener);\r\n }\r\n}\r\n","import type { ElementStore } from '../elements/element-store';\nimport type { Command } from './types';\n\nexport interface HistoryStackOptions {\n maxSize?: number;\n}\n\nconst DEFAULT_MAX_SIZE = 100;\n\nexport class HistoryStack {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private readonly maxSize: number;\n private changeListeners = new Set<() => void>();\n\n constructor(options: HistoryStackOptions = {}) {\n this.maxSize = options.maxSize ?? DEFAULT_MAX_SIZE;\n }\n\n get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n get undoCount(): number {\n return this.undoStack.length;\n }\n\n get redoCount(): number {\n return this.redoStack.length;\n }\n\n push(command: Command): void {\n this.undoStack.push(command);\n this.redoStack = [];\n\n if (this.undoStack.length > this.maxSize) {\n this.undoStack.shift();\n }\n\n this.notifyChange();\n }\n\n undo(store: ElementStore): boolean {\n const command = this.undoStack.pop();\n if (!command) return false;\n\n command.undo(store);\n this.redoStack.push(command);\n this.notifyChange();\n return true;\n }\n\n redo(store: ElementStore): boolean {\n const command = this.redoStack.pop();\n if (!command) return false;\n\n command.execute(store);\n this.undoStack.push(command);\n this.notifyChange();\n return true;\n }\n\n clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.notifyChange();\n }\n\n onChange(listener: () => void): () => void {\n this.changeListeners.add(listener);\n return () => this.changeListeners.delete(listener);\n }\n\n private notifyChange(): void {\n this.changeListeners.forEach((fn) => fn());\n }\n}\n","import type { CanvasElement } from '../elements/types';\nimport type { ElementStore } from '../elements/element-store';\nimport type { Command } from './types';\n\nexport class AddElementCommand implements Command {\n private readonly element: CanvasElement;\n\n constructor(element: CanvasElement) {\n this.element = { ...element };\n }\n\n execute(store: ElementStore): void {\n store.add(this.element);\n }\n\n undo(store: ElementStore): void {\n store.remove(this.element.id);\n }\n}\n\nexport class RemoveElementCommand implements Command {\n private readonly element: CanvasElement;\n\n constructor(element: CanvasElement) {\n this.element = { ...element };\n }\n\n execute(store: ElementStore): void {\n store.remove(this.element.id);\n }\n\n undo(store: ElementStore): void {\n store.add(this.element);\n }\n}\n\nexport class UpdateElementCommand implements Command {\n constructor(\n private readonly id: string,\n private readonly previous: CanvasElement,\n private readonly current: CanvasElement,\n ) {}\n\n execute(store: ElementStore): void {\n store.update(this.id, { ...this.current });\n }\n\n undo(store: ElementStore): void {\n store.update(this.id, { ...this.previous });\n }\n}\n\nexport class BatchCommand implements Command {\n readonly commands: readonly Command[];\n\n constructor(commands: Command[]) {\n this.commands = [...commands];\n }\n\n execute(store: ElementStore): void {\n for (const cmd of this.commands) {\n cmd.execute(store);\n }\n }\n\n undo(store: ElementStore): void {\n for (let i = this.commands.length - 1; i >= 0; i--) {\n this.commands[i]?.undo(store);\n }\n }\n}\n","import type { ElementStore } from '../elements/element-store';\nimport type { CanvasElement } from '../elements/types';\nimport type { Command } from './types';\nimport type { HistoryStack } from './history-stack';\nimport {\n AddElementCommand,\n RemoveElementCommand,\n UpdateElementCommand,\n BatchCommand,\n} from './commands';\n\nexport class HistoryRecorder {\n private recording = true;\n private transaction: Command[] | null = null;\n private updateSnapshots = new Map<string, CanvasElement>();\n private unsubscribers: (() => void)[];\n\n constructor(\n private readonly store: ElementStore,\n private readonly stack: HistoryStack,\n ) {\n this.unsubscribers = [\n store.on('add', (el) => this.onAdd(el)),\n store.on('remove', (el) => this.onRemove(el)),\n store.on('update', ({ previous, current }) => this.onUpdate(previous, current)),\n ];\n }\n\n pause(): void {\n this.recording = false;\n }\n\n resume(): void {\n this.recording = true;\n }\n\n begin(): void {\n this.transaction = [];\n this.updateSnapshots.clear();\n }\n\n commit(): void {\n if (!this.transaction) return;\n\n const finalCommands = this.flushUpdateSnapshots();\n const all = [...this.transaction, ...finalCommands];\n this.transaction = null;\n this.updateSnapshots.clear();\n\n if (all.length === 0) return;\n const first = all[0];\n this.stack.push(all.length === 1 && first ? first : new BatchCommand(all));\n }\n\n rollback(): void {\n this.transaction = null;\n this.updateSnapshots.clear();\n }\n\n destroy(): void {\n this.unsubscribers.forEach((fn) => fn());\n }\n\n private record(command: Command): void {\n if (this.transaction) {\n this.transaction.push(command);\n } else {\n this.stack.push(command);\n }\n }\n\n private onAdd(element: CanvasElement): void {\n if (!this.recording) return;\n this.record(new AddElementCommand(element));\n }\n\n private onRemove(element: CanvasElement): void {\n if (!this.recording) return;\n\n if (this.transaction && this.updateSnapshots.has(element.id)) {\n this.updateSnapshots.delete(element.id);\n }\n\n this.record(new RemoveElementCommand(element));\n }\n\n private onUpdate(previous: CanvasElement, current: CanvasElement): void {\n if (!this.recording) return;\n\n if (this.transaction) {\n if (!this.updateSnapshots.has(current.id)) {\n this.updateSnapshots.set(current.id, { ...previous });\n }\n } else {\n this.stack.push(new UpdateElementCommand(current.id, previous, current));\n }\n }\n\n private flushUpdateSnapshots(): Command[] {\n const commands: Command[] = [];\n for (const [id, previous] of this.updateSnapshots) {\n const current = this.store.getById(id);\n if (current) {\n commands.push(new UpdateElementCommand(id, previous, current));\n }\n }\n return commands;\n }\n}\n","let counter = 0;\n\nexport function createId(prefix: string): string {\n return `${prefix}_${Date.now().toString(36)}_${(counter++).toString(36)}`;\n}\n","import type { Point, Size, StrokePoint } from '../core/types';\r\nimport type {\r\n Binding,\r\n StrokeElement,\r\n NoteElement,\r\n ArrowElement,\r\n ImageElement,\r\n HtmlElement,\r\n TextElement,\r\n ShapeElement,\r\n ShapeKind,\r\n GridElement,\r\n HexOrientation,\r\n} from './types';\r\nimport { createId } from './create-id';\r\n\r\ninterface BaseDefaults {\r\n position?: Point;\r\n zIndex?: number;\r\n locked?: boolean;\r\n layerId?: string;\r\n}\r\n\r\ninterface StrokeInput extends BaseDefaults {\r\n points: StrokePoint[];\r\n color?: string;\r\n width?: number;\r\n opacity?: number;\r\n}\r\n\r\ninterface NoteInput extends BaseDefaults {\r\n position: Point;\r\n size?: Size;\r\n text?: string;\r\n backgroundColor?: string;\r\n textColor?: string;\r\n}\r\n\r\ninterface ArrowInput extends BaseDefaults {\r\n from: Point;\r\n to: Point;\r\n bend?: number;\r\n color?: string;\r\n width?: number;\r\n fromBinding?: Binding;\r\n toBinding?: Binding;\r\n}\r\n\r\ninterface ImageInput extends BaseDefaults {\r\n position: Point;\r\n size: Size;\r\n src: string;\r\n}\r\n\r\ninterface HtmlInput extends BaseDefaults {\r\n position: Point;\r\n size: Size;\r\n domId?: string;\r\n}\r\n\r\ninterface TextInput extends BaseDefaults {\r\n position: Point;\r\n size?: Size;\r\n text?: string;\r\n fontSize?: number;\r\n color?: string;\r\n textAlign?: 'left' | 'center' | 'right';\r\n}\r\n\r\nexport function createStroke(input: StrokeInput): StrokeElement {\r\n return {\r\n id: createId('stroke'),\r\n type: 'stroke',\r\n position: input.position ?? { x: 0, y: 0 },\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n points: input.points,\r\n color: input.color ?? '#000000',\r\n width: input.width ?? 2,\r\n opacity: input.opacity ?? 1,\r\n };\r\n}\r\n\r\nexport function createNote(input: NoteInput): NoteElement {\r\n return {\r\n id: createId('note'),\r\n type: 'note',\r\n position: input.position,\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n size: input.size ?? { w: 200, h: 100 },\r\n text: input.text ?? '',\r\n backgroundColor: input.backgroundColor ?? '#ffeb3b',\r\n textColor: input.textColor ?? '#000000',\r\n };\r\n}\r\n\r\nexport function createArrow(input: ArrowInput): ArrowElement {\r\n const result: ArrowElement = {\r\n id: createId('arrow'),\r\n type: 'arrow',\r\n position: input.position ?? { x: 0, y: 0 },\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n from: input.from,\r\n to: input.to,\r\n bend: input.bend ?? 0,\r\n color: input.color ?? '#000000',\r\n width: input.width ?? 2,\r\n };\r\n if (input.fromBinding) result.fromBinding = input.fromBinding;\r\n if (input.toBinding) result.toBinding = input.toBinding;\r\n return result;\r\n}\r\n\r\nexport function createImage(input: ImageInput): ImageElement {\r\n return {\r\n id: createId('image'),\r\n type: 'image',\r\n position: input.position,\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n size: input.size,\r\n src: input.src,\r\n };\r\n}\r\n\r\nexport function createHtmlElement(input: HtmlInput): HtmlElement {\r\n const el: HtmlElement = {\r\n id: createId('html'),\r\n type: 'html',\r\n position: input.position,\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n size: input.size,\r\n };\r\n if (input.domId) el.domId = input.domId;\r\n return el;\r\n}\r\n\r\ninterface ShapeInput extends BaseDefaults {\r\n position: Point;\r\n size: Size;\r\n shape?: ShapeKind;\r\n strokeColor?: string;\r\n strokeWidth?: number;\r\n fillColor?: string;\r\n}\r\n\r\nexport function createShape(input: ShapeInput): ShapeElement {\r\n return {\r\n id: createId('shape'),\r\n type: 'shape',\r\n position: input.position,\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n shape: input.shape ?? 'rectangle',\r\n size: input.size,\r\n strokeColor: input.strokeColor ?? '#000000',\r\n strokeWidth: input.strokeWidth ?? 2,\r\n fillColor: input.fillColor ?? 'none',\r\n };\r\n}\r\n\r\ninterface GridInput extends BaseDefaults {\r\n gridType?: 'square' | 'hex';\r\n hexOrientation?: HexOrientation;\r\n cellSize?: number;\r\n strokeColor?: string;\r\n strokeWidth?: number;\r\n opacity?: number;\r\n}\r\n\r\nexport function createGrid(input: GridInput): GridElement {\r\n return {\r\n id: createId('grid'),\r\n type: 'grid',\r\n position: input.position ?? { x: 0, y: 0 },\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n gridType: input.gridType ?? 'square',\r\n hexOrientation: input.hexOrientation ?? 'pointy',\r\n cellSize: input.cellSize ?? 40,\r\n strokeColor: input.strokeColor ?? '#000000',\r\n strokeWidth: input.strokeWidth ?? 1,\r\n opacity: input.opacity ?? 1,\r\n };\r\n}\r\n\r\nexport function createText(input: TextInput): TextElement {\r\n return {\r\n id: createId('text'),\r\n type: 'text',\r\n position: input.position,\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n size: input.size ?? { w: 200, h: 28 },\r\n text: input.text ?? '',\r\n fontSize: input.fontSize ?? 16,\r\n color: input.color ?? '#1a1a1a',\r\n textAlign: input.textAlign ?? 'left',\r\n };\r\n}\r\n","import type { CanvasElement, NoteElement, TextElement, GridElement } from '../elements/types';\r\nimport type { ElementStore } from '../elements/element-store';\r\nimport { ElementRenderer } from '../elements/element-renderer';\r\nimport { getArrowBounds } from '../elements/arrow-geometry';\r\nimport { renderSquareGrid, renderHexGrid } from '../elements/grid-renderer';\r\nimport type { LayerManager } from '../layers/layer-manager';\r\n\r\nexport interface ExportImageOptions {\r\n scale?: number;\r\n padding?: number;\r\n background?: string;\r\n filter?: (element: CanvasElement) => boolean;\r\n}\r\n\r\ninterface Rect {\r\n x: number;\r\n y: number;\r\n w: number;\r\n h: number;\r\n}\r\n\r\nfunction getStrokeBounds(el: CanvasElement): Rect | null {\r\n if (el.type !== 'stroke') return null;\r\n if (el.points.length === 0) return null;\r\n\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n\r\n for (const p of el.points) {\r\n const px = el.position.x + p.x;\r\n const py = el.position.y + p.y;\r\n minX = Math.min(minX, px);\r\n minY = Math.min(minY, py);\r\n maxX = Math.max(maxX, px);\r\n maxY = Math.max(maxY, py);\r\n }\r\n\r\n const pad = el.width / 2;\r\n return {\r\n x: minX - pad,\r\n y: minY - pad,\r\n w: maxX - minX + el.width,\r\n h: maxY - minY + el.width,\r\n };\r\n}\r\n\r\nfunction getElementRect(el: CanvasElement): Rect | null {\r\n switch (el.type) {\r\n case 'stroke':\r\n return getStrokeBounds(el);\r\n case 'arrow': {\r\n const b = getArrowBounds(el.from, el.to, el.bend);\r\n const pad = el.width / 2 + 14;\r\n return { x: b.x - pad, y: b.y - pad, w: b.w + pad * 2, h: b.h + pad * 2 };\r\n }\r\n case 'grid':\r\n return null;\r\n case 'note':\r\n case 'image':\r\n case 'html':\r\n case 'text':\r\n case 'shape':\r\n if ('size' in el) {\r\n return { x: el.position.x, y: el.position.y, w: el.size.w, h: el.size.h };\r\n }\r\n return null;\r\n default:\r\n return null;\r\n }\r\n}\r\n\r\nfunction computeBounds(\r\n elements: CanvasElement[],\r\n padding: number,\r\n): { x: number; y: number; w: number; h: number } | null {\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n let found = false;\r\n\r\n for (const el of elements) {\r\n const rect = getElementRect(el);\r\n if (!rect) continue;\r\n found = true;\r\n minX = Math.min(minX, rect.x);\r\n minY = Math.min(minY, rect.y);\r\n maxX = Math.max(maxX, rect.x + rect.w);\r\n maxY = Math.max(maxY, rect.y + rect.h);\r\n }\r\n\r\n if (!found) return null;\r\n\r\n return {\r\n x: minX - padding,\r\n y: minY - padding,\r\n w: maxX - minX + padding * 2,\r\n h: maxY - minY + padding * 2,\r\n };\r\n}\r\n\r\nfunction renderNoteOnCanvas(ctx: CanvasRenderingContext2D, note: NoteElement): void {\r\n const { x, y } = note.position;\r\n const { w, h } = note.size;\r\n const r = 4;\r\n const pad = 8;\r\n\r\n ctx.save();\r\n ctx.fillStyle = note.backgroundColor;\r\n ctx.beginPath();\r\n ctx.moveTo(x + r, y);\r\n ctx.lineTo(x + w - r, y);\r\n ctx.arcTo(x + w, y, x + w, y + r, r);\r\n ctx.lineTo(x + w, y + h - r);\r\n ctx.arcTo(x + w, y + h, x + w - r, y + h, r);\r\n ctx.lineTo(x + r, y + h);\r\n ctx.arcTo(x, y + h, x, y + h - r, r);\r\n ctx.lineTo(x, y + r);\r\n ctx.arcTo(x, y, x + r, y, r);\r\n ctx.closePath();\r\n ctx.fill();\r\n\r\n if (note.text) {\r\n ctx.fillStyle = note.textColor;\r\n ctx.font = '14px system-ui, sans-serif';\r\n ctx.textBaseline = 'top';\r\n wrapText(ctx, note.text, x + pad, y + pad, w - pad * 2, 18);\r\n }\r\n\r\n ctx.restore();\r\n}\r\n\r\nfunction renderTextOnCanvas(ctx: CanvasRenderingContext2D, text: TextElement): void {\r\n if (!text.text) return;\r\n\r\n ctx.save();\r\n ctx.fillStyle = text.color;\r\n ctx.font = `${text.fontSize}px system-ui, sans-serif`;\r\n ctx.textBaseline = 'top';\r\n ctx.textAlign = text.textAlign;\r\n\r\n const pad = 2;\r\n let textX = text.position.x + pad;\r\n if (text.textAlign === 'center') {\r\n textX = text.position.x + text.size.w / 2;\r\n } else if (text.textAlign === 'right') {\r\n textX = text.position.x + text.size.w - pad;\r\n }\r\n\r\n const lineHeight = text.fontSize * 1.4;\r\n const lines = text.text.split('\\n');\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n if (line !== undefined) {\r\n ctx.fillText(line, textX, text.position.y + pad + i * lineHeight);\r\n }\r\n }\r\n\r\n ctx.restore();\r\n}\r\n\r\nfunction wrapText(\r\n ctx: CanvasRenderingContext2D,\r\n text: string,\r\n x: number,\r\n y: number,\r\n maxWidth: number,\r\n lineHeight: number,\r\n): void {\r\n const words = text.split(' ');\r\n let line = '';\r\n let offsetY = 0;\r\n\r\n for (const word of words) {\r\n const testLine = line ? `${line} ${word}` : word;\r\n const metrics = ctx.measureText(testLine);\r\n if (metrics.width > maxWidth && line) {\r\n ctx.fillText(line, x, y + offsetY);\r\n line = word;\r\n offsetY += lineHeight;\r\n } else {\r\n line = testLine;\r\n }\r\n }\r\n if (line) {\r\n ctx.fillText(line, x, y + offsetY);\r\n }\r\n}\r\n\r\nfunction renderGridForBounds(\r\n ctx: CanvasRenderingContext2D,\r\n grid: GridElement,\r\n bounds: { x: number; y: number; w: number; h: number },\r\n): void {\r\n const visibleBounds = {\r\n minX: bounds.x,\r\n minY: bounds.y,\r\n maxX: bounds.x + bounds.w,\r\n maxY: bounds.y + bounds.h,\r\n };\r\n\r\n if (grid.gridType === 'hex') {\r\n renderHexGrid(\r\n ctx,\r\n visibleBounds,\r\n grid.cellSize,\r\n grid.hexOrientation,\r\n grid.strokeColor,\r\n grid.strokeWidth,\r\n grid.opacity,\r\n );\r\n } else {\r\n renderSquareGrid(\r\n ctx,\r\n visibleBounds,\r\n grid.cellSize,\r\n grid.strokeColor,\r\n grid.strokeWidth,\r\n grid.opacity,\r\n );\r\n }\r\n}\r\n\r\nfunction loadImages(elements: CanvasElement[]): Promise<Map<string, HTMLImageElement>> {\r\n const imageElements = elements.filter(\r\n (el): el is CanvasElement & { src: string } => el.type === 'image' && 'src' in el,\r\n );\r\n\r\n const cache = new Map<string, HTMLImageElement>();\r\n if (imageElements.length === 0) return Promise.resolve(cache);\r\n\r\n return new Promise((resolve) => {\r\n let remaining = imageElements.length;\r\n const done = () => {\r\n remaining--;\r\n if (remaining <= 0) resolve(cache);\r\n };\r\n\r\n for (const el of imageElements) {\r\n const img = new Image();\r\n img.crossOrigin = 'anonymous';\r\n img.onload = () => {\r\n cache.set(el.id, img);\r\n done();\r\n };\r\n img.onerror = done;\r\n img.src = el.src;\r\n }\r\n });\r\n}\r\n\r\nexport async function exportImage(\r\n store: ElementStore,\r\n options: ExportImageOptions = {},\r\n layerManager?: LayerManager,\r\n): Promise<Blob | null> {\r\n const scale = options.scale ?? 2;\r\n const padding = options.padding ?? 0;\r\n const background = options.background ?? '#ffffff';\r\n const filter = options.filter;\r\n\r\n const allElements = store.getAll();\r\n let visibleElements = layerManager\r\n ? allElements.filter((el) => layerManager.isLayerVisible(el.layerId))\r\n : allElements;\r\n\r\n if (filter) {\r\n visibleElements = visibleElements.filter(filter);\r\n }\r\n\r\n const bounds = computeBounds(visibleElements, padding);\r\n if (!bounds) return null;\r\n\r\n const imageCache = await loadImages(visibleElements);\r\n\r\n const canvas = document.createElement('canvas');\r\n canvas.width = Math.ceil(bounds.w * scale);\r\n canvas.height = Math.ceil(bounds.h * scale);\r\n\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return null;\r\n\r\n ctx.scale(scale, scale);\r\n ctx.translate(-bounds.x, -bounds.y);\r\n\r\n ctx.fillStyle = background;\r\n ctx.fillRect(bounds.x, bounds.y, bounds.w, bounds.h);\r\n\r\n const renderer = new ElementRenderer();\r\n renderer.setStore(store);\r\n\r\n const grids: GridElement[] = [];\r\n\r\n for (const el of visibleElements) {\r\n if (el.type === 'grid') {\r\n grids.push(el);\r\n continue;\r\n }\r\n\r\n if (el.type === 'note') {\r\n renderNoteOnCanvas(ctx, el);\r\n continue;\r\n }\r\n\r\n if (el.type === 'text') {\r\n renderTextOnCanvas(ctx, el);\r\n continue;\r\n }\r\n\r\n if (el.type === 'html') {\r\n continue;\r\n }\r\n\r\n if (el.type === 'image') {\r\n const img = imageCache.get(el.id);\r\n if (img) {\r\n ctx.drawImage(img, el.position.x, el.position.y, el.size.w, el.size.h);\r\n }\r\n continue;\r\n }\r\n\r\n renderer.renderCanvasElement(ctx, el);\r\n }\r\n\r\n for (const grid of grids) {\r\n renderGridForBounds(ctx, grid, bounds);\r\n }\r\n\r\n return new Promise((resolve) => {\r\n canvas.toBlob((blob) => resolve(blob), 'image/png');\r\n });\r\n}\r\n\r\nexport { computeBounds, getElementRect };\r\n","import { EventBus } from '../core/event-bus';\r\nimport type { ElementStore } from '../elements/element-store';\r\nimport type { Layer } from './types';\r\nimport { createId } from '../elements/create-id';\r\n\r\ninterface LayerManagerEvents {\r\n change: null;\r\n}\r\n\r\nexport class LayerManager {\r\n private layers = new Map<string, Layer>();\r\n private _activeLayerId: string;\r\n private bus = new EventBus<LayerManagerEvents>();\r\n\r\n constructor(private readonly store: ElementStore) {\r\n const defaultLayer: Layer = {\r\n id: createId('layer'),\r\n name: 'Layer 1',\r\n visible: true,\r\n locked: false,\r\n order: 0,\r\n opacity: 1.0,\r\n };\r\n this.layers.set(defaultLayer.id, defaultLayer);\r\n this._activeLayerId = defaultLayer.id;\r\n this.syncLayerOrder();\r\n }\r\n\r\n get activeLayer(): Layer {\r\n const layer = this.layers.get(this._activeLayerId);\r\n if (!layer) throw new Error('Active layer not found');\r\n return { ...layer };\r\n }\r\n\r\n get activeLayerId(): string {\r\n return this._activeLayerId;\r\n }\r\n\r\n getLayers(): Layer[] {\r\n return [...this.layers.values()].sort((a, b) => a.order - b.order).map((l) => ({ ...l }));\r\n }\r\n\r\n getLayer(id: string): Layer | undefined {\r\n const layer = this.layers.get(id);\r\n return layer ? { ...layer } : undefined;\r\n }\r\n\r\n isLayerVisible(id: string): boolean {\r\n return this.layers.get(id)?.visible ?? true;\r\n }\r\n\r\n isLayerLocked(id: string): boolean {\r\n return this.layers.get(id)?.locked ?? false;\r\n }\r\n\r\n createLayer(name?: string): Layer {\r\n const maxOrder = Math.max(...[...this.layers.values()].map((l) => l.order), -1);\r\n const autoName = name ?? `Layer ${this.layers.size + 1}`;\r\n const layer: Layer = {\r\n id: createId('layer'),\r\n name: autoName,\r\n visible: true,\r\n locked: false,\r\n order: maxOrder + 1,\r\n opacity: 1.0,\r\n };\r\n this.addLayerDirect(layer);\r\n return { ...layer };\r\n }\r\n\r\n removeLayer(id: string): void {\r\n if (this.layers.size <= 1) {\r\n throw new Error('Cannot remove the last layer');\r\n }\r\n if (this._activeLayerId === id) {\r\n const remaining = [...this.layers.values()]\r\n .filter((l) => l.id !== id)\r\n .sort((a, b) => b.order - a.order);\r\n const fallback = remaining[0];\r\n if (fallback) this._activeLayerId = fallback.id;\r\n }\r\n const elements = this.store.getAll().filter((el) => el.layerId === id);\r\n for (const el of elements) {\r\n this.store.update(el.id, { layerId: this._activeLayerId });\r\n }\r\n this.removeLayerDirect(id);\r\n }\r\n\r\n renameLayer(id: string, name: string): void {\r\n this.updateLayerDirect(id, { name });\r\n }\r\n\r\n reorderLayer(id: string, newOrder: number): void {\r\n if (!this.layers.has(id)) return;\r\n this.updateLayerDirect(id, { order: newOrder });\r\n }\r\n\r\n setLayerVisible(id: string, visible: boolean): boolean {\r\n if (!visible && id === this._activeLayerId) {\r\n const fallback = this.findFallbackLayer(id);\r\n if (!fallback) return false;\r\n this._activeLayerId = fallback.id;\r\n }\r\n this.updateLayerDirect(id, { visible });\r\n return true;\r\n }\r\n\r\n setLayerLocked(id: string, locked: boolean): boolean {\r\n if (locked && id === this._activeLayerId) {\r\n const fallback = this.findFallbackLayer(id);\r\n if (!fallback) return false;\r\n this._activeLayerId = fallback.id;\r\n }\r\n this.updateLayerDirect(id, { locked });\r\n return true;\r\n }\r\n\r\n setActiveLayer(id: string): void {\r\n if (!this.layers.has(id)) return;\r\n this._activeLayerId = id;\r\n this.bus.emit('change', null);\r\n }\r\n\r\n moveElementToLayer(elementId: string, layerId: string): void {\r\n if (!this.layers.has(layerId)) return;\r\n this.store.update(elementId, { layerId });\r\n this.bus.emit('change', null);\r\n }\r\n\r\n snapshot(): Layer[] {\r\n return this.getLayers();\r\n }\r\n\r\n loadSnapshot(layers: Layer[]): void {\r\n this.layers.clear();\r\n for (const layer of layers) {\r\n this.layers.set(layer.id, { ...layer });\r\n }\r\n const first = this.getLayers()[0];\r\n if (first) this._activeLayerId = first.id;\r\n this.syncLayerOrder();\r\n this.bus.emit('change', null);\r\n }\r\n\r\n on(event: 'change', callback: () => void): () => void {\r\n return this.bus.on(event, callback);\r\n }\r\n\r\n addLayerDirect(layer: Layer): void {\r\n this.layers.set(layer.id, { ...layer });\r\n this.syncLayerOrder();\r\n this.bus.emit('change', null);\r\n }\r\n\r\n removeLayerDirect(id: string): void {\r\n this.layers.delete(id);\r\n this.syncLayerOrder();\r\n this.bus.emit('change', null);\r\n }\r\n\r\n updateLayerDirect(id: string, props: Omit<Partial<Layer>, 'id'>): void {\r\n const layer = this.layers.get(id);\r\n if (!layer) return;\r\n Object.assign(layer, props);\r\n if ('order' in props) this.syncLayerOrder();\r\n this.bus.emit('change', null);\r\n }\r\n\r\n private syncLayerOrder(): void {\r\n const order = new Map<string, number>();\r\n for (const layer of this.layers.values()) {\r\n order.set(layer.id, layer.order);\r\n }\r\n this.store.setLayerOrder(order);\r\n }\r\n\r\n private findFallbackLayer(excludeId: string): Layer | undefined {\r\n return [...this.layers.values()]\r\n .filter((l) => l.id !== excludeId && l.visible && !l.locked)\r\n .sort((a, b) => b.order - a.order)[0];\r\n }\r\n}\r\n","import { Camera } from './camera';\r\nimport type { CameraOptions } from './camera';\r\nimport { InputHandler } from './input-handler';\r\nimport { Background } from './background';\r\nimport type { BackgroundOptions } from './background';\r\nimport { ElementStore } from '../elements/element-store';\r\nimport { ElementRenderer } from '../elements/element-renderer';\r\nimport { NoteEditor } from '../elements/note-editor';\r\nimport type { CanvasElement, ArrowElement, GridElement } from '../elements/types';\r\nimport { findBoundArrows, getElementBounds, getEdgeIntersection } from '../elements/arrow-binding';\r\nimport { getArrowTangentAngle } from '../elements/arrow-geometry';\r\nimport { ToolManager } from '../tools/tool-manager';\r\nimport type { ToolContext } from '../tools/types';\r\nimport { HistoryStack } from '../history/history-stack';\r\nimport { HistoryRecorder } from '../history/history-recorder';\r\nimport { createImage, createHtmlElement, createGrid } from '../elements/element-factory';\r\nimport { exportState as exportCanvasState, parseState } from '../core/state-serializer';\r\nimport { exportImage } from './export-image';\r\nimport type { ExportImageOptions } from './export-image';\r\nimport type { CanvasState } from '../core/state-serializer';\r\nimport { LayerManager } from '../layers/layer-manager';\r\n\r\nexport interface ViewportOptions {\r\n camera?: CameraOptions;\r\n background?: BackgroundOptions;\r\n}\r\n\r\nexport class Viewport {\r\n readonly camera: Camera;\r\n readonly store: ElementStore;\r\n readonly layerManager: LayerManager;\r\n readonly toolManager: ToolManager;\r\n readonly history: HistoryStack;\r\n readonly domLayer: HTMLDivElement;\r\n private readonly canvasEl: HTMLCanvasElement;\r\n private readonly wrapper: HTMLDivElement;\r\n private readonly unsubCamera: () => void;\r\n private readonly unsubStore: (() => void)[];\r\n private readonly inputHandler: InputHandler;\r\n private readonly background: Background;\r\n private readonly renderer: ElementRenderer;\r\n private readonly noteEditor: NoteEditor;\r\n private readonly historyRecorder: HistoryRecorder;\r\n readonly toolContext: ToolContext;\r\n private resizeObserver: ResizeObserver | null = null;\r\n private animFrameId = 0;\r\n private _snapToGrid = false;\r\n private readonly _gridSize: number;\r\n private needsRender = true;\r\n private domNodes = new Map<string, HTMLDivElement>();\r\n private htmlContent = new Map<string, HTMLElement>();\r\n private interactingElementId: string | null = null;\r\n\r\n constructor(\r\n private readonly container: HTMLElement,\r\n options: ViewportOptions = {},\r\n ) {\r\n this.camera = new Camera(options.camera);\r\n this.background = new Background(options.background);\r\n this._gridSize = options.background?.spacing ?? 24;\r\n this.store = new ElementStore();\r\n this.layerManager = new LayerManager(this.store);\r\n this.toolManager = new ToolManager();\r\n this.renderer = new ElementRenderer();\r\n this.renderer.setStore(this.store);\r\n this.renderer.setCamera(this.camera);\r\n this.renderer.setOnImageLoad(() => this.requestRender());\r\n this.noteEditor = new NoteEditor();\r\n this.noteEditor.setOnStop((id) => this.onTextEditStop(id));\r\n this.history = new HistoryStack();\r\n this.historyRecorder = new HistoryRecorder(this.store, this.history);\r\n\r\n this.wrapper = this.createWrapper();\r\n this.canvasEl = this.createCanvas();\r\n this.domLayer = this.createDomLayer();\r\n\r\n this.wrapper.appendChild(this.canvasEl);\r\n this.wrapper.appendChild(this.domLayer);\r\n this.container.appendChild(this.wrapper);\r\n\r\n this.toolContext = {\r\n camera: this.camera,\r\n store: this.store,\r\n requestRender: () => this.requestRender(),\r\n switchTool: (name: string) => this.toolManager.setTool(name, this.toolContext),\r\n editElement: (id: string) => this.startEditingElement(id),\r\n setCursor: (cursor: string) => {\r\n this.wrapper.style.cursor = cursor;\r\n },\r\n snapToGrid: false,\r\n gridSize: this._gridSize,\r\n activeLayerId: this.layerManager.activeLayerId,\r\n isLayerVisible: (id: string) => this.layerManager.isLayerVisible(id),\r\n isLayerLocked: (id: string) => this.layerManager.isLayerLocked(id),\r\n };\r\n\r\n this.inputHandler = new InputHandler(this.wrapper, this.camera, {\r\n toolManager: this.toolManager,\r\n toolContext: this.toolContext,\r\n historyRecorder: this.historyRecorder,\r\n historyStack: this.history,\r\n });\r\n\r\n this.unsubCamera = this.camera.onChange(() => {\r\n this.applyCameraTransform();\r\n this.requestRender();\r\n });\r\n\r\n this.unsubStore = [\r\n this.store.on('add', () => this.requestRender()),\r\n this.store.on('remove', (el) => {\r\n this.unbindArrowsFrom(el);\r\n this.removeDomNode(el.id);\r\n }),\r\n this.store.on('update', () => this.requestRender()),\r\n this.store.on('clear', () => this.clearDomNodes()),\r\n ];\r\n\r\n this.layerManager.on('change', () => {\r\n this.toolContext.activeLayerId = this.layerManager.activeLayerId;\r\n this.requestRender();\r\n });\r\n\r\n this.wrapper.addEventListener('dblclick', this.onDblClick);\r\n this.wrapper.addEventListener('dragover', this.onDragOver);\r\n this.wrapper.addEventListener('drop', this.onDrop);\r\n this.observeResize();\r\n this.syncCanvasSize();\r\n this.startRenderLoop();\r\n }\r\n\r\n get ctx(): CanvasRenderingContext2D | null {\r\n return this.canvasEl.getContext('2d');\r\n }\r\n\r\n get snapToGrid(): boolean {\r\n return this._snapToGrid;\r\n }\r\n\r\n setSnapToGrid(enabled: boolean): void {\r\n this._snapToGrid = enabled;\r\n this.toolContext.snapToGrid = enabled;\r\n }\r\n\r\n requestRender(): void {\r\n this.needsRender = true;\r\n }\r\n\r\n exportState(): CanvasState {\r\n return exportCanvasState(this.store.snapshot(), this.camera, this.layerManager.snapshot());\r\n }\r\n\r\n exportJSON(): string {\r\n return JSON.stringify(this.exportState());\r\n }\r\n\r\n async exportImage(options?: ExportImageOptions): Promise<Blob | null> {\r\n return exportImage(this.store, options, this.layerManager);\r\n }\r\n\r\n loadState(state: CanvasState): void {\r\n this.historyRecorder.pause();\r\n this.noteEditor.destroy(this.store);\r\n this.clearDomNodes();\r\n this.store.loadSnapshot(state.elements);\r\n if (state.layers && state.layers.length > 0) {\r\n this.layerManager.loadSnapshot(state.layers);\r\n }\r\n this.reattachHtmlContent();\r\n this.history.clear();\r\n this.historyRecorder.resume();\r\n this.camera.moveTo(state.camera.position.x, state.camera.position.y);\r\n this.camera.setZoom(state.camera.zoom);\r\n }\r\n\r\n loadJSON(json: string): void {\r\n this.loadState(parseState(json));\r\n }\r\n\r\n undo(): boolean {\r\n this.historyRecorder.pause();\r\n const result = this.history.undo(this.store);\r\n this.historyRecorder.resume();\r\n if (result) this.requestRender();\r\n return result;\r\n }\r\n\r\n redo(): boolean {\r\n this.historyRecorder.pause();\r\n const result = this.history.redo(this.store);\r\n this.historyRecorder.resume();\r\n if (result) this.requestRender();\r\n return result;\r\n }\r\n\r\n addImage(src: string, position: { x: number; y: number }, size = { w: 300, h: 200 }): string {\r\n const image = createImage({ position, size, src, layerId: this.layerManager.activeLayerId });\r\n this.historyRecorder.begin();\r\n this.store.add(image);\r\n this.historyRecorder.commit();\r\n this.requestRender();\r\n return image.id;\r\n }\r\n\r\n addHtmlElement(\r\n dom: HTMLElement,\r\n position: { x: number; y: number },\r\n size = { w: 200, h: 150 },\r\n ): string {\r\n const domId = dom.id || undefined;\r\n const el = createHtmlElement({\r\n position,\r\n size,\r\n domId,\r\n layerId: this.layerManager.activeLayerId,\r\n });\r\n this.htmlContent.set(el.id, dom);\r\n this.historyRecorder.begin();\r\n this.store.add(el);\r\n this.historyRecorder.commit();\r\n this.requestRender();\r\n return el.id;\r\n }\r\n\r\n addGrid(input: {\r\n gridType?: 'square' | 'hex';\r\n hexOrientation?: 'pointy' | 'flat';\r\n cellSize?: number;\r\n strokeColor?: string;\r\n strokeWidth?: number;\r\n opacity?: number;\r\n }): string {\r\n const existing = this.store.getElementsByType('grid')[0];\r\n this.historyRecorder.begin();\r\n if (existing) {\r\n this.store.remove(existing.id);\r\n }\r\n const grid = createGrid({ ...input, layerId: this.layerManager.activeLayerId });\r\n this.store.add(grid);\r\n this.historyRecorder.commit();\r\n this.requestRender();\r\n return grid.id;\r\n }\r\n\r\n updateGrid(\r\n updates: Partial<\r\n Pick<\r\n GridElement,\r\n 'gridType' | 'hexOrientation' | 'cellSize' | 'strokeColor' | 'strokeWidth' | 'opacity'\r\n >\r\n >,\r\n ): void {\r\n const grid = this.store.getElementsByType('grid')[0];\r\n if (!grid) return;\r\n this.historyRecorder.begin();\r\n this.store.update(grid.id, updates);\r\n this.historyRecorder.commit();\r\n this.requestRender();\r\n }\r\n\r\n removeGrid(): void {\r\n const grid = this.store.getElementsByType('grid')[0];\r\n if (!grid) return;\r\n this.historyRecorder.begin();\r\n this.store.remove(grid.id);\r\n this.historyRecorder.commit();\r\n this.requestRender();\r\n }\r\n\r\n destroy(): void {\r\n cancelAnimationFrame(this.animFrameId);\r\n this.stopInteracting();\r\n this.noteEditor.destroy(this.store);\r\n this.historyRecorder.destroy();\r\n this.wrapper.removeEventListener('dblclick', this.onDblClick);\r\n this.wrapper.removeEventListener('dragover', this.onDragOver);\r\n this.wrapper.removeEventListener('drop', this.onDrop);\r\n this.inputHandler.destroy();\r\n this.unsubCamera();\r\n this.unsubStore.forEach((fn) => fn());\r\n this.resizeObserver?.disconnect();\r\n this.resizeObserver = null;\r\n this.wrapper.remove();\r\n }\r\n\r\n private startRenderLoop(): void {\r\n const loop = (): void => {\r\n if (this.needsRender) {\r\n this.render();\r\n this.needsRender = false;\r\n }\r\n this.animFrameId = requestAnimationFrame(loop);\r\n };\r\n this.animFrameId = requestAnimationFrame(loop);\r\n }\r\n\r\n private render(): void {\r\n const ctx = this.ctx;\r\n if (!ctx) return;\r\n\r\n const dpr = typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;\r\n ctx.save();\r\n ctx.scale(dpr, dpr);\r\n\r\n this.renderer.setCanvasSize(this.canvasEl.clientWidth, this.canvasEl.clientHeight);\r\n this.background.render(ctx, this.camera);\r\n\r\n ctx.save();\r\n ctx.translate(this.camera.position.x, this.camera.position.y);\r\n ctx.scale(this.camera.zoom, this.camera.zoom);\r\n\r\n const allElements = this.store.getAll();\r\n let domZIndex = 0;\r\n for (const element of allElements) {\r\n if (!this.layerManager.isLayerVisible(element.layerId)) {\r\n if (this.renderer.isDomElement(element)) {\r\n this.hideDomNode(element.id);\r\n }\r\n continue;\r\n }\r\n if (this.renderer.isDomElement(element)) {\r\n this.syncDomNode(element, domZIndex++);\r\n } else {\r\n this.renderer.renderCanvasElement(ctx, element);\r\n }\r\n }\r\n\r\n const activeTool = this.toolManager.activeTool;\r\n if (activeTool?.renderOverlay) {\r\n activeTool.renderOverlay(ctx);\r\n }\r\n\r\n ctx.restore();\r\n ctx.restore();\r\n }\r\n\r\n private startEditingElement(id: string): void {\r\n const element = this.store.getById(id);\r\n if (!element || (element.type !== 'note' && element.type !== 'text')) return;\r\n\r\n this.render();\r\n\r\n const node = this.domNodes.get(id);\r\n if (node) {\r\n this.noteEditor.startEditing(node, id, this.store);\r\n }\r\n }\r\n\r\n private onTextEditStop(elementId: string): void {\r\n const element = this.store.getById(elementId);\r\n if (!element || element.type !== 'text') return;\r\n\r\n if (!element.text || element.text.trim() === '') {\r\n this.historyRecorder.begin();\r\n this.store.remove(elementId);\r\n this.historyRecorder.commit();\r\n return;\r\n }\r\n\r\n const node = this.domNodes.get(elementId);\r\n if (node && 'size' in element) {\r\n const measuredHeight = node.scrollHeight;\r\n if (measuredHeight !== element.size.h) {\r\n this.store.update(elementId, {\r\n size: { w: element.size.w, h: measuredHeight },\r\n });\r\n }\r\n }\r\n }\r\n\r\n private onDblClick = (e: MouseEvent): void => {\r\n const el = document.elementFromPoint(e.clientX, e.clientY);\r\n\r\n const nodeEl = (el as HTMLElement | null)?.closest<HTMLDivElement>('[data-element-id]');\r\n if (nodeEl) {\r\n const elementId = nodeEl.dataset['elementId'];\r\n if (elementId) {\r\n const element = this.store.getById(elementId);\r\n if (element?.type === 'note' || element?.type === 'text') {\r\n this.startEditingElement(elementId);\r\n return;\r\n }\r\n }\r\n }\r\n\r\n const rect = this.wrapper.getBoundingClientRect();\r\n const screen = { x: e.clientX - rect.left, y: e.clientY - rect.top };\r\n const world = this.camera.screenToWorld(screen);\r\n const hit = this.hitTestWorld(world);\r\n if (hit?.type === 'html') {\r\n this.startInteracting(hit.id);\r\n }\r\n };\r\n\r\n private hitTestWorld(world: { x: number; y: number }): CanvasElement | null {\r\n const elements = this.store.getAll().reverse();\r\n for (const el of elements) {\r\n if (!('size' in el)) continue;\r\n const { x, y } = el.position;\r\n const { w, h } = el.size;\r\n if (world.x >= x && world.x <= x + w && world.y >= y && world.y <= y + h) {\r\n return el;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n private startInteracting(id: string): void {\r\n this.stopInteracting();\r\n const node = this.domNodes.get(id);\r\n if (!node) return;\r\n\r\n this.interactingElementId = id;\r\n node.style.pointerEvents = 'auto';\r\n node.addEventListener('pointerdown', this.onInteractNodePointerDown);\r\n\r\n window.addEventListener('keydown', this.onInteractKeyDown);\r\n window.addEventListener('pointerdown', this.onInteractPointerDown);\r\n }\r\n\r\n stopInteracting(): void {\r\n if (!this.interactingElementId) return;\r\n\r\n const node = this.domNodes.get(this.interactingElementId);\r\n if (node) {\r\n node.style.pointerEvents = 'none';\r\n node.removeEventListener('pointerdown', this.onInteractNodePointerDown);\r\n }\r\n\r\n this.interactingElementId = null;\r\n window.removeEventListener('keydown', this.onInteractKeyDown);\r\n window.removeEventListener('pointerdown', this.onInteractPointerDown);\r\n }\r\n\r\n private onInteractNodePointerDown = (e: PointerEvent): void => {\r\n e.stopPropagation();\r\n };\r\n\r\n private onInteractKeyDown = (e: KeyboardEvent): void => {\r\n if (e.key === 'Escape') {\r\n this.stopInteracting();\r\n }\r\n };\r\n\r\n private onInteractPointerDown = (e: PointerEvent): void => {\r\n if (!this.interactingElementId) return;\r\n const target = e.target as HTMLElement | null;\r\n if (!target) return;\r\n\r\n const node = this.domNodes.get(this.interactingElementId);\r\n if (node && !node.contains(target)) {\r\n this.stopInteracting();\r\n }\r\n };\r\n\r\n private onDragOver = (e: DragEvent): void => {\r\n e.preventDefault();\r\n };\r\n\r\n private onDrop = (e: DragEvent): void => {\r\n e.preventDefault();\r\n const files = e.dataTransfer?.files;\r\n if (!files) return;\r\n\r\n const rect = this.wrapper.getBoundingClientRect();\r\n\r\n for (const file of files) {\r\n if (!file.type.startsWith('image/')) continue;\r\n\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n const src = reader.result;\r\n if (typeof src !== 'string') return;\r\n\r\n const screenPos = { x: e.clientX - rect.left, y: e.clientY - rect.top };\r\n const worldPos = this.camera.screenToWorld(screenPos);\r\n this.addImage(src, worldPos);\r\n };\r\n reader.readAsDataURL(file);\r\n }\r\n };\r\n\r\n private syncDomNode(element: CanvasElement, zIndex = 0): void {\r\n let node = this.domNodes.get(element.id);\r\n if (!node) {\r\n node = document.createElement('div');\r\n node.dataset['elementId'] = element.id;\r\n Object.assign(node.style, {\r\n position: 'absolute',\r\n pointerEvents: 'auto',\r\n });\r\n this.domLayer.appendChild(node);\r\n this.domNodes.set(element.id, node);\r\n }\r\n\r\n const size = 'size' in element ? element.size : null;\r\n Object.assign(node.style, {\r\n display: 'block',\r\n left: `${element.position.x}px`,\r\n top: `${element.position.y}px`,\r\n width: size ? `${size.w}px` : 'auto',\r\n height: size ? `${size.h}px` : 'auto',\r\n zIndex: String(zIndex),\r\n });\r\n\r\n this.renderDomContent(node, element);\r\n }\r\n\r\n private renderDomContent(node: HTMLDivElement, element: CanvasElement): void {\r\n if (element.type === 'note') {\r\n if (!node.dataset['initialized']) {\r\n node.dataset['initialized'] = 'true';\r\n Object.assign(node.style, {\r\n backgroundColor: element.backgroundColor,\r\n color: element.textColor,\r\n padding: '8px',\r\n borderRadius: '4px',\r\n boxShadow: '0 2px 8px rgba(0,0,0,0.15)',\r\n fontSize: '14px',\r\n overflow: 'hidden',\r\n cursor: 'default',\r\n userSelect: 'none',\r\n wordWrap: 'break-word',\r\n });\r\n node.textContent = element.text || '';\r\n\r\n node.addEventListener('dblclick', (e) => {\r\n e.stopPropagation();\r\n const id = node.dataset['elementId'];\r\n if (id) this.startEditingElement(id);\r\n });\r\n }\r\n\r\n if (!this.noteEditor.isEditing || this.noteEditor.editingElementId !== element.id) {\r\n if (node.textContent !== element.text) {\r\n node.textContent = element.text || '';\r\n }\r\n node.style.backgroundColor = element.backgroundColor;\r\n node.style.color = element.textColor;\r\n }\r\n }\r\n\r\n if (element.type === 'html' && !node.dataset['initialized']) {\r\n const content = this.htmlContent.get(element.id);\r\n if (content) {\r\n node.dataset['initialized'] = 'true';\r\n Object.assign(node.style, {\r\n overflow: 'hidden',\r\n pointerEvents: 'none',\r\n });\r\n node.appendChild(content);\r\n }\r\n }\r\n\r\n if (element.type === 'text') {\r\n if (!node.dataset['initialized']) {\r\n node.dataset['initialized'] = 'true';\r\n Object.assign(node.style, {\r\n padding: '2px',\r\n fontSize: `${element.fontSize}px`,\r\n color: element.color,\r\n textAlign: element.textAlign,\r\n background: 'none',\r\n border: 'none',\r\n boxShadow: 'none',\r\n overflow: 'visible',\r\n cursor: 'default',\r\n userSelect: 'none',\r\n wordWrap: 'break-word',\r\n whiteSpace: 'pre-wrap',\r\n lineHeight: '1.4',\r\n });\r\n node.textContent = element.text || '';\r\n\r\n node.addEventListener('dblclick', (e) => {\r\n e.stopPropagation();\r\n const id = node.dataset['elementId'];\r\n if (id) this.startEditingElement(id);\r\n });\r\n }\r\n\r\n if (!this.noteEditor.isEditing || this.noteEditor.editingElementId !== element.id) {\r\n if (node.textContent !== element.text) {\r\n node.textContent = element.text || '';\r\n }\r\n Object.assign(node.style, {\r\n fontSize: `${element.fontSize}px`,\r\n color: element.color,\r\n textAlign: element.textAlign,\r\n });\r\n }\r\n }\r\n }\r\n\r\n private unbindArrowsFrom(removedElement: CanvasElement): void {\r\n const boundArrows = findBoundArrows(removedElement.id, this.store);\r\n const bounds = getElementBounds(removedElement);\r\n\r\n for (const arrow of boundArrows) {\r\n const updates: Partial<ArrowElement> = {};\r\n\r\n if (arrow.fromBinding?.elementId === removedElement.id) {\r\n updates.fromBinding = undefined;\r\n if (bounds) {\r\n const angle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 0);\r\n const rayTarget = {\r\n x: arrow.from.x + Math.cos(angle) * 1000,\r\n y: arrow.from.y + Math.sin(angle) * 1000,\r\n };\r\n const edge = getEdgeIntersection(bounds, rayTarget);\r\n updates.from = edge;\r\n updates.position = edge;\r\n }\r\n }\r\n\r\n if (arrow.toBinding?.elementId === removedElement.id) {\r\n updates.toBinding = undefined;\r\n if (bounds) {\r\n const angle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 1);\r\n const rayTarget = {\r\n x: arrow.to.x - Math.cos(angle) * 1000,\r\n y: arrow.to.y - Math.sin(angle) * 1000,\r\n };\r\n updates.to = getEdgeIntersection(bounds, rayTarget);\r\n }\r\n }\r\n\r\n if (Object.keys(updates).length > 0) {\r\n this.store.update(arrow.id, updates);\r\n }\r\n }\r\n }\r\n\r\n private hideDomNode(id: string): void {\r\n const node = this.domNodes.get(id);\r\n if (node) node.style.display = 'none';\r\n }\r\n\r\n private removeDomNode(id: string): void {\r\n this.htmlContent.delete(id);\r\n const node = this.domNodes.get(id);\r\n if (node) {\r\n node.remove();\r\n this.domNodes.delete(id);\r\n }\r\n this.requestRender();\r\n }\r\n\r\n private clearDomNodes(): void {\r\n this.domNodes.forEach((node) => node.remove());\r\n this.domNodes.clear();\r\n this.htmlContent.clear();\r\n this.requestRender();\r\n }\r\n\r\n private reattachHtmlContent(): void {\r\n for (const el of this.store.getElementsByType('html')) {\r\n if (el.domId) {\r\n const dom = document.getElementById(el.domId);\r\n if (dom) {\r\n this.htmlContent.set(el.id, dom);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private createWrapper(): HTMLDivElement {\r\n const el = document.createElement('div');\r\n Object.assign(el.style, {\r\n position: 'relative',\r\n width: '100%',\r\n height: '100%',\r\n overflow: 'hidden',\r\n });\r\n return el;\r\n }\r\n\r\n private createCanvas(): HTMLCanvasElement {\r\n const el = document.createElement('canvas');\r\n Object.assign(el.style, {\r\n position: 'absolute',\r\n top: '0',\r\n left: '0',\r\n width: '100%',\r\n height: '100%',\r\n });\r\n return el;\r\n }\r\n\r\n private createDomLayer(): HTMLDivElement {\r\n const el = document.createElement('div');\r\n Object.assign(el.style, {\r\n position: 'absolute',\r\n top: '0',\r\n left: '0',\r\n width: '100%',\r\n height: '100%',\r\n pointerEvents: 'none',\r\n transformOrigin: '0 0',\r\n });\r\n return el;\r\n }\r\n\r\n private applyCameraTransform(): void {\r\n this.domLayer.style.transform = this.camera.toCSSTransform();\r\n }\r\n\r\n private syncCanvasSize(): void {\r\n const rect = this.container.getBoundingClientRect();\r\n const dpr = typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;\r\n this.canvasEl.width = rect.width * dpr;\r\n this.canvasEl.height = rect.height * dpr;\r\n this.requestRender();\r\n }\r\n\r\n private observeResize(): void {\r\n if (typeof ResizeObserver === 'undefined') return;\r\n this.resizeObserver = new ResizeObserver(() => this.syncCanvasSize());\r\n this.resizeObserver.observe(this.container);\r\n }\r\n}\r\n","import type { Tool, ToolContext, PointerState } from './types';\n\nexport class HandTool implements Tool {\n readonly name = 'hand';\n private panning = false;\n private lastScreen = { x: 0, y: 0 };\n\n onActivate(ctx: ToolContext): void {\n ctx.setCursor?.('grab');\n }\n\n onDeactivate(ctx: ToolContext): void {\n ctx.setCursor?.('default');\n }\n\n onPointerDown(state: PointerState, ctx: ToolContext): void {\n this.panning = true;\n this.lastScreen = { x: state.x, y: state.y };\n ctx.setCursor?.('grabbing');\n }\n\n onPointerMove(state: PointerState, ctx: ToolContext): void {\n if (!this.panning) return;\n const dx = state.x - this.lastScreen.x;\n const dy = state.y - this.lastScreen.y;\n this.lastScreen = { x: state.x, y: state.y };\n ctx.camera.pan(dx, dy);\n }\n\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\n this.panning = false;\n ctx.setCursor?.('grab');\n }\n}\n","import type { StrokePoint } from '../core/types';\r\nimport type { Tool, ToolContext, PointerState } from './types';\r\nimport { createStroke } from '../elements/element-factory';\r\nimport { simplifyPoints, smoothToSegments, pressureToWidth } from '../elements/stroke-smoothing';\r\n\r\nexport interface PencilToolOptions {\r\n color?: string;\r\n width?: number;\r\n smoothing?: number;\r\n}\r\n\r\nconst MIN_POINTS_FOR_STROKE = 2;\r\nconst DEFAULT_SMOOTHING = 1.5;\r\nconst DEFAULT_PRESSURE = 0.5;\r\n\r\nexport class PencilTool implements Tool {\r\n readonly name = 'pencil';\r\n private drawing = false;\r\n private points: StrokePoint[] = [];\r\n private color: string;\r\n private width: number;\r\n private smoothing: number;\r\n\r\n constructor(options: PencilToolOptions = {}) {\r\n this.color = options.color ?? '#000000';\r\n this.width = options.width ?? 2;\r\n this.smoothing = options.smoothing ?? DEFAULT_SMOOTHING;\r\n }\r\n\r\n onActivate(ctx: ToolContext): void {\r\n ctx.setCursor?.('crosshair');\r\n }\r\n\r\n onDeactivate(ctx: ToolContext): void {\r\n ctx.setCursor?.('default');\r\n }\r\n\r\n setOptions(options: PencilToolOptions): void {\r\n if (options.color !== undefined) this.color = options.color;\r\n if (options.width !== undefined) this.width = options.width;\r\n if (options.smoothing !== undefined) this.smoothing = options.smoothing;\r\n }\r\n\r\n onPointerDown(state: PointerState, ctx: ToolContext): void {\r\n this.drawing = true;\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n const pressure = state.pressure === 0 ? DEFAULT_PRESSURE : state.pressure;\r\n this.points = [{ x: world.x, y: world.y, pressure }];\r\n }\r\n\r\n onPointerMove(state: PointerState, ctx: ToolContext): void {\r\n if (!this.drawing) return;\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n const pressure = state.pressure === 0 ? DEFAULT_PRESSURE : state.pressure;\r\n this.points.push({ x: world.x, y: world.y, pressure });\r\n ctx.requestRender();\r\n }\r\n\r\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\r\n if (!this.drawing) return;\r\n this.drawing = false;\r\n\r\n if (this.points.length < MIN_POINTS_FOR_STROKE) {\r\n this.points = [];\r\n return;\r\n }\r\n\r\n const simplified = simplifyPoints(this.points, this.smoothing);\r\n const stroke = createStroke({\r\n points: simplified,\r\n color: this.color,\r\n width: this.width,\r\n layerId: ctx.activeLayerId ?? '',\r\n });\r\n ctx.store.add(stroke);\r\n this.points = [];\r\n ctx.requestRender();\r\n }\r\n\r\n renderOverlay(ctx: CanvasRenderingContext2D): void {\r\n if (!this.drawing || this.points.length < 2) return;\r\n\r\n ctx.save();\r\n ctx.strokeStyle = this.color;\r\n ctx.lineCap = 'round';\r\n ctx.lineJoin = 'round';\r\n ctx.globalAlpha = 0.8;\r\n\r\n const segments = smoothToSegments(this.points);\r\n for (const seg of segments) {\r\n const w =\r\n (pressureToWidth(seg.start.pressure, this.width) +\r\n pressureToWidth(seg.end.pressure, this.width)) /\r\n 2;\r\n ctx.lineWidth = w;\r\n ctx.beginPath();\r\n ctx.moveTo(seg.start.x, seg.start.y);\r\n ctx.bezierCurveTo(seg.cp1.x, seg.cp1.y, seg.cp2.x, seg.cp2.y, seg.end.x, seg.end.y);\r\n ctx.stroke();\r\n }\r\n\r\n ctx.restore();\r\n }\r\n}\r\n","import type { Point } from '../core/types';\r\nimport type { Tool, ToolContext, PointerState } from './types';\r\nimport type { StrokeElement } from '../elements/types';\r\n\r\nexport interface EraserToolOptions {\r\n radius?: number;\r\n}\r\n\r\nconst DEFAULT_RADIUS = 20;\r\n\r\nfunction makeEraserCursor(radius: number): string {\r\n const size = radius * 2;\r\n const svg = `<svg xmlns='http://www.w3.org/2000/svg' width='${size}' height='${size}'><circle cx='${radius}' cy='${radius}' r='${radius - 1}' fill='none' stroke='%23666' stroke-width='1.5'/></svg>`;\r\n return `url(\"data:image/svg+xml,${svg}\") ${radius} ${radius}, crosshair`;\r\n}\r\n\r\nexport class EraserTool implements Tool {\r\n readonly name = 'eraser';\r\n private erasing = false;\r\n private readonly radius: number;\r\n private readonly cursor: string;\r\n\r\n constructor(options: EraserToolOptions = {}) {\r\n this.radius = options.radius ?? DEFAULT_RADIUS;\r\n this.cursor = makeEraserCursor(this.radius);\r\n }\r\n\r\n onActivate(ctx: ToolContext): void {\r\n ctx.setCursor?.(this.cursor);\r\n }\r\n\r\n onDeactivate(ctx: ToolContext): void {\r\n ctx.setCursor?.('default');\r\n }\r\n\r\n onPointerDown(state: PointerState, ctx: ToolContext): void {\r\n this.erasing = true;\r\n this.eraseAt(state, ctx);\r\n }\r\n\r\n onPointerMove(state: PointerState, ctx: ToolContext): void {\r\n if (!this.erasing) return;\r\n this.eraseAt(state, ctx);\r\n }\r\n\r\n onPointerUp(_state: PointerState, _ctx: ToolContext): void {\r\n this.erasing = false;\r\n }\r\n\r\n private eraseAt(state: PointerState, ctx: ToolContext): void {\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n const strokes = ctx.store.getElementsByType('stroke');\r\n let erased = false;\r\n\r\n for (const stroke of strokes) {\r\n if (ctx.isLayerVisible && !ctx.isLayerVisible(stroke.layerId)) continue;\r\n if (ctx.isLayerLocked && ctx.isLayerLocked(stroke.layerId)) continue;\r\n if (this.strokeIntersects(stroke, world)) {\r\n ctx.store.remove(stroke.id);\r\n erased = true;\r\n }\r\n }\r\n\r\n if (erased) ctx.requestRender();\r\n }\r\n\r\n private strokeIntersects(stroke: StrokeElement, point: Point): boolean {\r\n const radiusSq = this.radius * this.radius;\r\n return stroke.points.some((p) => {\r\n const dx = p.x + stroke.position.x - point.x;\r\n const dy = p.y + stroke.position.y - point.y;\r\n return dx * dx + dy * dy <= radiusSq;\r\n });\r\n }\r\n}\r\n","import type { Point } from '../core/types';\r\nimport type { ArrowElement, CanvasElement } from '../elements/types';\r\nimport type { ToolContext } from './types';\r\nimport { getArrowMidpoint, getBendFromPoint } from '../elements/arrow-geometry';\r\nimport { findBindTarget, getElementCenter, getElementBounds } from '../elements/arrow-binding';\r\n\r\nconst BIND_THRESHOLD = 20;\r\n\r\nexport type ArrowHandle = 'start' | 'mid' | 'end';\r\n\r\nconst HANDLE_RADIUS = 5;\r\nconst HANDLE_HIT_PADDING = 4;\r\n\r\nconst ARROW_HANDLE_CURSORS: Record<ArrowHandle, string> = {\r\n start: 'crosshair',\r\n end: 'crosshair',\r\n mid: 'grab',\r\n};\r\n\r\nexport function getArrowHandleCursor(handle: ArrowHandle, active: boolean): string {\r\n if (handle === 'mid' && active) return 'grabbing';\r\n return ARROW_HANDLE_CURSORS[handle];\r\n}\r\n\r\nexport function getArrowHandlePositions(arrow: ArrowElement): [ArrowHandle, Point][] {\r\n const mid = getArrowMidpoint(arrow.from, arrow.to, arrow.bend);\r\n return [\r\n ['start', arrow.from],\r\n ['mid', mid],\r\n ['end', arrow.to],\r\n ];\r\n}\r\n\r\nexport function hitTestArrowHandles(\r\n world: Point,\r\n selectedIds: string[],\r\n ctx: ToolContext,\r\n): { elementId: string; handle: ArrowHandle } | null {\r\n if (selectedIds.length === 0) return null;\r\n\r\n const zoom = ctx.camera.zoom;\r\n const hitRadius = (HANDLE_RADIUS + HANDLE_HIT_PADDING) / zoom;\r\n\r\n for (const id of selectedIds) {\r\n const el = ctx.store.getById(id);\r\n if (!el || el.type !== 'arrow') continue;\r\n\r\n const handles = getArrowHandlePositions(el);\r\n for (const [handle, pos] of handles) {\r\n const dx = world.x - pos.x;\r\n const dy = world.y - pos.y;\r\n if (dx * dx + dy * dy <= hitRadius * hitRadius) {\r\n return { elementId: id, handle };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nexport function applyArrowHandleDrag(\r\n handle: ArrowHandle,\r\n elementId: string,\r\n world: Point,\r\n ctx: ToolContext,\r\n): void {\r\n const el = ctx.store.getById(elementId);\r\n if (!el || el.type !== 'arrow') return;\r\n\r\n const threshold = BIND_THRESHOLD / ctx.camera.zoom;\r\n\r\n const layerFilter = (candidate: CanvasElement) => candidate.layerId === el.layerId;\r\n\r\n switch (handle) {\r\n case 'start': {\r\n const excludeId = el.toBinding?.elementId;\r\n const target = findBindTarget(world, ctx.store, threshold, excludeId, layerFilter);\r\n if (target) {\r\n const center = getElementCenter(target);\r\n ctx.store.update(elementId, {\r\n from: center,\r\n position: center,\r\n fromBinding: { elementId: target.id },\r\n });\r\n } else {\r\n ctx.store.update(elementId, {\r\n from: { x: world.x, y: world.y },\r\n position: { x: world.x, y: world.y },\r\n fromBinding: undefined,\r\n });\r\n }\r\n break;\r\n }\r\n case 'end': {\r\n const excludeId = el.fromBinding?.elementId;\r\n const target = findBindTarget(world, ctx.store, threshold, excludeId, layerFilter);\r\n if (target) {\r\n const center = getElementCenter(target);\r\n ctx.store.update(elementId, {\r\n to: center,\r\n toBinding: { elementId: target.id },\r\n });\r\n } else {\r\n ctx.store.update(elementId, {\r\n to: { x: world.x, y: world.y },\r\n toBinding: undefined,\r\n });\r\n }\r\n break;\r\n }\r\n case 'mid': {\r\n const bend = getBendFromPoint(el.from, el.to, world);\r\n ctx.store.update(elementId, { bend });\r\n break;\r\n }\r\n }\r\n\r\n ctx.requestRender();\r\n}\r\n\r\nexport function getArrowHandleDragTarget(\r\n handle: ArrowHandle,\r\n elementId: string,\r\n world: Point,\r\n ctx: ToolContext,\r\n): { x: number; y: number; w: number; h: number } | null {\r\n if (handle === 'mid') return null;\r\n\r\n const el = ctx.store.getById(elementId);\r\n if (!el || el.type !== 'arrow') return null;\r\n\r\n const threshold = BIND_THRESHOLD / ctx.camera.zoom;\r\n const excludeId = handle === 'start' ? el.toBinding?.elementId : el.fromBinding?.elementId;\r\n const layerFilter = (candidate: CanvasElement) => candidate.layerId === el.layerId;\r\n const target = findBindTarget(world, ctx.store, threshold, excludeId, layerFilter);\r\n if (!target) return null;\r\n\r\n return getElementBounds(target);\r\n}\r\n\r\nexport function renderArrowHandles(\r\n canvasCtx: CanvasRenderingContext2D,\r\n arrow: ArrowElement,\r\n zoom: number,\r\n): void {\r\n const radius = HANDLE_RADIUS / zoom;\r\n const handles = getArrowHandlePositions(arrow);\r\n\r\n canvasCtx.setLineDash([]);\r\n canvasCtx.lineWidth = 1.5 / zoom;\r\n\r\n for (const [handle, pos] of handles) {\r\n canvasCtx.fillStyle = handle === 'mid' ? '#2196F3' : '#ffffff';\r\n canvasCtx.strokeStyle = '#2196F3';\r\n\r\n canvasCtx.beginPath();\r\n canvasCtx.arc(pos.x, pos.y, radius, 0, Math.PI * 2);\r\n canvasCtx.fill();\r\n canvasCtx.stroke();\r\n }\r\n}\r\n","import type { Point } from '../core/types';\r\nimport type { Tool, ToolContext, PointerState } from './types';\r\nimport { snapPoint } from '../core/snap';\r\nimport type { CanvasElement, ArrowElement } from '../elements/types';\r\nimport { isNearBezier, getArrowBounds } from '../elements/arrow-geometry';\r\nimport type { Rect } from '../elements/arrow-geometry';\r\nimport { findBoundArrows, updateBoundArrow, getElementBounds } from '../elements/arrow-binding';\r\nimport {\r\n type ArrowHandle,\r\n hitTestArrowHandles,\r\n applyArrowHandleDrag,\r\n renderArrowHandles,\r\n getArrowHandleCursor,\r\n getArrowHandleDragTarget,\r\n} from './arrow-handles';\r\n\r\ntype HandlePosition = 'nw' | 'ne' | 'sw' | 'se';\r\n\r\nconst HANDLE_SIZE = 8;\r\nconst HANDLE_HIT_PADDING = 4;\r\nconst SELECTION_PAD = 4;\r\nconst MIN_ELEMENT_SIZE = 20;\r\n\r\nconst HANDLE_CURSORS: Record<HandlePosition, string> = {\r\n nw: 'nwse-resize',\r\n se: 'nwse-resize',\r\n ne: 'nesw-resize',\r\n sw: 'nesw-resize',\r\n};\r\n\r\ntype Mode =\r\n | { type: 'idle' }\r\n | { type: 'dragging' }\r\n | { type: 'marquee'; start: Point }\r\n | { type: 'resizing'; elementId: string; handle: HandlePosition }\r\n | { type: 'arrow-handle'; elementId: string; handle: ArrowHandle };\r\n\r\nexport class SelectTool implements Tool {\r\n readonly name = 'select';\r\n private _selectedIds: string[] = [];\r\n private mode: Mode = { type: 'idle' };\r\n private lastWorld: Point = { x: 0, y: 0 };\r\n private currentWorld: Point = { x: 0, y: 0 };\r\n private ctx: ToolContext | null = null;\r\n\r\n get selectedIds(): string[] {\r\n return [...this._selectedIds];\r\n }\r\n\r\n get isMarqueeActive(): boolean {\r\n return this.mode.type === 'marquee';\r\n }\r\n\r\n onActivate(ctx: ToolContext): void {\r\n this.ctx = ctx;\r\n }\r\n\r\n onDeactivate(ctx: ToolContext): void {\r\n this._selectedIds = [];\r\n this.mode = { type: 'idle' };\r\n ctx.setCursor?.('default');\r\n }\r\n\r\n private snap(point: Point, ctx: ToolContext): Point {\r\n return ctx.snapToGrid && ctx.gridSize ? snapPoint(point, ctx.gridSize) : point;\r\n }\r\n\r\n onPointerDown(state: PointerState, ctx: ToolContext): void {\r\n this.ctx = ctx;\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n this.lastWorld = this.snap(world, ctx);\r\n this.currentWorld = world;\r\n\r\n const arrowHit = hitTestArrowHandles(world, this._selectedIds, ctx);\r\n if (arrowHit) {\r\n this.mode = {\r\n type: 'arrow-handle',\r\n elementId: arrowHit.elementId,\r\n handle: arrowHit.handle,\r\n };\r\n ctx.requestRender();\r\n return;\r\n }\r\n\r\n const resizeHit = this.hitTestResizeHandle(world, ctx);\r\n if (resizeHit) {\r\n const el = ctx.store.getById(resizeHit.elementId);\r\n if (el) {\r\n this.mode = {\r\n type: 'resizing',\r\n elementId: resizeHit.elementId,\r\n handle: resizeHit.handle,\r\n };\r\n ctx.requestRender();\r\n return;\r\n }\r\n }\r\n\r\n const hit = this.hitTest(world, ctx);\r\n if (hit) {\r\n const alreadySelected = this._selectedIds.includes(hit.id);\r\n if (!alreadySelected) {\r\n this._selectedIds = [hit.id];\r\n }\r\n this.mode = hit.locked ? { type: 'idle' } : { type: 'dragging' };\r\n } else {\r\n this._selectedIds = [];\r\n this.mode = { type: 'marquee', start: world };\r\n }\r\n\r\n ctx.requestRender();\r\n }\r\n\r\n onPointerMove(state: PointerState, ctx: ToolContext): void {\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n this.currentWorld = world;\r\n\r\n if (this.mode.type === 'arrow-handle') {\r\n ctx.setCursor?.(getArrowHandleCursor(this.mode.handle, true));\r\n applyArrowHandleDrag(this.mode.handle, this.mode.elementId, world, ctx);\r\n return;\r\n }\r\n\r\n if (this.mode.type === 'resizing') {\r\n ctx.setCursor?.(HANDLE_CURSORS[this.mode.handle]);\r\n this.handleResize(world, ctx);\r\n return;\r\n }\r\n\r\n if (this.mode.type === 'dragging' && this._selectedIds.length > 0) {\r\n ctx.setCursor?.('move');\r\n const snapped = this.snap(world, ctx);\r\n const dx = snapped.x - this.lastWorld.x;\r\n const dy = snapped.y - this.lastWorld.y;\r\n this.lastWorld = snapped;\r\n\r\n for (const id of this._selectedIds) {\r\n const el = ctx.store.getById(id);\r\n if (!el || el.locked) continue;\r\n\r\n if (el.type === 'arrow') {\r\n if (el.fromBinding || el.toBinding) {\r\n // Arrow has bindings — don't allow independent dragging.\r\n // Use handle drag to detach individual endpoints.\r\n continue;\r\n }\r\n\r\n ctx.store.update(id, {\r\n position: { x: el.position.x + dx, y: el.position.y + dy },\r\n from: { x: el.from.x + dx, y: el.from.y + dy },\r\n to: { x: el.to.x + dx, y: el.to.y + dy },\r\n });\r\n } else {\r\n ctx.store.update(id, {\r\n position: { x: el.position.x + dx, y: el.position.y + dy },\r\n });\r\n }\r\n }\r\n\r\n // Update any arrows bound to moved elements\r\n const movedNonArrowIds = new Set<string>();\r\n for (const id of this._selectedIds) {\r\n const el = ctx.store.getById(id);\r\n if (el && el.type !== 'arrow') movedNonArrowIds.add(id);\r\n }\r\n\r\n if (movedNonArrowIds.size > 0) {\r\n const updatedArrows = new Set<string>();\r\n for (const id of movedNonArrowIds) {\r\n const boundArrows = findBoundArrows(id, ctx.store);\r\n for (const ba of boundArrows) {\r\n if (updatedArrows.has(ba.id)) continue;\r\n updatedArrows.add(ba.id);\r\n const updates = updateBoundArrow(ba, ctx.store);\r\n if (updates) ctx.store.update(ba.id, updates);\r\n }\r\n }\r\n }\r\n\r\n ctx.requestRender();\r\n return;\r\n }\r\n\r\n if (this.mode.type === 'marquee') {\r\n ctx.setCursor?.('crosshair');\r\n ctx.requestRender();\r\n return;\r\n }\r\n\r\n this.updateHoverCursor(world, ctx);\r\n }\r\n\r\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\r\n if (this.mode.type === 'marquee') {\r\n const rect = this.getMarqueeRect();\r\n if (rect) {\r\n this._selectedIds = this.findElementsInRect(rect, ctx);\r\n }\r\n ctx.requestRender();\r\n }\r\n\r\n this.mode = { type: 'idle' };\r\n ctx.setCursor?.('default');\r\n }\r\n\r\n onHover(state: PointerState, ctx: ToolContext): void {\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n this.updateHoverCursor(world, ctx);\r\n }\r\n\r\n renderOverlay(canvasCtx: CanvasRenderingContext2D): void {\r\n this.renderMarquee(canvasCtx);\r\n this.renderSelectionBoxes(canvasCtx);\r\n\r\n if (this.mode.type === 'arrow-handle' && this.ctx) {\r\n const target = getArrowHandleDragTarget(\r\n this.mode.handle,\r\n this.mode.elementId,\r\n this.currentWorld,\r\n this.ctx,\r\n );\r\n if (target) {\r\n canvasCtx.save();\r\n canvasCtx.strokeStyle = '#2196F3';\r\n canvasCtx.lineWidth = 2 / this.ctx.camera.zoom;\r\n canvasCtx.setLineDash([]);\r\n canvasCtx.strokeRect(target.x, target.y, target.w, target.h);\r\n canvasCtx.restore();\r\n }\r\n }\r\n }\r\n\r\n private updateHoverCursor(world: Point, ctx: ToolContext): void {\r\n const arrowHit = hitTestArrowHandles(world, this._selectedIds, ctx);\r\n if (arrowHit) {\r\n ctx.setCursor?.(getArrowHandleCursor(arrowHit.handle, false));\r\n return;\r\n }\r\n\r\n const resizeHit = this.hitTestResizeHandle(world, ctx);\r\n if (resizeHit) {\r\n ctx.setCursor?.(HANDLE_CURSORS[resizeHit.handle]);\r\n return;\r\n }\r\n\r\n const hit = this.hitTest(world, ctx);\r\n ctx.setCursor?.(hit ? 'move' : 'default');\r\n }\r\n\r\n private handleResize(world: Point, ctx: ToolContext): void {\r\n if (this.mode.type !== 'resizing') return;\r\n\r\n const el = ctx.store.getById(this.mode.elementId);\r\n if (!el || !('size' in el) || el.locked) return;\r\n\r\n const { handle } = this.mode;\r\n const dx = world.x - this.lastWorld.x;\r\n const dy = world.y - this.lastWorld.y;\r\n this.lastWorld = world;\r\n\r\n let { x, y, w, h } = { x: el.position.x, y: el.position.y, w: el.size.w, h: el.size.h };\r\n\r\n switch (handle) {\r\n case 'se':\r\n w += dx;\r\n h += dy;\r\n break;\r\n case 'sw':\r\n x += dx;\r\n w -= dx;\r\n h += dy;\r\n break;\r\n case 'ne':\r\n y += dy;\r\n w += dx;\r\n h -= dy;\r\n break;\r\n case 'nw':\r\n x += dx;\r\n y += dy;\r\n w -= dx;\r\n h -= dy;\r\n break;\r\n }\r\n\r\n if (w < MIN_ELEMENT_SIZE) {\r\n if (handle === 'nw' || handle === 'sw') x = el.position.x + el.size.w - MIN_ELEMENT_SIZE;\r\n w = MIN_ELEMENT_SIZE;\r\n }\r\n if (h < MIN_ELEMENT_SIZE) {\r\n if (handle === 'nw' || handle === 'ne') y = el.position.y + el.size.h - MIN_ELEMENT_SIZE;\r\n h = MIN_ELEMENT_SIZE;\r\n }\r\n\r\n ctx.store.update(this.mode.elementId, {\r\n position: { x, y },\r\n size: { w, h },\r\n });\r\n\r\n // Update arrows bound to the resized element\r\n const boundArrows = findBoundArrows(this.mode.elementId, ctx.store);\r\n for (const ba of boundArrows) {\r\n const updates = updateBoundArrow(ba, ctx.store);\r\n if (updates) ctx.store.update(ba.id, updates);\r\n }\r\n\r\n ctx.requestRender();\r\n }\r\n\r\n private hitTestResizeHandle(\r\n world: Point,\r\n ctx: ToolContext,\r\n ): { elementId: string; handle: HandlePosition } | null {\r\n if (this._selectedIds.length === 0) return null;\r\n\r\n const zoom = ctx.camera.zoom;\r\n const handleHalf = (HANDLE_SIZE / 2 + HANDLE_HIT_PADDING) / zoom;\r\n\r\n for (const id of this._selectedIds) {\r\n const el = ctx.store.getById(id);\r\n if (!el || !('size' in el)) continue;\r\n\r\n const bounds = this.getElementBounds(el);\r\n if (!bounds) continue;\r\n\r\n const corners = this.getHandlePositions(bounds);\r\n for (const [handle, pos] of corners) {\r\n if (Math.abs(world.x - pos.x) <= handleHalf && Math.abs(world.y - pos.y) <= handleHalf) {\r\n return { elementId: id, handle };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private getHandlePositions(bounds: Rect): [HandlePosition, Point][] {\r\n return [\r\n ['nw', { x: bounds.x, y: bounds.y }],\r\n ['ne', { x: bounds.x + bounds.w, y: bounds.y }],\r\n ['sw', { x: bounds.x, y: bounds.y + bounds.h }],\r\n ['se', { x: bounds.x + bounds.w, y: bounds.y + bounds.h }],\r\n ];\r\n }\r\n\r\n private renderMarquee(canvasCtx: CanvasRenderingContext2D): void {\r\n if (this.mode.type !== 'marquee') return;\r\n\r\n const rect = this.getMarqueeRect();\r\n if (!rect) return;\r\n\r\n canvasCtx.save();\r\n canvasCtx.strokeStyle = '#2196F3';\r\n canvasCtx.fillStyle = 'rgba(33, 150, 243, 0.08)';\r\n canvasCtx.lineWidth = 1;\r\n canvasCtx.setLineDash([4, 4]);\r\n canvasCtx.strokeRect(rect.x, rect.y, rect.w, rect.h);\r\n canvasCtx.fillRect(rect.x, rect.y, rect.w, rect.h);\r\n canvasCtx.restore();\r\n }\r\n\r\n private renderSelectionBoxes(canvasCtx: CanvasRenderingContext2D): void {\r\n if (this._selectedIds.length === 0 || !this.ctx) return;\r\n\r\n const zoom = this.ctx.camera.zoom;\r\n const handleWorldSize = HANDLE_SIZE / zoom;\r\n\r\n canvasCtx.save();\r\n canvasCtx.strokeStyle = '#2196F3';\r\n canvasCtx.lineWidth = 1.5 / zoom;\r\n canvasCtx.setLineDash([4 / zoom, 4 / zoom]);\r\n\r\n for (const id of this._selectedIds) {\r\n const el = this.ctx.store.getById(id);\r\n if (!el) continue;\r\n\r\n if (el.type === 'arrow') {\r\n renderArrowHandles(canvasCtx, el, zoom);\r\n this.renderBindingHighlights(canvasCtx, el, zoom);\r\n continue;\r\n }\r\n\r\n const bounds = this.getElementBounds(el);\r\n if (!bounds) continue;\r\n\r\n const pad = SELECTION_PAD / zoom;\r\n canvasCtx.strokeRect(bounds.x - pad, bounds.y - pad, bounds.w + pad * 2, bounds.h + pad * 2);\r\n\r\n if ('size' in el) {\r\n canvasCtx.setLineDash([]);\r\n canvasCtx.fillStyle = '#ffffff';\r\n const corners = this.getHandlePositions(bounds);\r\n for (const [, pos] of corners) {\r\n canvasCtx.fillRect(\r\n pos.x - handleWorldSize / 2,\r\n pos.y - handleWorldSize / 2,\r\n handleWorldSize,\r\n handleWorldSize,\r\n );\r\n canvasCtx.strokeRect(\r\n pos.x - handleWorldSize / 2,\r\n pos.y - handleWorldSize / 2,\r\n handleWorldSize,\r\n handleWorldSize,\r\n );\r\n }\r\n canvasCtx.setLineDash([4 / zoom, 4 / zoom]);\r\n }\r\n }\r\n\r\n canvasCtx.restore();\r\n }\r\n\r\n private renderBindingHighlights(\r\n canvasCtx: CanvasRenderingContext2D,\r\n arrow: ArrowElement,\r\n zoom: number,\r\n ): void {\r\n if (!this.ctx) return;\r\n if (!arrow.fromBinding && !arrow.toBinding) return;\r\n\r\n const pad = SELECTION_PAD / zoom;\r\n\r\n canvasCtx.save();\r\n canvasCtx.strokeStyle = '#2196F3';\r\n canvasCtx.lineWidth = 2 / zoom;\r\n canvasCtx.setLineDash([]);\r\n\r\n const drawn = new Set<string>();\r\n for (const binding of [arrow.fromBinding, arrow.toBinding]) {\r\n if (!binding || drawn.has(binding.elementId)) continue;\r\n drawn.add(binding.elementId);\r\n\r\n const target = this.ctx.store.getById(binding.elementId);\r\n if (!target) continue;\r\n\r\n const bounds = getElementBounds(target);\r\n if (!bounds) continue;\r\n\r\n canvasCtx.strokeRect(bounds.x - pad, bounds.y - pad, bounds.w + pad * 2, bounds.h + pad * 2);\r\n }\r\n\r\n canvasCtx.restore();\r\n }\r\n\r\n private getMarqueeRect(): Rect | null {\r\n if (this.mode.type !== 'marquee') return null;\r\n\r\n const { start } = this.mode;\r\n const end = this.currentWorld;\r\n const x = Math.min(start.x, end.x);\r\n const y = Math.min(start.y, end.y);\r\n const w = Math.abs(end.x - start.x);\r\n const h = Math.abs(end.y - start.y);\r\n\r\n if (w === 0 && h === 0) return null;\r\n return { x, y, w, h };\r\n }\r\n\r\n private findElementsInRect(marquee: Rect, ctx: ToolContext): string[] {\r\n const ids: string[] = [];\r\n for (const el of ctx.store.getAll()) {\r\n if (ctx.isLayerVisible && !ctx.isLayerVisible(el.layerId)) continue;\r\n if (ctx.isLayerLocked && ctx.isLayerLocked(el.layerId)) continue;\r\n if (el.type === 'grid') continue;\r\n const bounds = this.getElementBounds(el);\r\n if (bounds && this.rectsOverlap(marquee, bounds)) {\r\n ids.push(el.id);\r\n }\r\n }\r\n return ids;\r\n }\r\n\r\n private rectsOverlap(a: Rect, b: Rect): boolean {\r\n return a.x <= b.x + b.w && a.x + a.w >= b.x && a.y <= b.y + b.h && a.y + a.h >= b.y;\r\n }\r\n\r\n private getElementBounds(el: CanvasElement): Rect | null {\r\n if ('size' in el) {\r\n return { x: el.position.x, y: el.position.y, w: el.size.w, h: el.size.h };\r\n }\r\n if (el.type === 'stroke' && el.points.length > 0) {\r\n let minX = Infinity,\r\n minY = Infinity,\r\n maxX = -Infinity,\r\n maxY = -Infinity;\r\n for (const p of el.points) {\r\n const px = p.x + el.position.x;\r\n const py = p.y + el.position.y;\r\n if (px < minX) minX = px;\r\n if (py < minY) minY = py;\r\n if (px > maxX) maxX = px;\r\n if (py > maxY) maxY = py;\r\n }\r\n return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };\r\n }\r\n if (el.type === 'arrow') {\r\n return getArrowBounds(el.from, el.to, el.bend);\r\n }\r\n return null;\r\n }\r\n\r\n private hitTest(world: Point, ctx: ToolContext): CanvasElement | null {\r\n const elements = ctx.store.getAll().reverse();\r\n for (const el of elements) {\r\n if (ctx.isLayerVisible && !ctx.isLayerVisible(el.layerId)) continue;\r\n if (ctx.isLayerLocked && ctx.isLayerLocked(el.layerId)) continue;\r\n if (el.type === 'grid') continue;\r\n if (this.isInsideBounds(world, el)) return el;\r\n }\r\n return null;\r\n }\r\n\r\n private isInsideBounds(point: Point, el: CanvasElement): boolean {\r\n if (el.type === 'grid') return false;\r\n if ('size' in el) {\r\n const s = el.size;\r\n return (\r\n point.x >= el.position.x &&\r\n point.x <= el.position.x + s.w &&\r\n point.y >= el.position.y &&\r\n point.y <= el.position.y + s.h\r\n );\r\n }\r\n\r\n if (el.type === 'stroke') {\r\n const HIT_RADIUS = 10;\r\n return el.points.some((p) => {\r\n const dx = p.x + el.position.x - point.x;\r\n const dy = p.y + el.position.y - point.y;\r\n return dx * dx + dy * dy <= HIT_RADIUS * HIT_RADIUS;\r\n });\r\n }\r\n\r\n if (el.type === 'arrow') {\r\n return isNearBezier(point, el.from, el.to, el.bend, 10);\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n","import type { Point } from '../core/types';\r\nimport type { Binding, CanvasElement } from '../elements/types';\r\nimport type { Tool, ToolContext, PointerState } from './types';\r\nimport { createArrow } from '../elements/element-factory';\r\nimport { findBindTarget, getElementCenter, getElementBounds } from '../elements/arrow-binding';\r\nimport { snapPoint } from '../core/snap';\r\n\r\nconst BIND_THRESHOLD = 20;\r\n\r\nexport interface ArrowToolOptions {\r\n color?: string;\r\n width?: number;\r\n}\r\n\r\nexport class ArrowTool implements Tool {\r\n readonly name = 'arrow';\r\n private drawing = false;\r\n private start: Point = { x: 0, y: 0 };\r\n private end: Point = { x: 0, y: 0 };\r\n private color: string;\r\n private width: number;\r\n private fromBinding: Binding | undefined;\r\n private fromTarget: CanvasElement | null = null;\r\n private toTarget: CanvasElement | null = null;\r\n\r\n constructor(options: ArrowToolOptions = {}) {\r\n this.color = options.color ?? '#000000';\r\n this.width = options.width ?? 2;\r\n }\r\n\r\n setOptions(options: ArrowToolOptions): void {\r\n if (options.color !== undefined) this.color = options.color;\r\n if (options.width !== undefined) this.width = options.width;\r\n }\r\n\r\n private layerFilter(ctx: ToolContext): ((el: CanvasElement) => boolean) | undefined {\r\n const activeLayerId = ctx.activeLayerId;\r\n if (!activeLayerId && !ctx.isLayerVisible && !ctx.isLayerLocked) return undefined;\r\n return (el: CanvasElement) => {\r\n if (activeLayerId && el.layerId !== activeLayerId) return false;\r\n if (ctx.isLayerVisible && !ctx.isLayerVisible(el.layerId)) return false;\r\n if (ctx.isLayerLocked && ctx.isLayerLocked(el.layerId)) return false;\r\n return true;\r\n };\r\n }\r\n\r\n onPointerDown(state: PointerState, ctx: ToolContext): void {\r\n this.drawing = true;\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n const threshold = BIND_THRESHOLD / ctx.camera.zoom;\r\n const filter = this.layerFilter(ctx);\r\n\r\n const target = findBindTarget(world, ctx.store, threshold, undefined, filter);\r\n if (target) {\r\n this.start = getElementCenter(target);\r\n this.fromBinding = { elementId: target.id };\r\n this.fromTarget = target;\r\n } else {\r\n this.start = ctx.snapToGrid && ctx.gridSize ? snapPoint(world, ctx.gridSize) : world;\r\n this.fromBinding = undefined;\r\n this.fromTarget = null;\r\n }\r\n this.end = { ...this.start };\r\n this.toTarget = null;\r\n }\r\n\r\n onPointerMove(state: PointerState, ctx: ToolContext): void {\r\n if (!this.drawing) return;\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n const threshold = BIND_THRESHOLD / ctx.camera.zoom;\r\n const excludeId = this.fromBinding?.elementId;\r\n const filter = this.layerFilter(ctx);\r\n\r\n const target = findBindTarget(world, ctx.store, threshold, excludeId, filter);\r\n if (target) {\r\n this.end = getElementCenter(target);\r\n this.toTarget = target;\r\n } else {\r\n this.end = ctx.snapToGrid && ctx.gridSize ? snapPoint(world, ctx.gridSize) : world;\r\n this.toTarget = null;\r\n }\r\n ctx.requestRender();\r\n }\r\n\r\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\r\n if (!this.drawing) return;\r\n this.drawing = false;\r\n\r\n if (this.start.x === this.end.x && this.start.y === this.end.y) return;\r\n\r\n const arrow = createArrow({\r\n from: this.start,\r\n to: this.end,\r\n position: this.start,\r\n color: this.color,\r\n width: this.width,\r\n fromBinding: this.fromBinding,\r\n toBinding: this.toTarget ? { elementId: this.toTarget.id } : undefined,\r\n layerId: ctx.activeLayerId ?? '',\r\n });\r\n ctx.store.add(arrow);\r\n this.fromTarget = null;\r\n this.toTarget = null;\r\n ctx.requestRender();\r\n ctx.switchTool?.('select');\r\n }\r\n\r\n renderOverlay(ctx: CanvasRenderingContext2D): void {\r\n if (!this.drawing) return;\r\n if (this.start.x === this.end.x && this.start.y === this.end.y) return;\r\n\r\n ctx.save();\r\n\r\n if (this.fromTarget) {\r\n const bounds = getElementBounds(this.fromTarget);\r\n if (bounds) {\r\n ctx.strokeStyle = '#2196F3';\r\n ctx.lineWidth = 2;\r\n ctx.setLineDash([]);\r\n ctx.strokeRect(bounds.x, bounds.y, bounds.w, bounds.h);\r\n }\r\n }\r\n\r\n if (this.toTarget) {\r\n const bounds = getElementBounds(this.toTarget);\r\n if (bounds) {\r\n ctx.strokeStyle = '#2196F3';\r\n ctx.lineWidth = 2;\r\n ctx.setLineDash([]);\r\n ctx.strokeRect(bounds.x, bounds.y, bounds.w, bounds.h);\r\n }\r\n }\r\n\r\n ctx.strokeStyle = this.color;\r\n ctx.lineWidth = this.width;\r\n ctx.lineCap = 'round';\r\n ctx.globalAlpha = 0.6;\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(this.start.x, this.start.y);\r\n ctx.lineTo(this.end.x, this.end.y);\r\n ctx.stroke();\r\n\r\n const angle = Math.atan2(this.end.y - this.start.y, this.end.x - this.start.x);\r\n const headLen = 12;\r\n const headAngle = Math.PI / 6;\r\n\r\n ctx.fillStyle = this.color;\r\n ctx.beginPath();\r\n ctx.moveTo(this.end.x, this.end.y);\r\n ctx.lineTo(\r\n this.end.x - headLen * Math.cos(angle - headAngle),\r\n this.end.y - headLen * Math.sin(angle - headAngle),\r\n );\r\n ctx.lineTo(\r\n this.end.x - headLen * Math.cos(angle + headAngle),\r\n this.end.y - headLen * Math.sin(angle + headAngle),\r\n );\r\n ctx.closePath();\r\n ctx.fill();\r\n ctx.restore();\r\n }\r\n}\r\n","import type { Size } from '../core/types';\r\nimport type { Tool, ToolContext, PointerState } from './types';\r\nimport { createNote } from '../elements/element-factory';\r\nimport { snapPoint } from '../core/snap';\r\n\r\nexport interface NoteToolOptions {\r\n backgroundColor?: string;\r\n textColor?: string;\r\n size?: Size;\r\n}\r\n\r\nexport class NoteTool implements Tool {\r\n readonly name = 'note';\r\n private backgroundColor: string;\r\n private textColor: string;\r\n private size: Size;\r\n\r\n constructor(options: NoteToolOptions = {}) {\r\n this.backgroundColor = options.backgroundColor ?? '#ffeb3b';\r\n this.textColor = options.textColor ?? '#000000';\r\n this.size = options.size ?? { w: 200, h: 100 };\r\n }\r\n\r\n setOptions(options: NoteToolOptions): void {\r\n if (options.backgroundColor !== undefined) this.backgroundColor = options.backgroundColor;\r\n if (options.textColor !== undefined) this.textColor = options.textColor;\r\n if (options.size !== undefined) this.size = options.size;\r\n }\r\n\r\n onPointerDown(_state: PointerState, _ctx: ToolContext): void {\r\n // Note is placed on pointer up\r\n }\r\n\r\n onPointerMove(_state: PointerState, _ctx: ToolContext): void {\r\n // No drag behavior for note placement\r\n }\r\n\r\n onPointerUp(state: PointerState, ctx: ToolContext): void {\r\n let world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n if (ctx.snapToGrid && ctx.gridSize) {\r\n world = snapPoint(world, ctx.gridSize);\r\n }\r\n const note = createNote({\r\n position: world,\r\n size: { ...this.size },\r\n backgroundColor: this.backgroundColor,\r\n textColor: this.textColor,\r\n layerId: ctx.activeLayerId ?? '',\r\n });\r\n ctx.store.add(note);\r\n ctx.requestRender();\r\n\r\n ctx.switchTool?.('select');\r\n ctx.editElement?.(note.id);\r\n }\r\n}\r\n","import type { Tool, ToolContext, PointerState } from './types';\r\nimport { createText } from '../elements/element-factory';\r\nimport { snapPoint } from '../core/snap';\r\n\r\nexport interface TextToolOptions {\r\n fontSize?: number;\r\n color?: string;\r\n textAlign?: 'left' | 'center' | 'right';\r\n}\r\n\r\nexport class TextTool implements Tool {\r\n readonly name = 'text';\r\n private fontSize: number;\r\n private color: string;\r\n private textAlign: 'left' | 'center' | 'right';\r\n\r\n constructor(options: TextToolOptions = {}) {\r\n this.fontSize = options.fontSize ?? 16;\r\n this.color = options.color ?? '#1a1a1a';\r\n this.textAlign = options.textAlign ?? 'left';\r\n }\r\n\r\n setOptions(options: TextToolOptions): void {\r\n if (options.fontSize !== undefined) this.fontSize = options.fontSize;\r\n if (options.color !== undefined) this.color = options.color;\r\n if (options.textAlign !== undefined) this.textAlign = options.textAlign;\r\n }\r\n\r\n onActivate(ctx: ToolContext): void {\r\n ctx.setCursor?.('text');\r\n }\r\n\r\n onDeactivate(ctx: ToolContext): void {\r\n ctx.setCursor?.('default');\r\n }\r\n\r\n onPointerDown(_state: PointerState, _ctx: ToolContext): void {\r\n // Text is placed on pointer up\r\n }\r\n\r\n onPointerMove(_state: PointerState, _ctx: ToolContext): void {\r\n // No drag behavior for text placement\r\n }\r\n\r\n onPointerUp(state: PointerState, ctx: ToolContext): void {\r\n let world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n if (ctx.snapToGrid && ctx.gridSize) {\r\n world = snapPoint(world, ctx.gridSize);\r\n }\r\n const textEl = createText({\r\n position: world,\r\n fontSize: this.fontSize,\r\n color: this.color,\r\n textAlign: this.textAlign,\r\n layerId: ctx.activeLayerId ?? '',\r\n });\r\n ctx.store.add(textEl);\r\n ctx.requestRender();\r\n\r\n ctx.switchTool?.('select');\r\n ctx.editElement?.(textEl.id);\r\n }\r\n}\r\n","import type { Size } from '../core/types';\nimport type { Tool, ToolContext, PointerState } from './types';\nimport { createImage } from '../elements/element-factory';\n\nexport interface ImageToolOptions {\n size?: Size;\n}\n\nexport class ImageTool implements Tool {\n readonly name = 'image';\n private size: Size;\n private src: string | null = null;\n\n constructor(options: ImageToolOptions = {}) {\n this.size = options.size ?? { w: 300, h: 200 };\n }\n\n setSrc(src: string): void {\n this.src = src;\n }\n\n onPointerDown(_state: PointerState, _ctx: ToolContext): void {\n // No action on pointer down — image is placed on pointer up\n }\n\n onPointerMove(_state: PointerState, _ctx: ToolContext): void {\n // No action on pointer move\n }\n\n onPointerUp(state: PointerState, ctx: ToolContext): void {\n if (!this.src) return;\n\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\n const image = createImage({\n position: world,\n size: { ...this.size },\n src: this.src,\n });\n ctx.store.add(image);\n ctx.requestRender();\n\n this.src = null;\n ctx.switchTool?.('select');\n }\n}\n","import type { Point } from '../core/types';\r\nimport type { ShapeKind } from '../elements/types';\r\nimport type { Tool, ToolContext, PointerState } from './types';\r\nimport { createShape } from '../elements/element-factory';\r\nimport { snapPoint } from '../core/snap';\r\n\r\nexport interface ShapeToolOptions {\r\n shape?: ShapeKind;\r\n strokeColor?: string;\r\n strokeWidth?: number;\r\n fillColor?: string;\r\n}\r\n\r\nexport class ShapeTool implements Tool {\r\n readonly name = 'shape';\r\n private drawing = false;\r\n private start: Point = { x: 0, y: 0 };\r\n private end: Point = { x: 0, y: 0 };\r\n private shiftHeld = false;\r\n private shape: ShapeKind;\r\n private strokeColor: string;\r\n private strokeWidth: number;\r\n private fillColor: string;\r\n\r\n constructor(options: ShapeToolOptions = {}) {\r\n this.shape = options.shape ?? 'rectangle';\r\n this.strokeColor = options.strokeColor ?? '#000000';\r\n this.strokeWidth = options.strokeWidth ?? 2;\r\n this.fillColor = options.fillColor ?? 'none';\r\n }\r\n\r\n setOptions(options: ShapeToolOptions): void {\r\n if (options.shape !== undefined) this.shape = options.shape;\r\n if (options.strokeColor !== undefined) this.strokeColor = options.strokeColor;\r\n if (options.strokeWidth !== undefined) this.strokeWidth = options.strokeWidth;\r\n if (options.fillColor !== undefined) this.fillColor = options.fillColor;\r\n }\r\n\r\n onActivate(_ctx: ToolContext): void {\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('keydown', this.onKeyDown);\r\n window.addEventListener('keyup', this.onKeyUp);\r\n }\r\n }\r\n\r\n onDeactivate(_ctx: ToolContext): void {\r\n this.shiftHeld = false;\r\n if (typeof window !== 'undefined') {\r\n window.removeEventListener('keydown', this.onKeyDown);\r\n window.removeEventListener('keyup', this.onKeyUp);\r\n }\r\n }\r\n\r\n onPointerDown(state: PointerState, ctx: ToolContext): void {\r\n this.drawing = true;\r\n this.start = this.snap(ctx.camera.screenToWorld({ x: state.x, y: state.y }), ctx);\r\n this.end = { ...this.start };\r\n }\r\n\r\n onPointerMove(state: PointerState, ctx: ToolContext): void {\r\n if (!this.drawing) return;\r\n this.end = this.snap(ctx.camera.screenToWorld({ x: state.x, y: state.y }), ctx);\r\n ctx.requestRender();\r\n }\r\n\r\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\r\n if (!this.drawing) return;\r\n this.drawing = false;\r\n\r\n const { position, size } = this.computeRect();\r\n if (size.w === 0 || size.h === 0) return;\r\n\r\n const shape = createShape({\r\n position,\r\n size,\r\n shape: this.shape,\r\n strokeColor: this.strokeColor,\r\n strokeWidth: this.strokeWidth,\r\n fillColor: this.fillColor,\r\n layerId: ctx.activeLayerId ?? '',\r\n });\r\n ctx.store.add(shape);\r\n ctx.requestRender();\r\n ctx.switchTool?.('select');\r\n }\r\n\r\n renderOverlay(ctx: CanvasRenderingContext2D): void {\r\n if (!this.drawing) return;\r\n\r\n const { position, size } = this.computeRect();\r\n if (size.w === 0 && size.h === 0) return;\r\n\r\n ctx.save();\r\n ctx.globalAlpha = 0.5;\r\n ctx.strokeStyle = this.strokeColor;\r\n ctx.lineWidth = this.strokeWidth;\r\n\r\n if (this.fillColor !== 'none') {\r\n ctx.fillStyle = this.fillColor;\r\n }\r\n\r\n switch (this.shape) {\r\n case 'rectangle':\r\n if (this.fillColor !== 'none') {\r\n ctx.fillRect(position.x, position.y, size.w, size.h);\r\n }\r\n ctx.strokeRect(position.x, position.y, size.w, size.h);\r\n break;\r\n case 'ellipse': {\r\n const cx = position.x + size.w / 2;\r\n const cy = position.y + size.h / 2;\r\n ctx.beginPath();\r\n ctx.ellipse(cx, cy, size.w / 2, size.h / 2, 0, 0, Math.PI * 2);\r\n if (this.fillColor !== 'none') ctx.fill();\r\n ctx.stroke();\r\n break;\r\n }\r\n }\r\n\r\n ctx.restore();\r\n }\r\n\r\n private computeRect(): { position: Point; size: { w: number; h: number } } {\r\n let x = Math.min(this.start.x, this.end.x);\r\n let y = Math.min(this.start.y, this.end.y);\r\n let w = Math.abs(this.end.x - this.start.x);\r\n let h = Math.abs(this.end.y - this.start.y);\r\n\r\n if (this.shiftHeld) {\r\n const side = Math.max(w, h);\r\n w = side;\r\n h = side;\r\n x = this.end.x >= this.start.x ? this.start.x : this.start.x - side;\r\n y = this.end.y >= this.start.y ? this.start.y : this.start.y - side;\r\n }\r\n\r\n return { position: { x, y }, size: { w, h } };\r\n }\r\n\r\n private snap(point: Point, ctx: ToolContext): Point {\r\n return ctx.snapToGrid && ctx.gridSize ? snapPoint(point, ctx.gridSize) : point;\r\n }\r\n\r\n private onKeyDown = (e: KeyboardEvent): void => {\r\n if (e.key === 'Shift') this.shiftHeld = true;\r\n };\r\n\r\n private onKeyUp = (e: KeyboardEvent): void => {\r\n if (e.key === 'Shift') this.shiftHeld = false;\r\n };\r\n}\r\n","import type { ElementStore } from '../elements/element-store';\r\nimport type { Command } from './types';\r\nimport type { LayerManager } from '../layers/layer-manager';\r\nimport type { Layer } from '../layers/types';\r\n\r\nexport class CreateLayerCommand implements Command {\r\n constructor(\r\n private readonly manager: LayerManager,\r\n private readonly layer: Layer,\r\n ) {}\r\n\r\n execute(_store: ElementStore): void {\r\n this.manager.addLayerDirect(this.layer);\r\n }\r\n\r\n undo(_store: ElementStore): void {\r\n this.manager.removeLayerDirect(this.layer.id);\r\n }\r\n}\r\n\r\nexport class RemoveLayerCommand implements Command {\r\n constructor(\r\n private readonly manager: LayerManager,\r\n private readonly layer: Layer,\r\n ) {}\r\n\r\n execute(_store: ElementStore): void {\r\n this.manager.removeLayerDirect(this.layer.id);\r\n }\r\n\r\n undo(_store: ElementStore): void {\r\n this.manager.addLayerDirect(this.layer);\r\n }\r\n}\r\n\r\nexport class UpdateLayerCommand implements Command {\r\n constructor(\r\n private readonly manager: LayerManager,\r\n private readonly layerId: string,\r\n private readonly previous: Layer,\r\n private readonly current: Layer,\r\n ) {}\r\n\r\n execute(_store: ElementStore): void {\r\n this.manager.updateLayerDirect(this.layerId, { ...this.current });\r\n }\r\n\r\n undo(_store: ElementStore): void {\r\n this.manager.updateLayerDirect(this.layerId, { ...this.previous });\r\n }\r\n}\r\n"],"mappings":"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","names":["minX","minY","HANDLE_HIT_PADDING","BIND_THRESHOLD"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/event-bus.ts","../src/core/state-serializer.ts","../src/core/snap.ts","../src/core/auto-save.ts","../src/canvas/camera.ts","../src/canvas/background.ts","../src/canvas/input-handler.ts","../src/elements/element-store.ts","../src/elements/arrow-geometry.ts","../src/elements/arrow-binding.ts","../src/elements/stroke-smoothing.ts","../src/elements/grid-renderer.ts","../src/elements/element-renderer.ts","../src/elements/note-editor.ts","../src/tools/tool-manager.ts","../src/history/history-stack.ts","../src/history/commands.ts","../src/history/history-recorder.ts","../src/elements/create-id.ts","../src/elements/element-factory.ts","../src/canvas/export-image.ts","../src/layers/layer-manager.ts","../src/canvas/viewport.ts","../src/tools/hand-tool.ts","../src/tools/pencil-tool.ts","../src/tools/eraser-tool.ts","../src/tools/arrow-handles.ts","../src/tools/select-tool.ts","../src/tools/arrow-tool.ts","../src/tools/note-tool.ts","../src/tools/text-tool.ts","../src/tools/image-tool.ts","../src/tools/shape-tool.ts","../src/history/layer-commands.ts"],"sourcesContent":["export const VERSION = '0.8.2';\n\nexport { EventBus } from './core/event-bus';\nexport type { Point, StrokePoint, Size, Bounds } from './core/types';\nexport { exportState, parseState } from './core/state-serializer';\nexport { snapPoint } from './core/snap';\nexport type { CanvasState } from './core/state-serializer';\nexport { AutoSave } from './core/auto-save';\nexport type { AutoSaveOptions } from './core/auto-save';\n\nexport { Camera } from './canvas/camera';\nexport type { CameraOptions } from './canvas/camera';\nexport { Background } from './canvas/background';\nexport type { BackgroundOptions, BackgroundPattern } from './canvas/background';\nexport { InputHandler } from './canvas/input-handler';\nexport { Viewport } from './canvas/viewport';\nexport type { ViewportOptions } from './canvas/viewport';\nexport { exportImage } from './canvas/export-image';\nexport type { ExportImageOptions } from './canvas/export-image';\n\nexport { ElementStore } from './elements/element-store';\nexport type { ElementUpdateEvent } from './elements/element-store';\nexport { ElementRenderer } from './elements/element-renderer';\nexport { NoteEditor } from './elements/note-editor';\nexport { createId } from './elements/create-id';\nexport {\n createStroke,\n createNote,\n createArrow,\n createImage,\n createHtmlElement,\n createText,\n createShape,\n createGrid,\n} from './elements/element-factory';\nexport {\n getArrowControlPoint,\n getArrowMidpoint,\n getBendFromPoint,\n getArrowTangentAngle,\n isNearBezier,\n getArrowBounds,\n} from './elements/arrow-geometry';\nexport {\n isBindable,\n getElementCenter,\n getElementBounds,\n getEdgeIntersection,\n findBindTarget,\n findBoundArrows,\n updateBoundArrow,\n clearStaleBindings,\n unbindArrow,\n} from './elements/arrow-binding';\nexport type {\n Binding,\n CanvasElement,\n ElementType,\n StrokeElement,\n NoteElement,\n ArrowElement,\n ImageElement,\n HtmlElement,\n TextElement,\n ShapeElement,\n ShapeKind,\n GridElement,\n HexOrientation,\n} from './elements/types';\n\nexport type { Command } from './history/types';\nexport {\n AddElementCommand,\n RemoveElementCommand,\n UpdateElementCommand,\n BatchCommand,\n} from './history/commands';\nexport { HistoryStack } from './history/history-stack';\nexport type { HistoryStackOptions } from './history/history-stack';\nexport { HistoryRecorder } from './history/history-recorder';\n\nexport { ToolManager } from './tools/tool-manager';\nexport { HandTool } from './tools/hand-tool';\nexport { PencilTool } from './tools/pencil-tool';\nexport type { PencilToolOptions } from './tools/pencil-tool';\nexport { EraserTool } from './tools/eraser-tool';\nexport type { EraserToolOptions } from './tools/eraser-tool';\nexport { SelectTool } from './tools/select-tool';\nexport { ArrowTool } from './tools/arrow-tool';\nexport type { ArrowToolOptions } from './tools/arrow-tool';\nexport { NoteTool } from './tools/note-tool';\nexport type { NoteToolOptions } from './tools/note-tool';\nexport { TextTool } from './tools/text-tool';\nexport type { TextToolOptions } from './tools/text-tool';\nexport { ImageTool } from './tools/image-tool';\nexport type { ImageToolOptions } from './tools/image-tool';\nexport { ShapeTool } from './tools/shape-tool';\nexport type { ShapeToolOptions } from './tools/shape-tool';\nexport type { Tool, ToolContext, PointerState, ToolName } from './tools/types';\n\nexport { LayerManager } from './layers/layer-manager';\nexport type { Layer } from './layers/types';\nexport {\n CreateLayerCommand,\n RemoveLayerCommand,\n UpdateLayerCommand,\n} from './history/layer-commands';\n","type Listener<T> = (data: T) => void;\n\nexport class EventBus<TEvents extends { [K in keyof TEvents]: TEvents[K] }> {\n private listeners = new Map<keyof TEvents, Set<Listener<never>>>();\n\n on<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): () => void {\n const existing = this.listeners.get(event);\n if (existing) {\n existing.add(listener as Listener<never>);\n } else {\n const set = new Set<Listener<never>>([listener as Listener<never>]);\n this.listeners.set(event, set);\n }\n return () => this.off(event, listener);\n }\n\n off<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): void {\n this.listeners.get(event)?.delete(listener as Listener<never>);\n }\n\n emit<K extends keyof TEvents>(event: K, data: TEvents[K]): void {\n this.listeners.get(event)?.forEach((listener) => listener(data as never));\n }\n\n clear(): void {\n this.listeners.clear();\n }\n}\n","import type { CanvasElement } from '../elements/types';\r\nimport type { Point } from './types';\r\nimport type { Layer } from '../layers/types';\r\n\r\nexport interface CanvasState {\r\n version: number;\r\n camera: {\r\n position: Point;\r\n zoom: number;\r\n };\r\n elements: CanvasElement[];\r\n layers?: Layer[];\r\n}\r\n\r\nconst CURRENT_VERSION = 2;\r\n\r\nexport function exportState(\r\n elements: CanvasElement[],\r\n camera: { position: Point; zoom: number },\r\n layers: Layer[] = [],\r\n): CanvasState {\r\n return {\r\n version: CURRENT_VERSION,\r\n camera: {\r\n position: { ...camera.position },\r\n zoom: camera.zoom,\r\n },\r\n elements: elements.map((el) => structuredClone(el)),\r\n layers: layers.map((l) => ({ ...l })),\r\n };\r\n}\r\n\r\nexport function parseState(json: string): CanvasState {\r\n const data: unknown = JSON.parse(json);\r\n validateState(data);\r\n return data;\r\n}\r\n\r\nfunction validateState(data: unknown): asserts data is CanvasState {\r\n if (!data || typeof data !== 'object') {\r\n throw new Error('Invalid state: expected an object');\r\n }\r\n\r\n const obj = data as Record<string, unknown>;\r\n\r\n if (typeof obj['version'] !== 'number') {\r\n throw new Error('Invalid state: missing or invalid version');\r\n }\r\n\r\n if (!obj['camera'] || typeof obj['camera'] !== 'object') {\r\n throw new Error('Invalid state: missing camera');\r\n }\r\n\r\n const cam = obj['camera'] as Record<string, unknown>;\r\n if (!cam['position'] || typeof cam['position'] !== 'object') {\r\n throw new Error('Invalid state: missing camera.position');\r\n }\r\n\r\n const pos = cam['position'] as Record<string, unknown>;\r\n if (typeof pos['x'] !== 'number' || typeof pos['y'] !== 'number') {\r\n throw new Error('Invalid state: camera.position must have x and y numbers');\r\n }\r\n\r\n if (typeof cam['zoom'] !== 'number') {\r\n throw new Error('Invalid state: missing camera.zoom');\r\n }\r\n\r\n if (!Array.isArray(obj['elements'])) {\r\n throw new Error('Invalid state: elements must be an array');\r\n }\r\n\r\n for (const el of obj['elements'] as unknown[]) {\r\n validateElement(el);\r\n migrateElement(el as unknown as Record<string, unknown>);\r\n }\r\n\r\n cleanBindings(obj['elements'] as Record<string, unknown>[]);\r\n\r\n const layers = obj['layers'];\r\n if (!Array.isArray(layers) || layers.length === 0) {\r\n obj['layers'] = [\r\n {\r\n id: 'default-layer',\r\n name: 'Layer 1',\r\n visible: true,\r\n locked: false,\r\n order: 0,\r\n opacity: 1.0,\r\n },\r\n ];\r\n }\r\n}\r\n\r\nconst VALID_TYPES = new Set(['stroke', 'note', 'arrow', 'image', 'html', 'text', 'shape', 'grid']);\r\n\r\nfunction validateElement(el: unknown): asserts el is CanvasElement {\r\n if (!el || typeof el !== 'object') {\r\n throw new Error('Invalid element: expected an object');\r\n }\r\n\r\n const obj = el as Record<string, unknown>;\r\n\r\n if (typeof obj['id'] !== 'string') {\r\n throw new Error('Invalid element: missing id');\r\n }\r\n\r\n if (typeof obj['type'] !== 'string' || !VALID_TYPES.has(obj['type'])) {\r\n throw new Error(`Invalid element: unknown type \"${String(obj['type'])}\"`);\r\n }\r\n\r\n if (typeof obj['zIndex'] !== 'number') {\r\n throw new Error('Invalid element: missing zIndex');\r\n }\r\n}\r\n\r\nfunction cleanBindings(elements: Record<string, unknown>[]): void {\r\n const ids = new Set(elements.map((el) => el['id'] as string));\r\n\r\n for (const el of elements) {\r\n if (el['type'] !== 'arrow') continue;\r\n\r\n const fromBinding = el['fromBinding'] as Record<string, unknown> | undefined;\r\n if (fromBinding && !ids.has(fromBinding['elementId'] as string)) {\r\n el['fromBinding'] = undefined;\r\n }\r\n\r\n const toBinding = el['toBinding'] as Record<string, unknown> | undefined;\r\n if (toBinding && !ids.has(toBinding['elementId'] as string)) {\r\n el['toBinding'] = undefined;\r\n }\r\n }\r\n}\r\n\r\nfunction migrateElement(obj: Record<string, unknown>): void {\r\n if (typeof obj['layerId'] !== 'string') {\r\n obj['layerId'] = 'default-layer';\r\n }\r\n\r\n if (obj['type'] === 'arrow' && typeof obj['bend'] !== 'number') {\r\n obj['bend'] = 0;\r\n }\r\n\r\n if (obj['type'] === 'stroke' && Array.isArray(obj['points'])) {\r\n for (const pt of obj['points'] as Record<string, unknown>[]) {\r\n if (typeof pt['pressure'] !== 'number') {\r\n pt['pressure'] = 0.5;\r\n }\r\n }\r\n }\r\n\r\n if (obj['type'] === 'shape' && typeof obj['shape'] !== 'string') {\r\n obj['shape'] = 'rectangle';\r\n }\r\n\r\n if (obj['type'] === 'note' && typeof obj['textColor'] !== 'string') {\r\n obj['textColor'] = '#000000';\r\n }\r\n}\r\n","import type { Point } from './types';\r\n\r\nexport function snapPoint(point: Point, gridSize: number): Point {\r\n return {\r\n x: Math.round(point.x / gridSize) * gridSize || 0,\r\n y: Math.round(point.y / gridSize) * gridSize || 0,\r\n };\r\n}\r\n","import type { ElementStore } from '../elements/element-store';\r\nimport type { Camera } from '../canvas/camera';\r\nimport type { LayerManager } from '../layers/layer-manager';\r\nimport { exportState, parseState } from './state-serializer';\r\nimport type { CanvasState } from './state-serializer';\r\n\r\nexport interface AutoSaveOptions {\r\n key?: string;\r\n debounceMs?: number;\r\n layerManager?: LayerManager;\r\n}\r\n\r\nconst DEFAULT_KEY = 'fieldnotes-autosave';\r\nconst DEFAULT_DEBOUNCE_MS = 1000;\r\n\r\nexport class AutoSave {\r\n private readonly key: string;\r\n private readonly debounceMs: number;\r\n private readonly layerManager?: LayerManager;\r\n private timerId: ReturnType<typeof setTimeout> | null = null;\r\n private unsubscribers: (() => void)[] = [];\r\n\r\n constructor(\r\n private readonly store: ElementStore,\r\n private readonly camera: Camera,\r\n options: AutoSaveOptions = {},\r\n ) {\r\n this.key = options.key ?? DEFAULT_KEY;\r\n this.debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;\r\n this.layerManager = options.layerManager;\r\n }\r\n\r\n start(): void {\r\n const schedule = () => this.scheduleSave();\r\n\r\n this.unsubscribers = [\r\n this.store.on('add', schedule),\r\n this.store.on('remove', schedule),\r\n this.store.on('update', schedule),\r\n this.camera.onChange(schedule),\r\n ];\r\n if (this.layerManager) {\r\n this.unsubscribers.push(this.layerManager.on('change', schedule));\r\n }\r\n }\r\n\r\n stop(): void {\r\n this.cancelPending();\r\n this.unsubscribers.forEach((fn) => fn());\r\n this.unsubscribers = [];\r\n }\r\n\r\n load(): CanvasState | null {\r\n if (typeof localStorage === 'undefined') return null;\r\n\r\n const json = localStorage.getItem(this.key);\r\n if (!json) return null;\r\n\r\n try {\r\n return parseState(json);\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n clear(): void {\r\n if (typeof localStorage === 'undefined') return;\r\n localStorage.removeItem(this.key);\r\n }\r\n\r\n private scheduleSave(): void {\r\n this.cancelPending();\r\n this.timerId = setTimeout(() => this.save(), this.debounceMs);\r\n }\r\n\r\n private cancelPending(): void {\r\n if (this.timerId !== null) {\r\n clearTimeout(this.timerId);\r\n this.timerId = null;\r\n }\r\n }\r\n\r\n private save(): void {\r\n if (typeof localStorage === 'undefined') return;\r\n\r\n const layers = this.layerManager?.snapshot() ?? [];\r\n const state = exportState(this.store.snapshot(), this.camera, layers);\r\n try {\r\n localStorage.setItem(this.key, JSON.stringify(state));\r\n } catch {\r\n console.warn('Auto-save failed: storage quota exceeded. State too large for localStorage.');\r\n }\r\n }\r\n}\r\n","import type { Point } from '../core/types';\n\nexport interface CameraOptions {\n minZoom?: number;\n maxZoom?: number;\n}\n\nconst DEFAULT_MIN_ZOOM = 0.1;\nconst DEFAULT_MAX_ZOOM = 10;\n\nexport class Camera {\n private x = 0;\n private y = 0;\n private z = 1;\n private readonly minZoom: number;\n private readonly maxZoom: number;\n private changeListeners = new Set<() => void>();\n\n constructor(options: CameraOptions = {}) {\n this.minZoom = options.minZoom ?? DEFAULT_MIN_ZOOM;\n this.maxZoom = options.maxZoom ?? DEFAULT_MAX_ZOOM;\n }\n\n get position(): Point {\n return { x: this.x, y: this.y };\n }\n\n get zoom(): number {\n return this.z;\n }\n\n pan(dx: number, dy: number): void {\n this.x += dx;\n this.y += dy;\n this.notifyChange();\n }\n\n moveTo(x: number, y: number): void {\n this.x = x;\n this.y = y;\n this.notifyChange();\n }\n\n setZoom(level: number): void {\n this.z = Math.min(this.maxZoom, Math.max(this.minZoom, level));\n this.notifyChange();\n }\n\n zoomAt(level: number, screenPoint: Point): void {\n const before = this.screenToWorld(screenPoint);\n this.z = Math.min(this.maxZoom, Math.max(this.minZoom, level));\n const after = this.screenToWorld(screenPoint);\n this.x += (after.x - before.x) * this.z;\n this.y += (after.y - before.y) * this.z;\n this.notifyChange();\n }\n\n screenToWorld(screen: Point): Point {\n return {\n x: (screen.x - this.x) / this.z,\n y: (screen.y - this.y) / this.z,\n };\n }\n\n worldToScreen(world: Point): Point {\n return {\n x: world.x * this.z + this.x,\n y: world.y * this.z + this.y,\n };\n }\n\n toCSSTransform(): string {\n return `translate3d(${this.x}px, ${this.y}px, 0) scale(${this.z})`;\n }\n\n onChange(listener: () => void): () => void {\n this.changeListeners.add(listener);\n return () => this.changeListeners.delete(listener);\n }\n\n private notifyChange(): void {\n this.changeListeners.forEach((fn) => fn());\n }\n}\n","import type { Camera } from './camera';\r\n\r\nexport type BackgroundPattern = 'dots' | 'grid' | 'none';\r\n\r\nexport interface BackgroundOptions {\r\n pattern?: BackgroundPattern;\r\n spacing?: number;\r\n color?: string;\r\n dotRadius?: number;\r\n lineWidth?: number;\r\n}\r\n\r\nconst MIN_PATTERN_SPACING = 16;\r\n\r\nconst DEFAULTS = {\r\n pattern: 'dots' as BackgroundPattern,\r\n spacing: 24,\r\n color: '#d0d0d0',\r\n dotRadius: 1,\r\n lineWidth: 0.5,\r\n};\r\n\r\nexport class Background {\r\n private readonly pattern: BackgroundPattern;\r\n private readonly spacing: number;\r\n private readonly color: string;\r\n private readonly dotRadius: number;\r\n private readonly lineWidth: number;\r\n\r\n constructor(options: BackgroundOptions = {}) {\r\n this.pattern = options.pattern ?? DEFAULTS.pattern;\r\n this.spacing = options.spacing ?? DEFAULTS.spacing;\r\n this.color = options.color ?? DEFAULTS.color;\r\n this.dotRadius = options.dotRadius ?? DEFAULTS.dotRadius;\r\n this.lineWidth = options.lineWidth ?? DEFAULTS.lineWidth;\r\n }\r\n\r\n render(ctx: CanvasRenderingContext2D, camera: Camera): void {\r\n const { width, height } = ctx.canvas;\r\n const dpr = typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;\r\n const cssWidth = width / dpr;\r\n const cssHeight = height / dpr;\r\n ctx.save();\r\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\r\n ctx.clearRect(0, 0, cssWidth, cssHeight);\r\n\r\n if (this.pattern === 'dots') {\r\n this.renderDots(ctx, camera, cssWidth, cssHeight);\r\n } else if (this.pattern === 'grid') {\r\n this.renderGrid(ctx, camera, cssWidth, cssHeight);\r\n }\r\n\r\n ctx.restore();\r\n }\r\n\r\n private adaptSpacing(baseSpacing: number, zoom: number): number {\r\n let spacing = baseSpacing * zoom;\r\n while (spacing < MIN_PATTERN_SPACING) {\r\n spacing *= 2;\r\n }\r\n return spacing;\r\n }\r\n\r\n private renderDots(\r\n ctx: CanvasRenderingContext2D,\r\n camera: Camera,\r\n width: number,\r\n height: number,\r\n ): void {\r\n const spacing = this.adaptSpacing(this.spacing, camera.zoom);\r\n const offsetX = camera.position.x % spacing;\r\n const offsetY = camera.position.y % spacing;\r\n const radius = this.dotRadius * Math.min(camera.zoom, 2);\r\n\r\n ctx.fillStyle = this.color;\r\n ctx.beginPath();\r\n\r\n for (let x = offsetX; x < width; x += spacing) {\r\n for (let y = offsetY; y < height; y += spacing) {\r\n ctx.moveTo(x + radius, y);\r\n ctx.arc(x, y, radius, 0, Math.PI * 2);\r\n }\r\n }\r\n\r\n ctx.fill();\r\n }\r\n\r\n private renderGrid(\r\n ctx: CanvasRenderingContext2D,\r\n camera: Camera,\r\n width: number,\r\n height: number,\r\n ): void {\r\n const spacing = this.adaptSpacing(this.spacing, camera.zoom);\r\n const offsetX = camera.position.x % spacing;\r\n const offsetY = camera.position.y % spacing;\r\n const lineW = this.lineWidth * Math.min(camera.zoom, 2);\r\n\r\n ctx.fillStyle = this.color;\r\n\r\n for (let x = offsetX; x < width; x += spacing) {\r\n ctx.fillRect(x, 0, lineW, height);\r\n }\r\n\r\n for (let y = offsetY; y < height; y += spacing) {\r\n ctx.fillRect(0, y, width, lineW);\r\n }\r\n }\r\n}\r\n","import type { Camera } from './camera';\r\nimport type { ToolManager } from '../tools/tool-manager';\r\nimport type { ToolContext, PointerState } from '../tools/types';\r\nimport type { SelectTool } from '../tools/select-tool';\r\nimport type { HistoryRecorder } from '../history/history-recorder';\r\nimport type { HistoryStack } from '../history/history-stack';\r\n\r\nconst ZOOM_SENSITIVITY = 0.001;\r\nconst MIDDLE_BUTTON = 1;\r\n\r\nexport interface InputHandlerOptions {\r\n toolManager?: ToolManager;\r\n toolContext?: ToolContext;\r\n historyRecorder?: HistoryRecorder;\r\n historyStack?: HistoryStack;\r\n}\r\n\r\nexport class InputHandler {\r\n private isPanning = false;\r\n private lastPointer = { x: 0, y: 0 };\r\n private spaceHeld = false;\r\n private activePointers = new Map<number, { x: number; y: number }>();\r\n private lastPinchDistance = 0;\r\n private lastPinchCenter = { x: 0, y: 0 };\r\n private toolManager: ToolManager | null;\r\n private toolContext: ToolContext | null;\r\n private historyRecorder: HistoryRecorder | null;\r\n private historyStack: HistoryStack | null;\r\n private isToolActive = false;\r\n private readonly abortController = new AbortController();\r\n\r\n constructor(\r\n private readonly element: HTMLElement,\r\n private readonly camera: Camera,\r\n options: InputHandlerOptions = {},\r\n ) {\r\n this.toolManager = options.toolManager ?? null;\r\n this.toolContext = options.toolContext ?? null;\r\n this.historyRecorder = options.historyRecorder ?? null;\r\n this.historyStack = options.historyStack ?? null;\r\n this.element.style.touchAction = 'none';\r\n this.bind();\r\n }\r\n\r\n setToolManager(toolManager: ToolManager, toolContext: ToolContext): void {\r\n this.toolManager = toolManager;\r\n this.toolContext = toolContext;\r\n }\r\n\r\n destroy(): void {\r\n this.abortController.abort();\r\n }\r\n\r\n private bind(): void {\r\n const opts = { signal: this.abortController.signal };\r\n\r\n this.element.addEventListener('wheel', this.onWheel, { ...opts, passive: false });\r\n this.element.addEventListener('pointerdown', this.onPointerDown, opts);\r\n this.element.addEventListener('pointermove', this.onPointerMove, opts);\r\n this.element.addEventListener('pointerup', this.onPointerUp, opts);\r\n this.element.addEventListener('pointerleave', this.onPointerUp, opts);\r\n this.element.addEventListener('pointercancel', this.onPointerUp, opts);\r\n window.addEventListener('keydown', this.onKeyDown, opts);\r\n window.addEventListener('keyup', this.onKeyUp, opts);\r\n }\r\n\r\n private onWheel = (e: WheelEvent): void => {\r\n e.preventDefault();\r\n const rect = this.element.getBoundingClientRect();\r\n const zoomFactor = 1 - e.deltaY * ZOOM_SENSITIVITY;\r\n const newZoom = this.camera.zoom * zoomFactor;\r\n this.camera.zoomAt(newZoom, {\r\n x: e.clientX - rect.left,\r\n y: e.clientY - rect.top,\r\n });\r\n };\r\n\r\n private onPointerDown = (e: PointerEvent): void => {\r\n this.activePointers.set(e.pointerId, { x: e.clientX, y: e.clientY });\r\n\r\n this.element.setPointerCapture?.(e.pointerId);\r\n\r\n if (this.activePointers.size === 2) {\r\n this.startPinch();\r\n this.cancelToolIfActive(e);\r\n return;\r\n }\r\n\r\n if (e.button === MIDDLE_BUTTON || (e.button === 0 && this.spaceHeld)) {\r\n this.isPanning = true;\r\n this.lastPointer = { x: e.clientX, y: e.clientY };\r\n return;\r\n }\r\n\r\n if (this.activePointers.size === 1 && e.button === 0) {\r\n this.dispatchToolDown(e);\r\n }\r\n };\r\n\r\n private onPointerMove = (e: PointerEvent): void => {\r\n if (this.activePointers.has(e.pointerId)) {\r\n this.activePointers.set(e.pointerId, { x: e.clientX, y: e.clientY });\r\n }\r\n\r\n if (this.activePointers.size === 2) {\r\n this.handlePinchMove();\r\n return;\r\n }\r\n\r\n if (this.isPanning) {\r\n const dx = e.clientX - this.lastPointer.x;\r\n const dy = e.clientY - this.lastPointer.y;\r\n this.lastPointer = { x: e.clientX, y: e.clientY };\r\n this.camera.pan(dx, dy);\r\n return;\r\n }\r\n\r\n if (this.isToolActive) {\r\n this.dispatchToolMove(e);\r\n } else if (this.activePointers.size === 0) {\r\n this.dispatchToolHover(e);\r\n }\r\n };\r\n\r\n private onPointerUp = (e: PointerEvent): void => {\r\n this.activePointers.delete(e.pointerId);\r\n\r\n if (this.activePointers.size < 2) {\r\n this.lastPinchDistance = 0;\r\n }\r\n\r\n if (this.isPanning && this.activePointers.size === 0) {\r\n this.isPanning = false;\r\n }\r\n\r\n if (this.isToolActive) {\r\n this.dispatchToolUp(e);\r\n this.isToolActive = false;\r\n }\r\n };\r\n\r\n private onKeyDown = (e: KeyboardEvent): void => {\r\n if ((e.target as HTMLElement)?.isContentEditable) return;\r\n\r\n if (e.key === ' ') {\r\n this.spaceHeld = true;\r\n }\r\n if (e.key === 'Delete' || e.key === 'Backspace') {\r\n this.deleteSelected();\r\n }\r\n if ((e.ctrlKey || e.metaKey) && e.key === 'z' && !e.shiftKey) {\r\n e.preventDefault();\r\n this.handleUndo();\r\n }\r\n if ((e.ctrlKey || e.metaKey) && (e.key === 'y' || (e.key === 'z' && e.shiftKey))) {\r\n e.preventDefault();\r\n this.handleRedo();\r\n }\r\n };\r\n\r\n private onKeyUp = (e: KeyboardEvent): void => {\r\n if (e.key === ' ') {\r\n this.spaceHeld = false;\r\n }\r\n };\r\n\r\n private startPinch(): void {\r\n this.isPanning = true;\r\n const [a, b] = this.getPinchPoints();\r\n this.lastPinchDistance = this.distance(a, b);\r\n this.lastPinchCenter = this.midpoint(a, b);\r\n this.lastPointer = { ...this.lastPinchCenter };\r\n }\r\n\r\n private handlePinchMove(): void {\r\n const [a, b] = this.getPinchPoints();\r\n const dist = this.distance(a, b);\r\n const center = this.midpoint(a, b);\r\n\r\n if (this.lastPinchDistance > 0) {\r\n const scale = dist / this.lastPinchDistance;\r\n const newZoom = this.camera.zoom * scale;\r\n this.camera.zoomAt(newZoom, center);\r\n }\r\n\r\n const dx = center.x - this.lastPointer.x;\r\n const dy = center.y - this.lastPointer.y;\r\n this.camera.pan(dx, dy);\r\n\r\n this.lastPinchDistance = dist;\r\n this.lastPinchCenter = center;\r\n this.lastPointer = { ...center };\r\n }\r\n\r\n private getPinchPoints(): [{ x: number; y: number }, { x: number; y: number }] {\r\n const pts = [...this.activePointers.values()];\r\n return [pts[0] ?? { x: 0, y: 0 }, pts[1] ?? { x: 0, y: 0 }];\r\n }\r\n\r\n private distance(a: { x: number; y: number }, b: { x: number; y: number }): number {\r\n const dx = a.x - b.x;\r\n const dy = a.y - b.y;\r\n return Math.sqrt(dx * dx + dy * dy);\r\n }\r\n\r\n private midpoint(\r\n a: { x: number; y: number },\r\n b: { x: number; y: number },\r\n ): { x: number; y: number } {\r\n return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\r\n }\r\n\r\n private toPointerState(e: PointerEvent): PointerState {\r\n const rect = this.element.getBoundingClientRect();\r\n return {\r\n x: e.clientX - rect.left,\r\n y: e.clientY - rect.top,\r\n pressure: e.pressure,\r\n };\r\n }\r\n\r\n private dispatchToolDown(e: PointerEvent): void {\r\n if (!this.toolManager || !this.toolContext) return;\r\n this.historyRecorder?.begin();\r\n this.isToolActive = true;\r\n this.toolManager.handlePointerDown(this.toPointerState(e), this.toolContext);\r\n }\r\n\r\n private dispatchToolMove(e: PointerEvent): void {\r\n if (!this.toolManager || !this.toolContext) return;\r\n this.toolManager.handlePointerMove(this.toPointerState(e), this.toolContext);\r\n }\r\n\r\n private dispatchToolHover(e: PointerEvent): void {\r\n if (!this.toolManager?.activeTool || !this.toolContext) return;\r\n const tool = this.toolManager.activeTool;\r\n if (tool.onHover) {\r\n tool.onHover(this.toPointerState(e), this.toolContext);\r\n }\r\n }\r\n\r\n private dispatchToolUp(e: PointerEvent): void {\r\n if (!this.toolManager || !this.toolContext) return;\r\n this.toolManager.handlePointerUp(this.toPointerState(e), this.toolContext);\r\n this.historyRecorder?.commit();\r\n }\r\n\r\n private deleteSelected(): void {\r\n if (!this.toolManager || !this.toolContext) return;\r\n const tool = this.toolManager.activeTool;\r\n if (tool?.name !== 'select') return;\r\n const selectTool = tool as SelectTool;\r\n const ids = selectTool.selectedIds;\r\n if (ids.length === 0) return;\r\n this.historyRecorder?.begin();\r\n for (const id of ids) {\r\n this.toolContext.store.remove(id);\r\n }\r\n this.historyRecorder?.commit();\r\n this.toolContext.requestRender();\r\n }\r\n\r\n private handleUndo(): void {\r\n if (!this.historyStack || !this.toolContext) return;\r\n this.historyRecorder?.pause();\r\n this.historyStack.undo(this.toolContext.store);\r\n this.historyRecorder?.resume();\r\n this.toolContext.requestRender();\r\n }\r\n\r\n private handleRedo(): void {\r\n if (!this.historyStack || !this.toolContext) return;\r\n this.historyRecorder?.pause();\r\n this.historyStack.redo(this.toolContext.store);\r\n this.historyRecorder?.resume();\r\n this.toolContext.requestRender();\r\n }\r\n\r\n private cancelToolIfActive(e: PointerEvent): void {\r\n if (this.isToolActive) {\r\n this.dispatchToolUp(e);\r\n this.isToolActive = false;\r\n }\r\n }\r\n}\r\n","import { EventBus } from '../core/event-bus';\r\nimport type { CanvasElement, ElementType } from './types';\r\n\r\nexport interface ElementUpdateEvent {\r\n previous: CanvasElement;\r\n current: CanvasElement;\r\n}\r\n\r\ninterface ElementStoreEvents {\r\n add: CanvasElement;\r\n remove: CanvasElement;\r\n update: ElementUpdateEvent;\r\n clear: null;\r\n}\r\n\r\nexport class ElementStore {\r\n private elements = new Map<string, CanvasElement>();\r\n private bus = new EventBus<ElementStoreEvents>();\r\n private layerOrderMap = new Map<string, number>();\r\n\r\n get count(): number {\r\n return this.elements.size;\r\n }\r\n\r\n setLayerOrder(order: Map<string, number>): void {\r\n this.layerOrderMap = new Map(order);\r\n }\r\n\r\n getAll(): CanvasElement[] {\r\n return [...this.elements.values()].sort((a, b) => {\r\n const layerA = this.layerOrderMap.get(a.layerId) ?? 0;\r\n const layerB = this.layerOrderMap.get(b.layerId) ?? 0;\r\n if (layerA !== layerB) return layerA - layerB;\r\n return a.zIndex - b.zIndex;\r\n });\r\n }\r\n\r\n getById(id: string): CanvasElement | undefined {\r\n return this.elements.get(id);\r\n }\r\n\r\n getElementsByType<T extends ElementType>(type: T): Extract<CanvasElement, { type: T }>[] {\r\n return this.getAll().filter(\r\n (el): el is Extract<CanvasElement, { type: T }> => el.type === type,\r\n );\r\n }\r\n\r\n add(element: CanvasElement): void {\r\n this.elements.set(element.id, element);\r\n this.bus.emit('add', element);\r\n }\r\n\r\n update(id: string, partial: Partial<CanvasElement>): void {\r\n const existing = this.elements.get(id);\r\n if (!existing) return;\r\n\r\n const updated = { ...existing, ...partial, id: existing.id, type: existing.type };\r\n this.elements.set(id, updated as CanvasElement);\r\n this.bus.emit('update', { previous: existing, current: updated as CanvasElement });\r\n }\r\n\r\n remove(id: string): void {\r\n const element = this.elements.get(id);\r\n if (!element) return;\r\n\r\n this.elements.delete(id);\r\n this.bus.emit('remove', element);\r\n }\r\n\r\n clear(): void {\r\n this.elements.clear();\r\n this.bus.emit('clear', null);\r\n }\r\n\r\n snapshot(): CanvasElement[] {\r\n return this.getAll().map((el) => ({ ...el }));\r\n }\r\n\r\n loadSnapshot(elements: CanvasElement[]): void {\r\n this.elements.clear();\r\n for (const el of elements) {\r\n this.elements.set(el.id, el);\r\n }\r\n }\r\n\r\n on<K extends keyof ElementStoreEvents>(\r\n event: K,\r\n listener: (data: ElementStoreEvents[K]) => void,\r\n ): () => void {\r\n return this.bus.on(event, listener);\r\n }\r\n}\r\n","import type { Point } from '../core/types';\r\n\r\nexport interface Rect {\r\n x: number;\r\n y: number;\r\n w: number;\r\n h: number;\r\n}\r\n\r\nexport function getArrowControlPoint(from: Point, to: Point, bend: number): Point {\r\n const midX = (from.x + to.x) / 2;\r\n const midY = (from.y + to.y) / 2;\r\n\r\n if (bend === 0) return { x: midX, y: midY };\r\n\r\n const dx = to.x - from.x;\r\n const dy = to.y - from.y;\r\n const len = Math.sqrt(dx * dx + dy * dy);\r\n\r\n if (len === 0) return { x: midX, y: midY };\r\n\r\n const perpX = -dy / len;\r\n const perpY = dx / len;\r\n\r\n return {\r\n x: midX + perpX * bend,\r\n y: midY + perpY * bend,\r\n };\r\n}\r\n\r\nexport function getArrowMidpoint(from: Point, to: Point, bend: number): Point {\r\n const cp = getArrowControlPoint(from, to, bend);\r\n return {\r\n x: 0.25 * from.x + 0.5 * cp.x + 0.25 * to.x,\r\n y: 0.25 * from.y + 0.5 * cp.y + 0.25 * to.y,\r\n };\r\n}\r\n\r\nexport function getBendFromPoint(from: Point, to: Point, dragPoint: Point): number {\r\n const midX = (from.x + to.x) / 2;\r\n const midY = (from.y + to.y) / 2;\r\n\r\n const dx = to.x - from.x;\r\n const dy = to.y - from.y;\r\n const len = Math.sqrt(dx * dx + dy * dy);\r\n\r\n if (len === 0) return 0;\r\n\r\n const perpX = -dy / len;\r\n const perpY = dx / len;\r\n\r\n return (dragPoint.x - midX) * perpX + (dragPoint.y - midY) * perpY;\r\n}\r\n\r\nexport function getArrowTangentAngle(from: Point, to: Point, bend: number, t: number): number {\r\n const cp = getArrowControlPoint(from, to, bend);\r\n\r\n const tangentX = 2 * (1 - t) * (cp.x - from.x) + 2 * t * (to.x - cp.x);\r\n const tangentY = 2 * (1 - t) * (cp.y - from.y) + 2 * t * (to.y - cp.y);\r\n\r\n return Math.atan2(tangentY, tangentX);\r\n}\r\n\r\nexport function isNearBezier(\r\n point: Point,\r\n from: Point,\r\n to: Point,\r\n bend: number,\r\n threshold: number,\r\n): boolean {\r\n if (bend === 0) return isNearLine(point, from, to, threshold);\r\n\r\n const cp = getArrowControlPoint(from, to, bend);\r\n const segments = 20;\r\n\r\n for (let i = 0; i < segments; i++) {\r\n const t0 = i / segments;\r\n const t1 = (i + 1) / segments;\r\n const a = bezierPoint(from, cp, to, t0);\r\n const b = bezierPoint(from, cp, to, t1);\r\n if (isNearLine(point, a, b, threshold)) return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function getArrowBounds(from: Point, to: Point, bend: number): Rect {\r\n if (bend === 0) {\r\n const minX = Math.min(from.x, to.x);\r\n const minY = Math.min(from.y, to.y);\r\n return {\r\n x: minX,\r\n y: minY,\r\n w: Math.abs(to.x - from.x),\r\n h: Math.abs(to.y - from.y),\r\n };\r\n }\r\n\r\n const cp = getArrowControlPoint(from, to, bend);\r\n const steps = 20;\r\n let minX = Math.min(from.x, to.x);\r\n let minY = Math.min(from.y, to.y);\r\n let maxX = Math.max(from.x, to.x);\r\n let maxY = Math.max(from.y, to.y);\r\n\r\n for (let i = 1; i < steps; i++) {\r\n const t = i / steps;\r\n const p = bezierPoint(from, cp, to, t);\r\n if (p.x < minX) minX = p.x;\r\n if (p.y < minY) minY = p.y;\r\n if (p.x > maxX) maxX = p.x;\r\n if (p.y > maxY) maxY = p.y;\r\n }\r\n\r\n return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };\r\n}\r\n\r\nfunction bezierPoint(from: Point, cp: Point, to: Point, t: number): Point {\r\n const mt = 1 - t;\r\n return {\r\n x: mt * mt * from.x + 2 * mt * t * cp.x + t * t * to.x,\r\n y: mt * mt * from.y + 2 * mt * t * cp.y + t * t * to.y,\r\n };\r\n}\r\n\r\nfunction isNearLine(point: Point, a: Point, b: Point, threshold: number): boolean {\r\n const dx = b.x - a.x;\r\n const dy = b.y - a.y;\r\n const lenSq = dx * dx + dy * dy;\r\n\r\n if (lenSq === 0) {\r\n return Math.hypot(point.x - a.x, point.y - a.y) <= threshold;\r\n }\r\n\r\n const t = Math.max(0, Math.min(1, ((point.x - a.x) * dx + (point.y - a.y) * dy) / lenSq));\r\n const projX = a.x + t * dx;\r\n const projY = a.y + t * dy;\r\n return Math.hypot(point.x - projX, point.y - projY) <= threshold;\r\n}\r\n","import type { Point } from '../core/types';\r\nimport type { ArrowElement, CanvasElement } from './types';\r\nimport type { ElementStore } from './element-store';\r\nimport { getArrowTangentAngle } from './arrow-geometry';\r\nimport type { Rect } from './arrow-geometry';\r\n\r\nconst BINDABLE_TYPES = new Set(['note', 'text', 'image', 'html', 'shape']);\r\n\r\nexport function isBindable(element: CanvasElement): boolean {\r\n return BINDABLE_TYPES.has(element.type);\r\n}\r\n\r\nexport function getElementCenter(element: CanvasElement): Point {\r\n if (!('size' in element)) {\r\n throw new Error(`getElementCenter: element type \"${element.type}\" has no size`);\r\n }\r\n return {\r\n x: element.position.x + element.size.w / 2,\r\n y: element.position.y + element.size.h / 2,\r\n };\r\n}\r\n\r\nexport function getElementBounds(element: CanvasElement): Rect | null {\r\n if (!('size' in element)) return null;\r\n return {\r\n x: element.position.x,\r\n y: element.position.y,\r\n w: element.size.w,\r\n h: element.size.h,\r\n };\r\n}\r\n\r\nexport function getEdgeIntersection(bounds: Rect, outsidePoint: Point): Point {\r\n const cx = bounds.x + bounds.w / 2;\r\n const cy = bounds.y + bounds.h / 2;\r\n const dx = outsidePoint.x - cx;\r\n const dy = outsidePoint.y - cy;\r\n\r\n if (dx === 0 && dy === 0) return { x: cx, y: cy };\r\n\r\n const halfW = bounds.w / 2;\r\n const halfH = bounds.h / 2;\r\n\r\n const scaleX = dx !== 0 ? halfW / Math.abs(dx) : Infinity;\r\n const scaleY = dy !== 0 ? halfH / Math.abs(dy) : Infinity;\r\n const scale = Math.min(scaleX, scaleY);\r\n\r\n return {\r\n x: cx + dx * scale,\r\n y: cy + dy * scale,\r\n };\r\n}\r\n\r\nexport function findBindTarget(\r\n point: Point,\r\n store: ElementStore,\r\n threshold: number,\r\n excludeId?: string,\r\n filter?: (el: CanvasElement) => boolean,\r\n): CanvasElement | null {\r\n let closest: CanvasElement | null = null;\r\n let closestDist = Infinity;\r\n\r\n for (const el of store.getAll()) {\r\n if (!isBindable(el)) continue;\r\n if (excludeId && el.id === excludeId) continue;\r\n if (filter && !filter(el)) continue;\r\n\r\n const bounds = getElementBounds(el);\r\n if (!bounds) continue;\r\n\r\n const dist = distToBounds(point, bounds);\r\n if (dist <= threshold && dist < closestDist) {\r\n closest = el;\r\n closestDist = dist;\r\n }\r\n }\r\n\r\n return closest;\r\n}\r\n\r\nfunction distToBounds(point: Point, bounds: Rect): number {\r\n const clampedX = Math.max(bounds.x, Math.min(point.x, bounds.x + bounds.w));\r\n const clampedY = Math.max(bounds.y, Math.min(point.y, bounds.y + bounds.h));\r\n return Math.hypot(point.x - clampedX, point.y - clampedY);\r\n}\r\n\r\nexport function findBoundArrows(elementId: string, store: ElementStore): ArrowElement[] {\r\n return store\r\n .getElementsByType('arrow')\r\n .filter((a) => a.fromBinding?.elementId === elementId || a.toBinding?.elementId === elementId);\r\n}\r\n\r\nexport function updateBoundArrow(\r\n arrow: ArrowElement,\r\n store: ElementStore,\r\n): Partial<ArrowElement> | null {\r\n if (!arrow.fromBinding && !arrow.toBinding) return null;\r\n\r\n const updates: Partial<ArrowElement> = {};\r\n\r\n if (arrow.fromBinding) {\r\n const el = store.getById(arrow.fromBinding.elementId);\r\n if (el) {\r\n const center = getElementCenter(el);\r\n updates.from = center;\r\n updates.position = center;\r\n }\r\n }\r\n\r\n if (arrow.toBinding) {\r\n const el = store.getById(arrow.toBinding.elementId);\r\n if (el) {\r\n updates.to = getElementCenter(el);\r\n }\r\n }\r\n\r\n return Object.keys(updates).length > 0 ? updates : null;\r\n}\r\n\r\nexport function clearStaleBindings(\r\n arrow: ArrowElement,\r\n store: ElementStore,\r\n): Partial<ArrowElement> | null {\r\n const updates: Partial<ArrowElement> = {};\r\n let hasUpdates = false;\r\n\r\n if (arrow.fromBinding && !store.getById(arrow.fromBinding.elementId)) {\r\n updates.fromBinding = undefined;\r\n hasUpdates = true;\r\n }\r\n\r\n if (arrow.toBinding && !store.getById(arrow.toBinding.elementId)) {\r\n updates.toBinding = undefined;\r\n hasUpdates = true;\r\n }\r\n\r\n return hasUpdates ? updates : null;\r\n}\r\n\r\nexport function unbindArrow(arrow: ArrowElement, store: ElementStore): Partial<ArrowElement> {\r\n const updates: Partial<ArrowElement> = {};\r\n\r\n if (arrow.fromBinding) {\r\n const el = store.getById(arrow.fromBinding.elementId);\r\n const bounds = el ? getElementBounds(el) : null;\r\n if (bounds) {\r\n const angle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 0);\r\n const rayTarget = {\r\n x: arrow.from.x + Math.cos(angle) * 1000,\r\n y: arrow.from.y + Math.sin(angle) * 1000,\r\n };\r\n const edge = getEdgeIntersection(bounds, rayTarget);\r\n updates.from = edge;\r\n updates.position = edge;\r\n }\r\n updates.fromBinding = undefined;\r\n }\r\n\r\n if (arrow.toBinding) {\r\n const el = store.getById(arrow.toBinding.elementId);\r\n const bounds = el ? getElementBounds(el) : null;\r\n if (bounds) {\r\n const angle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 1);\r\n // Reverse tangent direction — tangent at t=1 points away from curve body\r\n const rayTarget = {\r\n x: arrow.to.x - Math.cos(angle) * 1000,\r\n y: arrow.to.y - Math.sin(angle) * 1000,\r\n };\r\n updates.to = getEdgeIntersection(bounds, rayTarget);\r\n }\r\n updates.toBinding = undefined;\r\n }\r\n\r\n return updates;\r\n}\r\n","import type { Point, StrokePoint } from '../core/types';\r\n\r\nexport interface CurveSegment {\r\n start: StrokePoint;\r\n cp1: Point;\r\n cp2: Point;\r\n end: StrokePoint;\r\n}\r\n\r\nconst MIN_PRESSURE_SCALE = 0.2;\r\n\r\nexport function pressureToWidth(pressure: number, baseWidth: number): number {\r\n return baseWidth * (MIN_PRESSURE_SCALE + (1 - MIN_PRESSURE_SCALE) * pressure);\r\n}\r\n\r\nexport function simplifyPoints(points: StrokePoint[], tolerance: number): StrokePoint[] {\r\n if (points.length <= 2) return points.slice();\r\n return rdp(points, 0, points.length - 1, tolerance);\r\n}\r\n\r\nfunction rdp(points: StrokePoint[], start: number, end: number, tolerance: number): StrokePoint[] {\r\n const first = points[start];\r\n const last = points[end];\r\n if (!first || !last) return [];\r\n\r\n if (end - start <= 1) return [first, last];\r\n\r\n let maxDist = 0;\r\n let maxIndex = start;\r\n\r\n for (let i = start + 1; i < end; i++) {\r\n const pt = points[i];\r\n if (!pt) continue;\r\n const dist = perpendicularDistance(pt, first, last);\r\n if (dist > maxDist) {\r\n maxDist = dist;\r\n maxIndex = i;\r\n }\r\n }\r\n\r\n if (maxDist <= tolerance) return [first, last];\r\n\r\n const left = rdp(points, start, maxIndex, tolerance);\r\n const right = rdp(points, maxIndex, end, tolerance);\r\n\r\n return left.concat(right.slice(1));\r\n}\r\n\r\nfunction perpendicularDistance(pt: Point, lineStart: Point, lineEnd: Point): number {\r\n const dx = lineEnd.x - lineStart.x;\r\n const dy = lineEnd.y - lineStart.y;\r\n const lenSq = dx * dx + dy * dy;\r\n\r\n if (lenSq === 0) {\r\n const ex = pt.x - lineStart.x;\r\n const ey = pt.y - lineStart.y;\r\n return Math.sqrt(ex * ex + ey * ey);\r\n }\r\n\r\n const num = Math.abs(dy * pt.x - dx * pt.y + lineEnd.x * lineStart.y - lineEnd.y * lineStart.x);\r\n return num / Math.sqrt(lenSq);\r\n}\r\n\r\nexport function smoothToSegments(points: StrokePoint[]): CurveSegment[] {\r\n if (points.length < 2) return [];\r\n\r\n if (points.length === 2) {\r\n const p0 = points[0];\r\n const p1 = points[1];\r\n if (!p0 || !p1) return [];\r\n const mx = (p0.x + p1.x) / 2;\r\n const my = (p0.y + p1.y) / 2;\r\n return [{ start: p0, cp1: { x: mx, y: my }, cp2: { x: mx, y: my }, end: p1 }];\r\n }\r\n\r\n const segments: CurveSegment[] = [];\r\n const n = points.length;\r\n\r\n for (let i = 0; i < n - 1; i++) {\r\n const p0 = points[Math.max(0, i - 1)];\r\n const p1 = points[i];\r\n const p2 = points[i + 1];\r\n const p3 = points[Math.min(n - 1, i + 2)];\r\n if (!p0 || !p1 || !p2 || !p3) continue;\r\n\r\n const cp1: Point = {\r\n x: p1.x + (p2.x - p0.x) / 6,\r\n y: p1.y + (p2.y - p0.y) / 6,\r\n };\r\n const cp2: Point = {\r\n x: p2.x - (p3.x - p1.x) / 6,\r\n y: p2.y - (p3.y - p1.y) / 6,\r\n };\r\n\r\n segments.push({ start: p1, cp1, cp2, end: p2 });\r\n }\r\n\r\n return segments;\r\n}\r\n","import type { HexOrientation } from './types';\r\n\r\nexport interface VisibleBounds {\r\n minX: number;\r\n minY: number;\r\n maxX: number;\r\n maxY: number;\r\n}\r\n\r\nexport interface SquareGridLines {\r\n verticals: number[];\r\n horizontals: number[];\r\n}\r\n\r\nexport function getSquareGridLines(bounds: VisibleBounds, cellSize: number): SquareGridLines {\r\n if (cellSize <= 0) return { verticals: [], horizontals: [] };\r\n\r\n const verticals: number[] = [];\r\n const startX = Math.floor(bounds.minX / cellSize) * cellSize;\r\n const endX = Math.ceil(bounds.maxX / cellSize) * cellSize;\r\n for (let x = startX; x <= endX; x += cellSize) {\r\n verticals.push(x);\r\n }\r\n\r\n const horizontals: number[] = [];\r\n const startY = Math.floor(bounds.minY / cellSize) * cellSize;\r\n const endY = Math.ceil(bounds.maxY / cellSize) * cellSize;\r\n for (let y = startY; y <= endY; y += cellSize) {\r\n horizontals.push(y);\r\n }\r\n\r\n return { verticals, horizontals };\r\n}\r\n\r\nexport interface HexVertex {\r\n x: number;\r\n y: number;\r\n}\r\n\r\nexport function getHexVertices(\r\n cx: number,\r\n cy: number,\r\n circumradius: number,\r\n orientation: HexOrientation,\r\n): HexVertex[] {\r\n const vertices: HexVertex[] = [];\r\n const angleOffset = orientation === 'pointy' ? -Math.PI / 2 : 0;\r\n for (let i = 0; i < 6; i++) {\r\n const angle = (Math.PI / 3) * i + angleOffset;\r\n vertices.push({\r\n x: cx + circumradius * Math.cos(angle),\r\n y: cy + circumradius * Math.sin(angle),\r\n });\r\n }\r\n return vertices;\r\n}\r\n\r\nexport function getHexCenters(\r\n bounds: VisibleBounds,\r\n circumradius: number,\r\n orientation: HexOrientation,\r\n): HexVertex[] {\r\n if (circumradius <= 0) return [];\r\n\r\n const centers: HexVertex[] = [];\r\n\r\n if (orientation === 'pointy') {\r\n const hexW = Math.sqrt(3) * circumradius;\r\n const hexH = 2 * circumradius;\r\n const rowH = hexH * 0.75;\r\n\r\n const startRow = Math.floor((bounds.minY - circumradius) / rowH);\r\n const endRow = Math.ceil((bounds.maxY + circumradius) / rowH);\r\n const startCol = Math.floor((bounds.minX - hexW) / hexW);\r\n const endCol = Math.ceil((bounds.maxX + hexW) / hexW);\r\n\r\n for (let row = startRow; row <= endRow; row++) {\r\n const offsetX = row % 2 !== 0 ? hexW / 2 : 0;\r\n for (let col = startCol; col <= endCol; col++) {\r\n centers.push({\r\n x: col * hexW + offsetX,\r\n y: row * rowH,\r\n });\r\n }\r\n }\r\n } else {\r\n const hexW = 2 * circumradius;\r\n const hexH = Math.sqrt(3) * circumradius;\r\n const colW = hexW * 0.75;\r\n\r\n const startCol = Math.floor((bounds.minX - circumradius) / colW);\r\n const endCol = Math.ceil((bounds.maxX + circumradius) / colW);\r\n const startRow = Math.floor((bounds.minY - hexH) / hexH);\r\n const endRow = Math.ceil((bounds.maxY + hexH) / hexH);\r\n\r\n for (let col = startCol; col <= endCol; col++) {\r\n const offsetY = col % 2 !== 0 ? hexH / 2 : 0;\r\n for (let row = startRow; row <= endRow; row++) {\r\n centers.push({\r\n x: col * colW,\r\n y: row * hexH + offsetY,\r\n });\r\n }\r\n }\r\n }\r\n\r\n return centers;\r\n}\r\n\r\nexport function renderSquareGrid(\r\n ctx: CanvasRenderingContext2D,\r\n bounds: VisibleBounds,\r\n cellSize: number,\r\n strokeColor: string,\r\n strokeWidth: number,\r\n opacity: number,\r\n): void {\r\n if (cellSize <= 0) return;\r\n\r\n const { verticals, horizontals } = getSquareGridLines(bounds, cellSize);\r\n\r\n ctx.save();\r\n ctx.strokeStyle = strokeColor;\r\n ctx.lineWidth = strokeWidth;\r\n ctx.globalAlpha = opacity;\r\n ctx.beginPath();\r\n\r\n for (const x of verticals) {\r\n ctx.moveTo(x, bounds.minY);\r\n ctx.lineTo(x, bounds.maxY);\r\n }\r\n for (const y of horizontals) {\r\n ctx.moveTo(bounds.minX, y);\r\n ctx.lineTo(bounds.maxX, y);\r\n }\r\n\r\n ctx.stroke();\r\n ctx.restore();\r\n}\r\n\r\nexport function renderHexGrid(\r\n ctx: CanvasRenderingContext2D,\r\n bounds: VisibleBounds,\r\n cellSize: number,\r\n orientation: HexOrientation,\r\n strokeColor: string,\r\n strokeWidth: number,\r\n opacity: number,\r\n): void {\r\n if (cellSize <= 0) return;\r\n\r\n const centers = getHexCenters(bounds, cellSize, orientation);\r\n\r\n ctx.save();\r\n ctx.strokeStyle = strokeColor;\r\n ctx.lineWidth = strokeWidth;\r\n ctx.globalAlpha = opacity;\r\n ctx.beginPath();\r\n\r\n for (const center of centers) {\r\n const verts = getHexVertices(center.x, center.y, cellSize, orientation);\r\n const first = verts[0];\r\n if (!first) continue;\r\n ctx.moveTo(first.x, first.y);\r\n for (let i = 1; i < verts.length; i++) {\r\n const v = verts[i];\r\n if (!v) continue;\r\n ctx.lineTo(v.x, v.y);\r\n }\r\n ctx.closePath();\r\n }\r\n\r\n ctx.stroke();\r\n ctx.restore();\r\n}\r\n","import type {\r\n CanvasElement,\r\n StrokeElement,\r\n ArrowElement,\r\n ShapeElement,\r\n ImageElement,\r\n GridElement,\r\n} from './types';\r\nimport { getArrowControlPoint, getArrowTangentAngle } from './arrow-geometry';\r\nimport { getElementBounds, getEdgeIntersection } from './arrow-binding';\r\nimport { smoothToSegments, pressureToWidth } from './stroke-smoothing';\r\nimport type { ElementStore } from './element-store';\r\nimport { renderSquareGrid, renderHexGrid } from './grid-renderer';\r\nimport type { Camera } from '../canvas/camera';\r\n\r\nconst DOM_ELEMENT_TYPES = new Set(['note', 'html', 'text']);\r\nconst ARROWHEAD_LENGTH = 12;\r\nconst ARROWHEAD_ANGLE = Math.PI / 6;\r\n\r\nexport class ElementRenderer {\r\n private store: ElementStore | null = null;\r\n private imageCache = new Map<string, HTMLImageElement>();\r\n private onImageLoad: (() => void) | null = null;\r\n private camera: Camera | null = null;\r\n private canvasSize: { w: number; h: number } | null = null;\r\n\r\n setStore(store: ElementStore): void {\r\n this.store = store;\r\n }\r\n\r\n setOnImageLoad(callback: () => void): void {\r\n this.onImageLoad = callback;\r\n }\r\n\r\n setCamera(camera: Camera): void {\r\n this.camera = camera;\r\n }\r\n\r\n setCanvasSize(w: number, h: number): void {\r\n this.canvasSize = { w, h };\r\n }\r\n\r\n isDomElement(element: CanvasElement): boolean {\r\n return DOM_ELEMENT_TYPES.has(element.type);\r\n }\r\n\r\n renderCanvasElement(ctx: CanvasRenderingContext2D, element: CanvasElement): void {\r\n switch (element.type) {\r\n case 'stroke':\r\n this.renderStroke(ctx, element);\r\n break;\r\n case 'arrow':\r\n this.renderArrow(ctx, element);\r\n break;\r\n case 'shape':\r\n this.renderShape(ctx, element);\r\n break;\r\n case 'image':\r\n this.renderImage(ctx, element);\r\n break;\r\n case 'grid':\r\n this.renderGrid(ctx, element);\r\n break;\r\n }\r\n }\r\n\r\n private renderStroke(ctx: CanvasRenderingContext2D, stroke: StrokeElement): void {\r\n if (stroke.points.length < 2) return;\r\n\r\n ctx.save();\r\n ctx.translate(stroke.position.x, stroke.position.y);\r\n ctx.strokeStyle = stroke.color;\r\n ctx.lineCap = 'round';\r\n ctx.lineJoin = 'round';\r\n ctx.globalAlpha = stroke.opacity;\r\n\r\n const segments = smoothToSegments(stroke.points);\r\n for (const seg of segments) {\r\n const w =\r\n (pressureToWidth(seg.start.pressure, stroke.width) +\r\n pressureToWidth(seg.end.pressure, stroke.width)) /\r\n 2;\r\n ctx.lineWidth = w;\r\n ctx.beginPath();\r\n ctx.moveTo(seg.start.x, seg.start.y);\r\n ctx.bezierCurveTo(seg.cp1.x, seg.cp1.y, seg.cp2.x, seg.cp2.y, seg.end.x, seg.end.y);\r\n ctx.stroke();\r\n }\r\n\r\n ctx.restore();\r\n }\r\n\r\n private renderArrow(ctx: CanvasRenderingContext2D, arrow: ArrowElement): void {\r\n const { visualFrom, visualTo } = this.getVisualEndpoints(arrow);\r\n\r\n ctx.save();\r\n ctx.strokeStyle = arrow.color;\r\n ctx.lineWidth = arrow.width;\r\n ctx.lineCap = 'round';\r\n\r\n if (arrow.fromBinding || arrow.toBinding) {\r\n ctx.setLineDash([8, 4]);\r\n }\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(visualFrom.x, visualFrom.y);\r\n\r\n if (arrow.bend !== 0) {\r\n const cp = getArrowControlPoint(arrow.from, arrow.to, arrow.bend);\r\n ctx.quadraticCurveTo(cp.x, cp.y, visualTo.x, visualTo.y);\r\n } else {\r\n ctx.lineTo(visualTo.x, visualTo.y);\r\n }\r\n ctx.stroke();\r\n\r\n this.renderArrowhead(ctx, arrow, visualTo);\r\n ctx.restore();\r\n }\r\n\r\n private renderArrowhead(\r\n ctx: CanvasRenderingContext2D,\r\n arrow: ArrowElement,\r\n tip: { x: number; y: number },\r\n ): void {\r\n const angle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 1);\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(tip.x, tip.y);\r\n ctx.lineTo(\r\n tip.x - ARROWHEAD_LENGTH * Math.cos(angle - ARROWHEAD_ANGLE),\r\n tip.y - ARROWHEAD_LENGTH * Math.sin(angle - ARROWHEAD_ANGLE),\r\n );\r\n ctx.lineTo(\r\n tip.x - ARROWHEAD_LENGTH * Math.cos(angle + ARROWHEAD_ANGLE),\r\n tip.y - ARROWHEAD_LENGTH * Math.sin(angle + ARROWHEAD_ANGLE),\r\n );\r\n ctx.closePath();\r\n ctx.fillStyle = arrow.color;\r\n ctx.fill();\r\n }\r\n\r\n private getVisualEndpoints(arrow: ArrowElement): {\r\n visualFrom: { x: number; y: number };\r\n visualTo: { x: number; y: number };\r\n } {\r\n let visualFrom = arrow.from;\r\n let visualTo = arrow.to;\r\n\r\n if (!this.store) return { visualFrom, visualTo };\r\n\r\n if (arrow.fromBinding) {\r\n const el = this.store.getById(arrow.fromBinding.elementId);\r\n if (el) {\r\n const bounds = getElementBounds(el);\r\n if (bounds) {\r\n const tangentAngle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 0);\r\n const rayTarget = {\r\n x: arrow.from.x + Math.cos(tangentAngle) * 1000,\r\n y: arrow.from.y + Math.sin(tangentAngle) * 1000,\r\n };\r\n visualFrom = getEdgeIntersection(bounds, rayTarget);\r\n }\r\n }\r\n }\r\n\r\n if (arrow.toBinding) {\r\n const el = this.store.getById(arrow.toBinding.elementId);\r\n if (el) {\r\n const bounds = getElementBounds(el);\r\n if (bounds) {\r\n const tangentAngle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 1);\r\n // Reverse tangent — at t=1 tangent points away from curve body,\r\n // but we need the ray from center back toward the curve\r\n const rayTarget = {\r\n x: arrow.to.x - Math.cos(tangentAngle) * 1000,\r\n y: arrow.to.y - Math.sin(tangentAngle) * 1000,\r\n };\r\n visualTo = getEdgeIntersection(bounds, rayTarget);\r\n }\r\n }\r\n }\r\n\r\n return { visualFrom, visualTo };\r\n }\r\n\r\n private renderShape(ctx: CanvasRenderingContext2D, shape: ShapeElement): void {\r\n ctx.save();\r\n\r\n if (shape.fillColor !== 'none') {\r\n ctx.fillStyle = shape.fillColor;\r\n this.fillShapePath(ctx, shape);\r\n }\r\n\r\n if (shape.strokeWidth > 0) {\r\n ctx.strokeStyle = shape.strokeColor;\r\n ctx.lineWidth = shape.strokeWidth;\r\n this.strokeShapePath(ctx, shape);\r\n }\r\n\r\n ctx.restore();\r\n }\r\n\r\n private fillShapePath(ctx: CanvasRenderingContext2D, shape: ShapeElement): void {\r\n switch (shape.shape) {\r\n case 'rectangle':\r\n ctx.fillRect(shape.position.x, shape.position.y, shape.size.w, shape.size.h);\r\n break;\r\n case 'ellipse': {\r\n const cx = shape.position.x + shape.size.w / 2;\r\n const cy = shape.position.y + shape.size.h / 2;\r\n ctx.beginPath();\r\n ctx.ellipse(cx, cy, shape.size.w / 2, shape.size.h / 2, 0, 0, Math.PI * 2);\r\n ctx.fill();\r\n break;\r\n }\r\n }\r\n }\r\n\r\n private strokeShapePath(ctx: CanvasRenderingContext2D, shape: ShapeElement): void {\r\n switch (shape.shape) {\r\n case 'rectangle':\r\n ctx.strokeRect(shape.position.x, shape.position.y, shape.size.w, shape.size.h);\r\n break;\r\n case 'ellipse': {\r\n const cx = shape.position.x + shape.size.w / 2;\r\n const cy = shape.position.y + shape.size.h / 2;\r\n ctx.beginPath();\r\n ctx.ellipse(cx, cy, shape.size.w / 2, shape.size.h / 2, 0, 0, Math.PI * 2);\r\n ctx.stroke();\r\n break;\r\n }\r\n }\r\n }\r\n\r\n private renderGrid(ctx: CanvasRenderingContext2D, grid: GridElement): void {\r\n if (!this.canvasSize) return;\r\n\r\n const cam = this.camera;\r\n if (!cam) return;\r\n\r\n const topLeft = cam.screenToWorld({ x: 0, y: 0 });\r\n const bottomRight = cam.screenToWorld({\r\n x: this.canvasSize.w,\r\n y: this.canvasSize.h,\r\n });\r\n const bounds = {\r\n minX: topLeft.x,\r\n minY: topLeft.y,\r\n maxX: bottomRight.x,\r\n maxY: bottomRight.y,\r\n };\r\n\r\n if (grid.gridType === 'hex') {\r\n renderHexGrid(\r\n ctx,\r\n bounds,\r\n grid.cellSize,\r\n grid.hexOrientation,\r\n grid.strokeColor,\r\n grid.strokeWidth,\r\n grid.opacity,\r\n );\r\n } else {\r\n renderSquareGrid(\r\n ctx,\r\n bounds,\r\n grid.cellSize,\r\n grid.strokeColor,\r\n grid.strokeWidth,\r\n grid.opacity,\r\n );\r\n }\r\n }\r\n\r\n private renderImage(ctx: CanvasRenderingContext2D, image: ImageElement): void {\r\n const img = this.getImage(image.src);\r\n if (!img) return;\r\n ctx.drawImage(img, image.position.x, image.position.y, image.size.w, image.size.h);\r\n }\r\n\r\n private getImage(src: string): HTMLImageElement | null {\r\n const cached = this.imageCache.get(src);\r\n if (cached) return cached.complete ? cached : null;\r\n\r\n const img = new Image();\r\n img.src = src;\r\n this.imageCache.set(src, img);\r\n img.onload = () => this.onImageLoad?.();\r\n return null;\r\n }\r\n}\r\n","import type { ElementStore } from './element-store';\r\n\r\nexport class NoteEditor {\r\n private editingId: string | null = null;\r\n private editingNode: HTMLDivElement | null = null;\r\n private blurHandler: (() => void) | null = null;\r\n private keyHandler: ((e: KeyboardEvent) => void) | null = null;\r\n private pointerHandler: ((e: PointerEvent) => void) | null = null;\r\n private pendingEditId: string | null = null;\r\n private onStopCallback: ((elementId: string) => void) | null = null;\r\n\r\n get isEditing(): boolean {\r\n return this.editingId !== null;\r\n }\r\n\r\n get editingElementId(): string | null {\r\n return this.editingId;\r\n }\r\n\r\n setOnStop(callback: (elementId: string) => void): void {\r\n this.onStopCallback = callback;\r\n }\r\n\r\n startEditing(node: HTMLDivElement, elementId: string, store: ElementStore): void {\r\n if (this.editingId === elementId) return;\r\n\r\n if (this.editingId) {\r\n this.stopEditing(store);\r\n }\r\n\r\n this.pendingEditId = elementId;\r\n\r\n requestAnimationFrame(() => {\r\n if (this.pendingEditId !== elementId) return;\r\n this.pendingEditId = null;\r\n this.activateEditing(node, elementId, store);\r\n });\r\n }\r\n\r\n stopEditing(store: ElementStore): void {\r\n this.pendingEditId = null;\r\n\r\n if (!this.editingId || !this.editingNode) return;\r\n\r\n const text = this.editingNode.textContent ?? '';\r\n store.update(this.editingId, { text });\r\n\r\n this.editingNode.contentEditable = 'false';\r\n Object.assign(this.editingNode.style, {\r\n userSelect: 'none',\r\n cursor: 'default',\r\n });\r\n\r\n if (this.blurHandler) {\r\n this.editingNode.removeEventListener('blur', this.blurHandler);\r\n }\r\n if (this.keyHandler) {\r\n this.editingNode.removeEventListener('keydown', this.keyHandler);\r\n }\r\n if (this.pointerHandler) {\r\n this.editingNode.removeEventListener('pointerdown', this.pointerHandler);\r\n }\r\n\r\n if (this.editingId && this.onStopCallback) {\r\n this.onStopCallback(this.editingId);\r\n }\r\n\r\n this.editingId = null;\r\n this.editingNode = null;\r\n this.blurHandler = null;\r\n this.keyHandler = null;\r\n this.pointerHandler = null;\r\n }\r\n\r\n destroy(store: ElementStore): void {\r\n this.pendingEditId = null;\r\n if (this.isEditing) {\r\n this.stopEditing(store);\r\n }\r\n }\r\n\r\n private activateEditing(node: HTMLDivElement, elementId: string, store: ElementStore): void {\r\n this.editingId = elementId;\r\n this.editingNode = node;\r\n\r\n node.contentEditable = 'true';\r\n Object.assign(node.style, {\r\n userSelect: 'text',\r\n cursor: 'text',\r\n outline: 'none',\r\n });\r\n node.focus();\r\n\r\n const selection = window.getSelection?.();\r\n if (selection) {\r\n const range = document.createRange();\r\n range.selectNodeContents(node);\r\n range.collapse(false);\r\n selection.removeAllRanges();\r\n selection.addRange(range);\r\n }\r\n\r\n this.blurHandler = () => this.stopEditing(store);\r\n this.keyHandler = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n node.blur();\r\n }\r\n e.stopPropagation();\r\n };\r\n this.pointerHandler = (e: PointerEvent) => {\r\n e.stopPropagation();\r\n };\r\n\r\n node.addEventListener('blur', this.blurHandler);\r\n node.addEventListener('keydown', this.keyHandler);\r\n node.addEventListener('pointerdown', this.pointerHandler);\r\n }\r\n}\r\n","import type { Tool, ToolContext, PointerState } from './types';\r\n\r\nexport class ToolManager {\r\n private tools = new Map<string, Tool>();\r\n private current: Tool | null = null;\r\n private changeListeners = new Set<(name: string) => void>();\r\n\r\n get activeTool(): Tool | null {\r\n return this.current;\r\n }\r\n\r\n get toolNames(): string[] {\r\n return [...this.tools.keys()];\r\n }\r\n\r\n register(tool: Tool): void {\r\n this.tools.set(tool.name, tool);\r\n }\r\n\r\n getTool<T extends Tool = Tool>(name: string): T | undefined {\r\n return this.tools.get(name) as T | undefined;\r\n }\r\n\r\n setTool(name: string, ctx: ToolContext): void {\r\n const tool = this.tools.get(name);\r\n if (!tool) return;\r\n\r\n this.current?.onDeactivate?.(ctx);\r\n this.current = tool;\r\n this.current.onActivate?.(ctx);\r\n this.changeListeners.forEach((fn) => fn(name));\r\n }\r\n\r\n handlePointerDown(state: PointerState, ctx: ToolContext): void {\r\n this.current?.onPointerDown(state, ctx);\r\n }\r\n\r\n handlePointerMove(state: PointerState, ctx: ToolContext): void {\r\n this.current?.onPointerMove(state, ctx);\r\n }\r\n\r\n handlePointerUp(state: PointerState, ctx: ToolContext): void {\r\n this.current?.onPointerUp(state, ctx);\r\n }\r\n\r\n onChange(listener: (name: string) => void): () => void {\r\n this.changeListeners.add(listener);\r\n return () => this.changeListeners.delete(listener);\r\n }\r\n}\r\n","import type { ElementStore } from '../elements/element-store';\nimport type { Command } from './types';\n\nexport interface HistoryStackOptions {\n maxSize?: number;\n}\n\nconst DEFAULT_MAX_SIZE = 100;\n\nexport class HistoryStack {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private readonly maxSize: number;\n private changeListeners = new Set<() => void>();\n\n constructor(options: HistoryStackOptions = {}) {\n this.maxSize = options.maxSize ?? DEFAULT_MAX_SIZE;\n }\n\n get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n get undoCount(): number {\n return this.undoStack.length;\n }\n\n get redoCount(): number {\n return this.redoStack.length;\n }\n\n push(command: Command): void {\n this.undoStack.push(command);\n this.redoStack = [];\n\n if (this.undoStack.length > this.maxSize) {\n this.undoStack.shift();\n }\n\n this.notifyChange();\n }\n\n undo(store: ElementStore): boolean {\n const command = this.undoStack.pop();\n if (!command) return false;\n\n command.undo(store);\n this.redoStack.push(command);\n this.notifyChange();\n return true;\n }\n\n redo(store: ElementStore): boolean {\n const command = this.redoStack.pop();\n if (!command) return false;\n\n command.execute(store);\n this.undoStack.push(command);\n this.notifyChange();\n return true;\n }\n\n clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.notifyChange();\n }\n\n onChange(listener: () => void): () => void {\n this.changeListeners.add(listener);\n return () => this.changeListeners.delete(listener);\n }\n\n private notifyChange(): void {\n this.changeListeners.forEach((fn) => fn());\n }\n}\n","import type { CanvasElement } from '../elements/types';\nimport type { ElementStore } from '../elements/element-store';\nimport type { Command } from './types';\n\nexport class AddElementCommand implements Command {\n private readonly element: CanvasElement;\n\n constructor(element: CanvasElement) {\n this.element = { ...element };\n }\n\n execute(store: ElementStore): void {\n store.add(this.element);\n }\n\n undo(store: ElementStore): void {\n store.remove(this.element.id);\n }\n}\n\nexport class RemoveElementCommand implements Command {\n private readonly element: CanvasElement;\n\n constructor(element: CanvasElement) {\n this.element = { ...element };\n }\n\n execute(store: ElementStore): void {\n store.remove(this.element.id);\n }\n\n undo(store: ElementStore): void {\n store.add(this.element);\n }\n}\n\nexport class UpdateElementCommand implements Command {\n constructor(\n private readonly id: string,\n private readonly previous: CanvasElement,\n private readonly current: CanvasElement,\n ) {}\n\n execute(store: ElementStore): void {\n store.update(this.id, { ...this.current });\n }\n\n undo(store: ElementStore): void {\n store.update(this.id, { ...this.previous });\n }\n}\n\nexport class BatchCommand implements Command {\n readonly commands: readonly Command[];\n\n constructor(commands: Command[]) {\n this.commands = [...commands];\n }\n\n execute(store: ElementStore): void {\n for (const cmd of this.commands) {\n cmd.execute(store);\n }\n }\n\n undo(store: ElementStore): void {\n for (let i = this.commands.length - 1; i >= 0; i--) {\n this.commands[i]?.undo(store);\n }\n }\n}\n","import type { ElementStore } from '../elements/element-store';\nimport type { CanvasElement } from '../elements/types';\nimport type { Command } from './types';\nimport type { HistoryStack } from './history-stack';\nimport {\n AddElementCommand,\n RemoveElementCommand,\n UpdateElementCommand,\n BatchCommand,\n} from './commands';\n\nexport class HistoryRecorder {\n private recording = true;\n private transaction: Command[] | null = null;\n private updateSnapshots = new Map<string, CanvasElement>();\n private unsubscribers: (() => void)[];\n\n constructor(\n private readonly store: ElementStore,\n private readonly stack: HistoryStack,\n ) {\n this.unsubscribers = [\n store.on('add', (el) => this.onAdd(el)),\n store.on('remove', (el) => this.onRemove(el)),\n store.on('update', ({ previous, current }) => this.onUpdate(previous, current)),\n ];\n }\n\n pause(): void {\n this.recording = false;\n }\n\n resume(): void {\n this.recording = true;\n }\n\n begin(): void {\n this.transaction = [];\n this.updateSnapshots.clear();\n }\n\n commit(): void {\n if (!this.transaction) return;\n\n const finalCommands = this.flushUpdateSnapshots();\n const all = [...this.transaction, ...finalCommands];\n this.transaction = null;\n this.updateSnapshots.clear();\n\n if (all.length === 0) return;\n const first = all[0];\n this.stack.push(all.length === 1 && first ? first : new BatchCommand(all));\n }\n\n rollback(): void {\n this.transaction = null;\n this.updateSnapshots.clear();\n }\n\n destroy(): void {\n this.unsubscribers.forEach((fn) => fn());\n }\n\n private record(command: Command): void {\n if (this.transaction) {\n this.transaction.push(command);\n } else {\n this.stack.push(command);\n }\n }\n\n private onAdd(element: CanvasElement): void {\n if (!this.recording) return;\n this.record(new AddElementCommand(element));\n }\n\n private onRemove(element: CanvasElement): void {\n if (!this.recording) return;\n\n if (this.transaction && this.updateSnapshots.has(element.id)) {\n this.updateSnapshots.delete(element.id);\n }\n\n this.record(new RemoveElementCommand(element));\n }\n\n private onUpdate(previous: CanvasElement, current: CanvasElement): void {\n if (!this.recording) return;\n\n if (this.transaction) {\n if (!this.updateSnapshots.has(current.id)) {\n this.updateSnapshots.set(current.id, { ...previous });\n }\n } else {\n this.stack.push(new UpdateElementCommand(current.id, previous, current));\n }\n }\n\n private flushUpdateSnapshots(): Command[] {\n const commands: Command[] = [];\n for (const [id, previous] of this.updateSnapshots) {\n const current = this.store.getById(id);\n if (current) {\n commands.push(new UpdateElementCommand(id, previous, current));\n }\n }\n return commands;\n }\n}\n","let counter = 0;\n\nexport function createId(prefix: string): string {\n return `${prefix}_${Date.now().toString(36)}_${(counter++).toString(36)}`;\n}\n","import type { Point, Size, StrokePoint } from '../core/types';\r\nimport type {\r\n Binding,\r\n StrokeElement,\r\n NoteElement,\r\n ArrowElement,\r\n ImageElement,\r\n HtmlElement,\r\n TextElement,\r\n ShapeElement,\r\n ShapeKind,\r\n GridElement,\r\n HexOrientation,\r\n} from './types';\r\nimport { createId } from './create-id';\r\n\r\ninterface BaseDefaults {\r\n position?: Point;\r\n zIndex?: number;\r\n locked?: boolean;\r\n layerId?: string;\r\n}\r\n\r\ninterface StrokeInput extends BaseDefaults {\r\n points: StrokePoint[];\r\n color?: string;\r\n width?: number;\r\n opacity?: number;\r\n}\r\n\r\ninterface NoteInput extends BaseDefaults {\r\n position: Point;\r\n size?: Size;\r\n text?: string;\r\n backgroundColor?: string;\r\n textColor?: string;\r\n}\r\n\r\ninterface ArrowInput extends BaseDefaults {\r\n from: Point;\r\n to: Point;\r\n bend?: number;\r\n color?: string;\r\n width?: number;\r\n fromBinding?: Binding;\r\n toBinding?: Binding;\r\n}\r\n\r\ninterface ImageInput extends BaseDefaults {\r\n position: Point;\r\n size: Size;\r\n src: string;\r\n}\r\n\r\ninterface HtmlInput extends BaseDefaults {\r\n position: Point;\r\n size: Size;\r\n domId?: string;\r\n}\r\n\r\ninterface TextInput extends BaseDefaults {\r\n position: Point;\r\n size?: Size;\r\n text?: string;\r\n fontSize?: number;\r\n color?: string;\r\n textAlign?: 'left' | 'center' | 'right';\r\n}\r\n\r\nexport function createStroke(input: StrokeInput): StrokeElement {\r\n return {\r\n id: createId('stroke'),\r\n type: 'stroke',\r\n position: input.position ?? { x: 0, y: 0 },\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n points: input.points,\r\n color: input.color ?? '#000000',\r\n width: input.width ?? 2,\r\n opacity: input.opacity ?? 1,\r\n };\r\n}\r\n\r\nexport function createNote(input: NoteInput): NoteElement {\r\n return {\r\n id: createId('note'),\r\n type: 'note',\r\n position: input.position,\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n size: input.size ?? { w: 200, h: 100 },\r\n text: input.text ?? '',\r\n backgroundColor: input.backgroundColor ?? '#ffeb3b',\r\n textColor: input.textColor ?? '#000000',\r\n };\r\n}\r\n\r\nexport function createArrow(input: ArrowInput): ArrowElement {\r\n const result: ArrowElement = {\r\n id: createId('arrow'),\r\n type: 'arrow',\r\n position: input.position ?? { x: 0, y: 0 },\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n from: input.from,\r\n to: input.to,\r\n bend: input.bend ?? 0,\r\n color: input.color ?? '#000000',\r\n width: input.width ?? 2,\r\n };\r\n if (input.fromBinding) result.fromBinding = input.fromBinding;\r\n if (input.toBinding) result.toBinding = input.toBinding;\r\n return result;\r\n}\r\n\r\nexport function createImage(input: ImageInput): ImageElement {\r\n return {\r\n id: createId('image'),\r\n type: 'image',\r\n position: input.position,\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n size: input.size,\r\n src: input.src,\r\n };\r\n}\r\n\r\nexport function createHtmlElement(input: HtmlInput): HtmlElement {\r\n const el: HtmlElement = {\r\n id: createId('html'),\r\n type: 'html',\r\n position: input.position,\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n size: input.size,\r\n };\r\n if (input.domId) el.domId = input.domId;\r\n return el;\r\n}\r\n\r\ninterface ShapeInput extends BaseDefaults {\r\n position: Point;\r\n size: Size;\r\n shape?: ShapeKind;\r\n strokeColor?: string;\r\n strokeWidth?: number;\r\n fillColor?: string;\r\n}\r\n\r\nexport function createShape(input: ShapeInput): ShapeElement {\r\n return {\r\n id: createId('shape'),\r\n type: 'shape',\r\n position: input.position,\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n shape: input.shape ?? 'rectangle',\r\n size: input.size,\r\n strokeColor: input.strokeColor ?? '#000000',\r\n strokeWidth: input.strokeWidth ?? 2,\r\n fillColor: input.fillColor ?? 'none',\r\n };\r\n}\r\n\r\ninterface GridInput extends BaseDefaults {\r\n gridType?: 'square' | 'hex';\r\n hexOrientation?: HexOrientation;\r\n cellSize?: number;\r\n strokeColor?: string;\r\n strokeWidth?: number;\r\n opacity?: number;\r\n}\r\n\r\nexport function createGrid(input: GridInput): GridElement {\r\n return {\r\n id: createId('grid'),\r\n type: 'grid',\r\n position: input.position ?? { x: 0, y: 0 },\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n gridType: input.gridType ?? 'square',\r\n hexOrientation: input.hexOrientation ?? 'pointy',\r\n cellSize: input.cellSize ?? 40,\r\n strokeColor: input.strokeColor ?? '#000000',\r\n strokeWidth: input.strokeWidth ?? 1,\r\n opacity: input.opacity ?? 1,\r\n };\r\n}\r\n\r\nexport function createText(input: TextInput): TextElement {\r\n return {\r\n id: createId('text'),\r\n type: 'text',\r\n position: input.position,\r\n zIndex: input.zIndex ?? 0,\r\n locked: input.locked ?? false,\r\n layerId: input.layerId ?? '',\r\n size: input.size ?? { w: 200, h: 28 },\r\n text: input.text ?? '',\r\n fontSize: input.fontSize ?? 16,\r\n color: input.color ?? '#1a1a1a',\r\n textAlign: input.textAlign ?? 'left',\r\n };\r\n}\r\n","import type { CanvasElement, NoteElement, TextElement, GridElement } from '../elements/types';\nimport type { ElementStore } from '../elements/element-store';\nimport { ElementRenderer } from '../elements/element-renderer';\nimport { getArrowBounds } from '../elements/arrow-geometry';\nimport { renderSquareGrid, renderHexGrid } from '../elements/grid-renderer';\nimport type { LayerManager } from '../layers/layer-manager';\n\nexport interface ExportImageOptions {\n scale?: number;\n padding?: number;\n background?: string;\n filter?: (element: CanvasElement) => boolean;\n}\n\ninterface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nfunction getStrokeBounds(el: CanvasElement): Rect | null {\n if (el.type !== 'stroke') return null;\n if (el.points.length === 0) return null;\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const p of el.points) {\n const px = el.position.x + p.x;\n const py = el.position.y + p.y;\n minX = Math.min(minX, px);\n minY = Math.min(minY, py);\n maxX = Math.max(maxX, px);\n maxY = Math.max(maxY, py);\n }\n\n const pad = el.width / 2;\n return {\n x: minX - pad,\n y: minY - pad,\n w: maxX - minX + el.width,\n h: maxY - minY + el.width,\n };\n}\n\nfunction getElementRect(el: CanvasElement): Rect | null {\n switch (el.type) {\n case 'stroke':\n return getStrokeBounds(el);\n case 'arrow': {\n const b = getArrowBounds(el.from, el.to, el.bend);\n const pad = el.width / 2 + 14;\n return { x: b.x - pad, y: b.y - pad, w: b.w + pad * 2, h: b.h + pad * 2 };\n }\n case 'grid':\n return null;\n case 'note':\n case 'image':\n case 'html':\n case 'text':\n case 'shape':\n if ('size' in el) {\n return { x: el.position.x, y: el.position.y, w: el.size.w, h: el.size.h };\n }\n return null;\n default:\n return null;\n }\n}\n\nfunction computeBounds(\n elements: CanvasElement[],\n padding: number,\n): { x: number; y: number; w: number; h: number } | null {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n let found = false;\n\n for (const el of elements) {\n const rect = getElementRect(el);\n if (!rect) continue;\n found = true;\n minX = Math.min(minX, rect.x);\n minY = Math.min(minY, rect.y);\n maxX = Math.max(maxX, rect.x + rect.w);\n maxY = Math.max(maxY, rect.y + rect.h);\n }\n\n if (!found) return null;\n\n return {\n x: minX - padding,\n y: minY - padding,\n w: maxX - minX + padding * 2,\n h: maxY - minY + padding * 2,\n };\n}\n\nfunction renderNoteOnCanvas(ctx: CanvasRenderingContext2D, note: NoteElement): void {\n const { x, y } = note.position;\n const { w, h } = note.size;\n const r = 4;\n const pad = 8;\n\n ctx.save();\n ctx.fillStyle = note.backgroundColor;\n ctx.beginPath();\n ctx.moveTo(x + r, y);\n ctx.lineTo(x + w - r, y);\n ctx.arcTo(x + w, y, x + w, y + r, r);\n ctx.lineTo(x + w, y + h - r);\n ctx.arcTo(x + w, y + h, x + w - r, y + h, r);\n ctx.lineTo(x + r, y + h);\n ctx.arcTo(x, y + h, x, y + h - r, r);\n ctx.lineTo(x, y + r);\n ctx.arcTo(x, y, x + r, y, r);\n ctx.closePath();\n ctx.fill();\n\n if (note.text) {\n ctx.fillStyle = note.textColor;\n ctx.font = '14px system-ui, sans-serif';\n ctx.textBaseline = 'top';\n wrapText(ctx, note.text, x + pad, y + pad, w - pad * 2, 18);\n }\n\n ctx.restore();\n}\n\nfunction renderTextOnCanvas(ctx: CanvasRenderingContext2D, text: TextElement): void {\n if (!text.text) return;\n\n ctx.save();\n ctx.fillStyle = text.color;\n ctx.font = `${text.fontSize}px system-ui, sans-serif`;\n ctx.textBaseline = 'top';\n ctx.textAlign = text.textAlign;\n\n const pad = 2;\n let textX = text.position.x + pad;\n if (text.textAlign === 'center') {\n textX = text.position.x + text.size.w / 2;\n } else if (text.textAlign === 'right') {\n textX = text.position.x + text.size.w - pad;\n }\n\n const lineHeight = text.fontSize * 1.4;\n const lines = text.text.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line !== undefined) {\n ctx.fillText(line, textX, text.position.y + pad + i * lineHeight);\n }\n }\n\n ctx.restore();\n}\n\nfunction wrapText(\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n maxWidth: number,\n lineHeight: number,\n): void {\n const words = text.split(' ');\n let line = '';\n let offsetY = 0;\n\n for (const word of words) {\n const testLine = line ? `${line} ${word}` : word;\n const metrics = ctx.measureText(testLine);\n if (metrics.width > maxWidth && line) {\n ctx.fillText(line, x, y + offsetY);\n line = word;\n offsetY += lineHeight;\n } else {\n line = testLine;\n }\n }\n if (line) {\n ctx.fillText(line, x, y + offsetY);\n }\n}\n\nfunction renderGridForBounds(\n ctx: CanvasRenderingContext2D,\n grid: GridElement,\n bounds: { x: number; y: number; w: number; h: number },\n): void {\n const visibleBounds = {\n minX: bounds.x,\n minY: bounds.y,\n maxX: bounds.x + bounds.w,\n maxY: bounds.y + bounds.h,\n };\n\n if (grid.gridType === 'hex') {\n renderHexGrid(\n ctx,\n visibleBounds,\n grid.cellSize,\n grid.hexOrientation,\n grid.strokeColor,\n grid.strokeWidth,\n grid.opacity,\n );\n } else {\n renderSquareGrid(\n ctx,\n visibleBounds,\n grid.cellSize,\n grid.strokeColor,\n grid.strokeWidth,\n grid.opacity,\n );\n }\n}\n\nfunction loadImages(elements: CanvasElement[]): Promise<Map<string, HTMLImageElement>> {\n const imageElements = elements.filter(\n (el): el is CanvasElement & { src: string } => el.type === 'image' && 'src' in el,\n );\n\n const cache = new Map<string, HTMLImageElement>();\n if (imageElements.length === 0) return Promise.resolve(cache);\n\n return new Promise((resolve) => {\n let remaining = imageElements.length;\n const done = () => {\n remaining--;\n if (remaining <= 0) resolve(cache);\n };\n\n for (const el of imageElements) {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n cache.set(el.id, img);\n done();\n };\n img.onerror = done;\n const sep = el.src.includes('?') ? '&' : '?';\n img.src = `${el.src}${sep}_cors=1`;\n }\n });\n}\n\nexport async function exportImage(\n store: ElementStore,\n options: ExportImageOptions = {},\n layerManager?: LayerManager,\n): Promise<Blob | null> {\n const scale = options.scale ?? 2;\n const padding = options.padding ?? 0;\n const background = options.background ?? '#ffffff';\n const filter = options.filter;\n\n const allElements = store.getAll();\n let visibleElements = layerManager\n ? allElements.filter((el) => layerManager.isLayerVisible(el.layerId))\n : allElements;\n\n if (filter) {\n visibleElements = visibleElements.filter(filter);\n }\n\n const bounds = computeBounds(visibleElements, padding);\n if (!bounds) return null;\n\n const imageCache = await loadImages(visibleElements);\n\n const canvas = document.createElement('canvas');\n canvas.width = Math.ceil(bounds.w * scale);\n canvas.height = Math.ceil(bounds.h * scale);\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return null;\n\n ctx.scale(scale, scale);\n ctx.translate(-bounds.x, -bounds.y);\n\n ctx.fillStyle = background;\n ctx.fillRect(bounds.x, bounds.y, bounds.w, bounds.h);\n\n const renderer = new ElementRenderer();\n renderer.setStore(store);\n\n const grids: GridElement[] = [];\n\n for (const el of visibleElements) {\n if (el.type === 'grid') {\n grids.push(el);\n continue;\n }\n\n if (el.type === 'note') {\n renderNoteOnCanvas(ctx, el);\n continue;\n }\n\n if (el.type === 'text') {\n renderTextOnCanvas(ctx, el);\n continue;\n }\n\n if (el.type === 'html') {\n continue;\n }\n\n if (el.type === 'image') {\n const img = imageCache.get(el.id);\n if (img) {\n ctx.drawImage(img, el.position.x, el.position.y, el.size.w, el.size.h);\n }\n continue;\n }\n\n renderer.renderCanvasElement(ctx, el);\n }\n\n for (const grid of grids) {\n renderGridForBounds(ctx, grid, bounds);\n }\n\n return new Promise((resolve) => {\n canvas.toBlob((blob) => resolve(blob), 'image/png');\n });\n}\n\nexport { computeBounds, getElementRect };\n","import { EventBus } from '../core/event-bus';\r\nimport type { ElementStore } from '../elements/element-store';\r\nimport type { Layer } from './types';\r\nimport { createId } from '../elements/create-id';\r\n\r\ninterface LayerManagerEvents {\r\n change: null;\r\n}\r\n\r\nexport class LayerManager {\r\n private layers = new Map<string, Layer>();\r\n private _activeLayerId: string;\r\n private bus = new EventBus<LayerManagerEvents>();\r\n\r\n constructor(private readonly store: ElementStore) {\r\n const defaultLayer: Layer = {\r\n id: createId('layer'),\r\n name: 'Layer 1',\r\n visible: true,\r\n locked: false,\r\n order: 0,\r\n opacity: 1.0,\r\n };\r\n this.layers.set(defaultLayer.id, defaultLayer);\r\n this._activeLayerId = defaultLayer.id;\r\n this.syncLayerOrder();\r\n }\r\n\r\n get activeLayer(): Layer {\r\n const layer = this.layers.get(this._activeLayerId);\r\n if (!layer) throw new Error('Active layer not found');\r\n return { ...layer };\r\n }\r\n\r\n get activeLayerId(): string {\r\n return this._activeLayerId;\r\n }\r\n\r\n getLayers(): Layer[] {\r\n return [...this.layers.values()].sort((a, b) => a.order - b.order).map((l) => ({ ...l }));\r\n }\r\n\r\n getLayer(id: string): Layer | undefined {\r\n const layer = this.layers.get(id);\r\n return layer ? { ...layer } : undefined;\r\n }\r\n\r\n isLayerVisible(id: string): boolean {\r\n return this.layers.get(id)?.visible ?? true;\r\n }\r\n\r\n isLayerLocked(id: string): boolean {\r\n return this.layers.get(id)?.locked ?? false;\r\n }\r\n\r\n createLayer(name?: string): Layer {\r\n const maxOrder = Math.max(...[...this.layers.values()].map((l) => l.order), -1);\r\n const autoName = name ?? `Layer ${this.layers.size + 1}`;\r\n const layer: Layer = {\r\n id: createId('layer'),\r\n name: autoName,\r\n visible: true,\r\n locked: false,\r\n order: maxOrder + 1,\r\n opacity: 1.0,\r\n };\r\n this.addLayerDirect(layer);\r\n return { ...layer };\r\n }\r\n\r\n removeLayer(id: string): void {\r\n if (this.layers.size <= 1) {\r\n throw new Error('Cannot remove the last layer');\r\n }\r\n if (this._activeLayerId === id) {\r\n const remaining = [...this.layers.values()]\r\n .filter((l) => l.id !== id)\r\n .sort((a, b) => b.order - a.order);\r\n const fallback = remaining[0];\r\n if (fallback) this._activeLayerId = fallback.id;\r\n }\r\n const elements = this.store.getAll().filter((el) => el.layerId === id);\r\n for (const el of elements) {\r\n this.store.update(el.id, { layerId: this._activeLayerId });\r\n }\r\n this.removeLayerDirect(id);\r\n }\r\n\r\n renameLayer(id: string, name: string): void {\r\n this.updateLayerDirect(id, { name });\r\n }\r\n\r\n reorderLayer(id: string, newOrder: number): void {\r\n if (!this.layers.has(id)) return;\r\n this.updateLayerDirect(id, { order: newOrder });\r\n }\r\n\r\n setLayerVisible(id: string, visible: boolean): boolean {\r\n if (!visible && id === this._activeLayerId) {\r\n const fallback = this.findFallbackLayer(id);\r\n if (!fallback) return false;\r\n this._activeLayerId = fallback.id;\r\n }\r\n this.updateLayerDirect(id, { visible });\r\n return true;\r\n }\r\n\r\n setLayerLocked(id: string, locked: boolean): boolean {\r\n if (locked && id === this._activeLayerId) {\r\n const fallback = this.findFallbackLayer(id);\r\n if (!fallback) return false;\r\n this._activeLayerId = fallback.id;\r\n }\r\n this.updateLayerDirect(id, { locked });\r\n return true;\r\n }\r\n\r\n setActiveLayer(id: string): void {\r\n if (!this.layers.has(id)) return;\r\n this._activeLayerId = id;\r\n this.bus.emit('change', null);\r\n }\r\n\r\n moveElementToLayer(elementId: string, layerId: string): void {\r\n if (!this.layers.has(layerId)) return;\r\n this.store.update(elementId, { layerId });\r\n this.bus.emit('change', null);\r\n }\r\n\r\n snapshot(): Layer[] {\r\n return this.getLayers();\r\n }\r\n\r\n loadSnapshot(layers: Layer[]): void {\r\n this.layers.clear();\r\n for (const layer of layers) {\r\n this.layers.set(layer.id, { ...layer });\r\n }\r\n const first = this.getLayers()[0];\r\n if (first) this._activeLayerId = first.id;\r\n this.syncLayerOrder();\r\n this.bus.emit('change', null);\r\n }\r\n\r\n on(event: 'change', callback: () => void): () => void {\r\n return this.bus.on(event, callback);\r\n }\r\n\r\n addLayerDirect(layer: Layer): void {\r\n this.layers.set(layer.id, { ...layer });\r\n this.syncLayerOrder();\r\n this.bus.emit('change', null);\r\n }\r\n\r\n removeLayerDirect(id: string): void {\r\n this.layers.delete(id);\r\n this.syncLayerOrder();\r\n this.bus.emit('change', null);\r\n }\r\n\r\n updateLayerDirect(id: string, props: Omit<Partial<Layer>, 'id'>): void {\r\n const layer = this.layers.get(id);\r\n if (!layer) return;\r\n Object.assign(layer, props);\r\n if ('order' in props) this.syncLayerOrder();\r\n this.bus.emit('change', null);\r\n }\r\n\r\n private syncLayerOrder(): void {\r\n const order = new Map<string, number>();\r\n for (const layer of this.layers.values()) {\r\n order.set(layer.id, layer.order);\r\n }\r\n this.store.setLayerOrder(order);\r\n }\r\n\r\n private findFallbackLayer(excludeId: string): Layer | undefined {\r\n return [...this.layers.values()]\r\n .filter((l) => l.id !== excludeId && l.visible && !l.locked)\r\n .sort((a, b) => b.order - a.order)[0];\r\n }\r\n}\r\n","import { Camera } from './camera';\r\nimport type { CameraOptions } from './camera';\r\nimport { InputHandler } from './input-handler';\r\nimport { Background } from './background';\r\nimport type { BackgroundOptions } from './background';\r\nimport { ElementStore } from '../elements/element-store';\r\nimport { ElementRenderer } from '../elements/element-renderer';\r\nimport { NoteEditor } from '../elements/note-editor';\r\nimport type { CanvasElement, ArrowElement, GridElement } from '../elements/types';\r\nimport { findBoundArrows, getElementBounds, getEdgeIntersection } from '../elements/arrow-binding';\r\nimport { getArrowTangentAngle } from '../elements/arrow-geometry';\r\nimport { ToolManager } from '../tools/tool-manager';\r\nimport type { ToolContext } from '../tools/types';\r\nimport { HistoryStack } from '../history/history-stack';\r\nimport { HistoryRecorder } from '../history/history-recorder';\r\nimport { createImage, createHtmlElement, createGrid } from '../elements/element-factory';\r\nimport { exportState as exportCanvasState, parseState } from '../core/state-serializer';\r\nimport { exportImage } from './export-image';\r\nimport type { ExportImageOptions } from './export-image';\r\nimport type { CanvasState } from '../core/state-serializer';\r\nimport { LayerManager } from '../layers/layer-manager';\r\n\r\nexport interface ViewportOptions {\r\n camera?: CameraOptions;\r\n background?: BackgroundOptions;\r\n}\r\n\r\nexport class Viewport {\r\n readonly camera: Camera;\r\n readonly store: ElementStore;\r\n readonly layerManager: LayerManager;\r\n readonly toolManager: ToolManager;\r\n readonly history: HistoryStack;\r\n readonly domLayer: HTMLDivElement;\r\n private readonly canvasEl: HTMLCanvasElement;\r\n private readonly wrapper: HTMLDivElement;\r\n private readonly unsubCamera: () => void;\r\n private readonly unsubStore: (() => void)[];\r\n private readonly inputHandler: InputHandler;\r\n private readonly background: Background;\r\n private readonly renderer: ElementRenderer;\r\n private readonly noteEditor: NoteEditor;\r\n private readonly historyRecorder: HistoryRecorder;\r\n readonly toolContext: ToolContext;\r\n private resizeObserver: ResizeObserver | null = null;\r\n private animFrameId = 0;\r\n private _snapToGrid = false;\r\n private readonly _gridSize: number;\r\n private needsRender = true;\r\n private domNodes = new Map<string, HTMLDivElement>();\r\n private htmlContent = new Map<string, HTMLElement>();\r\n private interactingElementId: string | null = null;\r\n\r\n constructor(\r\n private readonly container: HTMLElement,\r\n options: ViewportOptions = {},\r\n ) {\r\n this.camera = new Camera(options.camera);\r\n this.background = new Background(options.background);\r\n this._gridSize = options.background?.spacing ?? 24;\r\n this.store = new ElementStore();\r\n this.layerManager = new LayerManager(this.store);\r\n this.toolManager = new ToolManager();\r\n this.renderer = new ElementRenderer();\r\n this.renderer.setStore(this.store);\r\n this.renderer.setCamera(this.camera);\r\n this.renderer.setOnImageLoad(() => this.requestRender());\r\n this.noteEditor = new NoteEditor();\r\n this.noteEditor.setOnStop((id) => this.onTextEditStop(id));\r\n this.history = new HistoryStack();\r\n this.historyRecorder = new HistoryRecorder(this.store, this.history);\r\n\r\n this.wrapper = this.createWrapper();\r\n this.canvasEl = this.createCanvas();\r\n this.domLayer = this.createDomLayer();\r\n\r\n this.wrapper.appendChild(this.canvasEl);\r\n this.wrapper.appendChild(this.domLayer);\r\n this.container.appendChild(this.wrapper);\r\n\r\n this.toolContext = {\r\n camera: this.camera,\r\n store: this.store,\r\n requestRender: () => this.requestRender(),\r\n switchTool: (name: string) => this.toolManager.setTool(name, this.toolContext),\r\n editElement: (id: string) => this.startEditingElement(id),\r\n setCursor: (cursor: string) => {\r\n this.wrapper.style.cursor = cursor;\r\n },\r\n snapToGrid: false,\r\n gridSize: this._gridSize,\r\n activeLayerId: this.layerManager.activeLayerId,\r\n isLayerVisible: (id: string) => this.layerManager.isLayerVisible(id),\r\n isLayerLocked: (id: string) => this.layerManager.isLayerLocked(id),\r\n };\r\n\r\n this.inputHandler = new InputHandler(this.wrapper, this.camera, {\r\n toolManager: this.toolManager,\r\n toolContext: this.toolContext,\r\n historyRecorder: this.historyRecorder,\r\n historyStack: this.history,\r\n });\r\n\r\n this.unsubCamera = this.camera.onChange(() => {\r\n this.applyCameraTransform();\r\n this.requestRender();\r\n });\r\n\r\n this.unsubStore = [\r\n this.store.on('add', () => this.requestRender()),\r\n this.store.on('remove', (el) => {\r\n this.unbindArrowsFrom(el);\r\n this.removeDomNode(el.id);\r\n }),\r\n this.store.on('update', () => this.requestRender()),\r\n this.store.on('clear', () => this.clearDomNodes()),\r\n ];\r\n\r\n this.layerManager.on('change', () => {\r\n this.toolContext.activeLayerId = this.layerManager.activeLayerId;\r\n this.requestRender();\r\n });\r\n\r\n this.wrapper.addEventListener('dblclick', this.onDblClick);\r\n this.wrapper.addEventListener('dragover', this.onDragOver);\r\n this.wrapper.addEventListener('drop', this.onDrop);\r\n this.observeResize();\r\n this.syncCanvasSize();\r\n this.startRenderLoop();\r\n }\r\n\r\n get ctx(): CanvasRenderingContext2D | null {\r\n return this.canvasEl.getContext('2d');\r\n }\r\n\r\n get snapToGrid(): boolean {\r\n return this._snapToGrid;\r\n }\r\n\r\n setSnapToGrid(enabled: boolean): void {\r\n this._snapToGrid = enabled;\r\n this.toolContext.snapToGrid = enabled;\r\n }\r\n\r\n requestRender(): void {\r\n this.needsRender = true;\r\n }\r\n\r\n exportState(): CanvasState {\r\n return exportCanvasState(this.store.snapshot(), this.camera, this.layerManager.snapshot());\r\n }\r\n\r\n exportJSON(): string {\r\n return JSON.stringify(this.exportState());\r\n }\r\n\r\n async exportImage(options?: ExportImageOptions): Promise<Blob | null> {\r\n return exportImage(this.store, options, this.layerManager);\r\n }\r\n\r\n loadState(state: CanvasState): void {\r\n this.historyRecorder.pause();\r\n this.noteEditor.destroy(this.store);\r\n this.clearDomNodes();\r\n this.store.loadSnapshot(state.elements);\r\n if (state.layers && state.layers.length > 0) {\r\n this.layerManager.loadSnapshot(state.layers);\r\n }\r\n this.reattachHtmlContent();\r\n this.history.clear();\r\n this.historyRecorder.resume();\r\n this.camera.moveTo(state.camera.position.x, state.camera.position.y);\r\n this.camera.setZoom(state.camera.zoom);\r\n }\r\n\r\n loadJSON(json: string): void {\r\n this.loadState(parseState(json));\r\n }\r\n\r\n undo(): boolean {\r\n this.historyRecorder.pause();\r\n const result = this.history.undo(this.store);\r\n this.historyRecorder.resume();\r\n if (result) this.requestRender();\r\n return result;\r\n }\r\n\r\n redo(): boolean {\r\n this.historyRecorder.pause();\r\n const result = this.history.redo(this.store);\r\n this.historyRecorder.resume();\r\n if (result) this.requestRender();\r\n return result;\r\n }\r\n\r\n addImage(src: string, position: { x: number; y: number }, size = { w: 300, h: 200 }): string {\r\n const image = createImage({ position, size, src, layerId: this.layerManager.activeLayerId });\r\n this.historyRecorder.begin();\r\n this.store.add(image);\r\n this.historyRecorder.commit();\r\n this.requestRender();\r\n return image.id;\r\n }\r\n\r\n addHtmlElement(\r\n dom: HTMLElement,\r\n position: { x: number; y: number },\r\n size = { w: 200, h: 150 },\r\n ): string {\r\n const domId = dom.id || undefined;\r\n const el = createHtmlElement({\r\n position,\r\n size,\r\n domId,\r\n layerId: this.layerManager.activeLayerId,\r\n });\r\n this.htmlContent.set(el.id, dom);\r\n this.historyRecorder.begin();\r\n this.store.add(el);\r\n this.historyRecorder.commit();\r\n this.requestRender();\r\n return el.id;\r\n }\r\n\r\n addGrid(input: {\r\n gridType?: 'square' | 'hex';\r\n hexOrientation?: 'pointy' | 'flat';\r\n cellSize?: number;\r\n strokeColor?: string;\r\n strokeWidth?: number;\r\n opacity?: number;\r\n }): string {\r\n const existing = this.store.getElementsByType('grid')[0];\r\n this.historyRecorder.begin();\r\n if (existing) {\r\n this.store.remove(existing.id);\r\n }\r\n const grid = createGrid({ ...input, layerId: this.layerManager.activeLayerId });\r\n this.store.add(grid);\r\n this.historyRecorder.commit();\r\n this.requestRender();\r\n return grid.id;\r\n }\r\n\r\n updateGrid(\r\n updates: Partial<\r\n Pick<\r\n GridElement,\r\n 'gridType' | 'hexOrientation' | 'cellSize' | 'strokeColor' | 'strokeWidth' | 'opacity'\r\n >\r\n >,\r\n ): void {\r\n const grid = this.store.getElementsByType('grid')[0];\r\n if (!grid) return;\r\n this.historyRecorder.begin();\r\n this.store.update(grid.id, updates);\r\n this.historyRecorder.commit();\r\n this.requestRender();\r\n }\r\n\r\n removeGrid(): void {\r\n const grid = this.store.getElementsByType('grid')[0];\r\n if (!grid) return;\r\n this.historyRecorder.begin();\r\n this.store.remove(grid.id);\r\n this.historyRecorder.commit();\r\n this.requestRender();\r\n }\r\n\r\n destroy(): void {\r\n cancelAnimationFrame(this.animFrameId);\r\n this.stopInteracting();\r\n this.noteEditor.destroy(this.store);\r\n this.historyRecorder.destroy();\r\n this.wrapper.removeEventListener('dblclick', this.onDblClick);\r\n this.wrapper.removeEventListener('dragover', this.onDragOver);\r\n this.wrapper.removeEventListener('drop', this.onDrop);\r\n this.inputHandler.destroy();\r\n this.unsubCamera();\r\n this.unsubStore.forEach((fn) => fn());\r\n this.resizeObserver?.disconnect();\r\n this.resizeObserver = null;\r\n this.wrapper.remove();\r\n }\r\n\r\n private startRenderLoop(): void {\r\n const loop = (): void => {\r\n if (this.needsRender) {\r\n this.render();\r\n this.needsRender = false;\r\n }\r\n this.animFrameId = requestAnimationFrame(loop);\r\n };\r\n this.animFrameId = requestAnimationFrame(loop);\r\n }\r\n\r\n private render(): void {\r\n const ctx = this.ctx;\r\n if (!ctx) return;\r\n\r\n const dpr = typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;\r\n ctx.save();\r\n ctx.scale(dpr, dpr);\r\n\r\n this.renderer.setCanvasSize(this.canvasEl.clientWidth, this.canvasEl.clientHeight);\r\n this.background.render(ctx, this.camera);\r\n\r\n ctx.save();\r\n ctx.translate(this.camera.position.x, this.camera.position.y);\r\n ctx.scale(this.camera.zoom, this.camera.zoom);\r\n\r\n const allElements = this.store.getAll();\r\n let domZIndex = 0;\r\n for (const element of allElements) {\r\n if (!this.layerManager.isLayerVisible(element.layerId)) {\r\n if (this.renderer.isDomElement(element)) {\r\n this.hideDomNode(element.id);\r\n }\r\n continue;\r\n }\r\n if (this.renderer.isDomElement(element)) {\r\n this.syncDomNode(element, domZIndex++);\r\n } else {\r\n this.renderer.renderCanvasElement(ctx, element);\r\n }\r\n }\r\n\r\n const activeTool = this.toolManager.activeTool;\r\n if (activeTool?.renderOverlay) {\r\n activeTool.renderOverlay(ctx);\r\n }\r\n\r\n ctx.restore();\r\n ctx.restore();\r\n }\r\n\r\n private startEditingElement(id: string): void {\r\n const element = this.store.getById(id);\r\n if (!element || (element.type !== 'note' && element.type !== 'text')) return;\r\n\r\n this.render();\r\n\r\n const node = this.domNodes.get(id);\r\n if (node) {\r\n this.noteEditor.startEditing(node, id, this.store);\r\n }\r\n }\r\n\r\n private onTextEditStop(elementId: string): void {\r\n const element = this.store.getById(elementId);\r\n if (!element || element.type !== 'text') return;\r\n\r\n if (!element.text || element.text.trim() === '') {\r\n this.historyRecorder.begin();\r\n this.store.remove(elementId);\r\n this.historyRecorder.commit();\r\n return;\r\n }\r\n\r\n const node = this.domNodes.get(elementId);\r\n if (node && 'size' in element) {\r\n const measuredHeight = node.scrollHeight;\r\n if (measuredHeight !== element.size.h) {\r\n this.store.update(elementId, {\r\n size: { w: element.size.w, h: measuredHeight },\r\n });\r\n }\r\n }\r\n }\r\n\r\n private onDblClick = (e: MouseEvent): void => {\r\n const el = document.elementFromPoint(e.clientX, e.clientY);\r\n\r\n const nodeEl = (el as HTMLElement | null)?.closest<HTMLDivElement>('[data-element-id]');\r\n if (nodeEl) {\r\n const elementId = nodeEl.dataset['elementId'];\r\n if (elementId) {\r\n const element = this.store.getById(elementId);\r\n if (element?.type === 'note' || element?.type === 'text') {\r\n this.startEditingElement(elementId);\r\n return;\r\n }\r\n }\r\n }\r\n\r\n const rect = this.wrapper.getBoundingClientRect();\r\n const screen = { x: e.clientX - rect.left, y: e.clientY - rect.top };\r\n const world = this.camera.screenToWorld(screen);\r\n const hit = this.hitTestWorld(world);\r\n if (hit?.type === 'html') {\r\n this.startInteracting(hit.id);\r\n }\r\n };\r\n\r\n private hitTestWorld(world: { x: number; y: number }): CanvasElement | null {\r\n const elements = this.store.getAll().reverse();\r\n for (const el of elements) {\r\n if (!('size' in el)) continue;\r\n const { x, y } = el.position;\r\n const { w, h } = el.size;\r\n if (world.x >= x && world.x <= x + w && world.y >= y && world.y <= y + h) {\r\n return el;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n private startInteracting(id: string): void {\r\n this.stopInteracting();\r\n const node = this.domNodes.get(id);\r\n if (!node) return;\r\n\r\n this.interactingElementId = id;\r\n node.style.pointerEvents = 'auto';\r\n node.addEventListener('pointerdown', this.onInteractNodePointerDown);\r\n\r\n window.addEventListener('keydown', this.onInteractKeyDown);\r\n window.addEventListener('pointerdown', this.onInteractPointerDown);\r\n }\r\n\r\n stopInteracting(): void {\r\n if (!this.interactingElementId) return;\r\n\r\n const node = this.domNodes.get(this.interactingElementId);\r\n if (node) {\r\n node.style.pointerEvents = 'none';\r\n node.removeEventListener('pointerdown', this.onInteractNodePointerDown);\r\n }\r\n\r\n this.interactingElementId = null;\r\n window.removeEventListener('keydown', this.onInteractKeyDown);\r\n window.removeEventListener('pointerdown', this.onInteractPointerDown);\r\n }\r\n\r\n private onInteractNodePointerDown = (e: PointerEvent): void => {\r\n e.stopPropagation();\r\n };\r\n\r\n private onInteractKeyDown = (e: KeyboardEvent): void => {\r\n if (e.key === 'Escape') {\r\n this.stopInteracting();\r\n }\r\n };\r\n\r\n private onInteractPointerDown = (e: PointerEvent): void => {\r\n if (!this.interactingElementId) return;\r\n const target = e.target as HTMLElement | null;\r\n if (!target) return;\r\n\r\n const node = this.domNodes.get(this.interactingElementId);\r\n if (node && !node.contains(target)) {\r\n this.stopInteracting();\r\n }\r\n };\r\n\r\n private onDragOver = (e: DragEvent): void => {\r\n e.preventDefault();\r\n };\r\n\r\n private onDrop = (e: DragEvent): void => {\r\n e.preventDefault();\r\n const files = e.dataTransfer?.files;\r\n if (!files) return;\r\n\r\n const rect = this.wrapper.getBoundingClientRect();\r\n\r\n for (const file of files) {\r\n if (!file.type.startsWith('image/')) continue;\r\n\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n const src = reader.result;\r\n if (typeof src !== 'string') return;\r\n\r\n const screenPos = { x: e.clientX - rect.left, y: e.clientY - rect.top };\r\n const worldPos = this.camera.screenToWorld(screenPos);\r\n this.addImage(src, worldPos);\r\n };\r\n reader.readAsDataURL(file);\r\n }\r\n };\r\n\r\n private syncDomNode(element: CanvasElement, zIndex = 0): void {\r\n let node = this.domNodes.get(element.id);\r\n if (!node) {\r\n node = document.createElement('div');\r\n node.dataset['elementId'] = element.id;\r\n Object.assign(node.style, {\r\n position: 'absolute',\r\n pointerEvents: 'auto',\r\n });\r\n this.domLayer.appendChild(node);\r\n this.domNodes.set(element.id, node);\r\n }\r\n\r\n const size = 'size' in element ? element.size : null;\r\n Object.assign(node.style, {\r\n display: 'block',\r\n left: `${element.position.x}px`,\r\n top: `${element.position.y}px`,\r\n width: size ? `${size.w}px` : 'auto',\r\n height: size ? `${size.h}px` : 'auto',\r\n zIndex: String(zIndex),\r\n });\r\n\r\n this.renderDomContent(node, element);\r\n }\r\n\r\n private renderDomContent(node: HTMLDivElement, element: CanvasElement): void {\r\n if (element.type === 'note') {\r\n if (!node.dataset['initialized']) {\r\n node.dataset['initialized'] = 'true';\r\n Object.assign(node.style, {\r\n backgroundColor: element.backgroundColor,\r\n color: element.textColor,\r\n padding: '8px',\r\n borderRadius: '4px',\r\n boxShadow: '0 2px 8px rgba(0,0,0,0.15)',\r\n fontSize: '14px',\r\n overflow: 'hidden',\r\n cursor: 'default',\r\n userSelect: 'none',\r\n wordWrap: 'break-word',\r\n });\r\n node.textContent = element.text || '';\r\n\r\n node.addEventListener('dblclick', (e) => {\r\n e.stopPropagation();\r\n const id = node.dataset['elementId'];\r\n if (id) this.startEditingElement(id);\r\n });\r\n }\r\n\r\n if (!this.noteEditor.isEditing || this.noteEditor.editingElementId !== element.id) {\r\n if (node.textContent !== element.text) {\r\n node.textContent = element.text || '';\r\n }\r\n node.style.backgroundColor = element.backgroundColor;\r\n node.style.color = element.textColor;\r\n }\r\n }\r\n\r\n if (element.type === 'html' && !node.dataset['initialized']) {\r\n const content = this.htmlContent.get(element.id);\r\n if (content) {\r\n node.dataset['initialized'] = 'true';\r\n Object.assign(node.style, {\r\n overflow: 'hidden',\r\n pointerEvents: 'none',\r\n });\r\n node.appendChild(content);\r\n }\r\n }\r\n\r\n if (element.type === 'text') {\r\n if (!node.dataset['initialized']) {\r\n node.dataset['initialized'] = 'true';\r\n Object.assign(node.style, {\r\n padding: '2px',\r\n fontSize: `${element.fontSize}px`,\r\n color: element.color,\r\n textAlign: element.textAlign,\r\n background: 'none',\r\n border: 'none',\r\n boxShadow: 'none',\r\n overflow: 'visible',\r\n cursor: 'default',\r\n userSelect: 'none',\r\n wordWrap: 'break-word',\r\n whiteSpace: 'pre-wrap',\r\n lineHeight: '1.4',\r\n });\r\n node.textContent = element.text || '';\r\n\r\n node.addEventListener('dblclick', (e) => {\r\n e.stopPropagation();\r\n const id = node.dataset['elementId'];\r\n if (id) this.startEditingElement(id);\r\n });\r\n }\r\n\r\n if (!this.noteEditor.isEditing || this.noteEditor.editingElementId !== element.id) {\r\n if (node.textContent !== element.text) {\r\n node.textContent = element.text || '';\r\n }\r\n Object.assign(node.style, {\r\n fontSize: `${element.fontSize}px`,\r\n color: element.color,\r\n textAlign: element.textAlign,\r\n });\r\n }\r\n }\r\n }\r\n\r\n private unbindArrowsFrom(removedElement: CanvasElement): void {\r\n const boundArrows = findBoundArrows(removedElement.id, this.store);\r\n const bounds = getElementBounds(removedElement);\r\n\r\n for (const arrow of boundArrows) {\r\n const updates: Partial<ArrowElement> = {};\r\n\r\n if (arrow.fromBinding?.elementId === removedElement.id) {\r\n updates.fromBinding = undefined;\r\n if (bounds) {\r\n const angle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 0);\r\n const rayTarget = {\r\n x: arrow.from.x + Math.cos(angle) * 1000,\r\n y: arrow.from.y + Math.sin(angle) * 1000,\r\n };\r\n const edge = getEdgeIntersection(bounds, rayTarget);\r\n updates.from = edge;\r\n updates.position = edge;\r\n }\r\n }\r\n\r\n if (arrow.toBinding?.elementId === removedElement.id) {\r\n updates.toBinding = undefined;\r\n if (bounds) {\r\n const angle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 1);\r\n const rayTarget = {\r\n x: arrow.to.x - Math.cos(angle) * 1000,\r\n y: arrow.to.y - Math.sin(angle) * 1000,\r\n };\r\n updates.to = getEdgeIntersection(bounds, rayTarget);\r\n }\r\n }\r\n\r\n if (Object.keys(updates).length > 0) {\r\n this.store.update(arrow.id, updates);\r\n }\r\n }\r\n }\r\n\r\n private hideDomNode(id: string): void {\r\n const node = this.domNodes.get(id);\r\n if (node) node.style.display = 'none';\r\n }\r\n\r\n private removeDomNode(id: string): void {\r\n this.htmlContent.delete(id);\r\n const node = this.domNodes.get(id);\r\n if (node) {\r\n node.remove();\r\n this.domNodes.delete(id);\r\n }\r\n this.requestRender();\r\n }\r\n\r\n private clearDomNodes(): void {\r\n this.domNodes.forEach((node) => node.remove());\r\n this.domNodes.clear();\r\n this.htmlContent.clear();\r\n this.requestRender();\r\n }\r\n\r\n private reattachHtmlContent(): void {\r\n for (const el of this.store.getElementsByType('html')) {\r\n if (el.domId) {\r\n const dom = document.getElementById(el.domId);\r\n if (dom) {\r\n this.htmlContent.set(el.id, dom);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private createWrapper(): HTMLDivElement {\r\n const el = document.createElement('div');\r\n Object.assign(el.style, {\r\n position: 'relative',\r\n width: '100%',\r\n height: '100%',\r\n overflow: 'hidden',\r\n });\r\n return el;\r\n }\r\n\r\n private createCanvas(): HTMLCanvasElement {\r\n const el = document.createElement('canvas');\r\n Object.assign(el.style, {\r\n position: 'absolute',\r\n top: '0',\r\n left: '0',\r\n width: '100%',\r\n height: '100%',\r\n });\r\n return el;\r\n }\r\n\r\n private createDomLayer(): HTMLDivElement {\r\n const el = document.createElement('div');\r\n Object.assign(el.style, {\r\n position: 'absolute',\r\n top: '0',\r\n left: '0',\r\n width: '100%',\r\n height: '100%',\r\n pointerEvents: 'none',\r\n transformOrigin: '0 0',\r\n });\r\n return el;\r\n }\r\n\r\n private applyCameraTransform(): void {\r\n this.domLayer.style.transform = this.camera.toCSSTransform();\r\n }\r\n\r\n private syncCanvasSize(): void {\r\n const rect = this.container.getBoundingClientRect();\r\n const dpr = typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;\r\n this.canvasEl.width = rect.width * dpr;\r\n this.canvasEl.height = rect.height * dpr;\r\n this.requestRender();\r\n }\r\n\r\n private observeResize(): void {\r\n if (typeof ResizeObserver === 'undefined') return;\r\n this.resizeObserver = new ResizeObserver(() => this.syncCanvasSize());\r\n this.resizeObserver.observe(this.container);\r\n }\r\n}\r\n","import type { Tool, ToolContext, PointerState } from './types';\n\nexport class HandTool implements Tool {\n readonly name = 'hand';\n private panning = false;\n private lastScreen = { x: 0, y: 0 };\n\n onActivate(ctx: ToolContext): void {\n ctx.setCursor?.('grab');\n }\n\n onDeactivate(ctx: ToolContext): void {\n ctx.setCursor?.('default');\n }\n\n onPointerDown(state: PointerState, ctx: ToolContext): void {\n this.panning = true;\n this.lastScreen = { x: state.x, y: state.y };\n ctx.setCursor?.('grabbing');\n }\n\n onPointerMove(state: PointerState, ctx: ToolContext): void {\n if (!this.panning) return;\n const dx = state.x - this.lastScreen.x;\n const dy = state.y - this.lastScreen.y;\n this.lastScreen = { x: state.x, y: state.y };\n ctx.camera.pan(dx, dy);\n }\n\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\n this.panning = false;\n ctx.setCursor?.('grab');\n }\n}\n","import type { StrokePoint } from '../core/types';\r\nimport type { Tool, ToolContext, PointerState } from './types';\r\nimport { createStroke } from '../elements/element-factory';\r\nimport { simplifyPoints, smoothToSegments, pressureToWidth } from '../elements/stroke-smoothing';\r\n\r\nexport interface PencilToolOptions {\r\n color?: string;\r\n width?: number;\r\n smoothing?: number;\r\n}\r\n\r\nconst MIN_POINTS_FOR_STROKE = 2;\r\nconst DEFAULT_SMOOTHING = 1.5;\r\nconst DEFAULT_PRESSURE = 0.5;\r\n\r\nexport class PencilTool implements Tool {\r\n readonly name = 'pencil';\r\n private drawing = false;\r\n private points: StrokePoint[] = [];\r\n private color: string;\r\n private width: number;\r\n private smoothing: number;\r\n\r\n constructor(options: PencilToolOptions = {}) {\r\n this.color = options.color ?? '#000000';\r\n this.width = options.width ?? 2;\r\n this.smoothing = options.smoothing ?? DEFAULT_SMOOTHING;\r\n }\r\n\r\n onActivate(ctx: ToolContext): void {\r\n ctx.setCursor?.('crosshair');\r\n }\r\n\r\n onDeactivate(ctx: ToolContext): void {\r\n ctx.setCursor?.('default');\r\n }\r\n\r\n setOptions(options: PencilToolOptions): void {\r\n if (options.color !== undefined) this.color = options.color;\r\n if (options.width !== undefined) this.width = options.width;\r\n if (options.smoothing !== undefined) this.smoothing = options.smoothing;\r\n }\r\n\r\n onPointerDown(state: PointerState, ctx: ToolContext): void {\r\n this.drawing = true;\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n const pressure = state.pressure === 0 ? DEFAULT_PRESSURE : state.pressure;\r\n this.points = [{ x: world.x, y: world.y, pressure }];\r\n }\r\n\r\n onPointerMove(state: PointerState, ctx: ToolContext): void {\r\n if (!this.drawing) return;\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n const pressure = state.pressure === 0 ? DEFAULT_PRESSURE : state.pressure;\r\n this.points.push({ x: world.x, y: world.y, pressure });\r\n ctx.requestRender();\r\n }\r\n\r\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\r\n if (!this.drawing) return;\r\n this.drawing = false;\r\n\r\n if (this.points.length < MIN_POINTS_FOR_STROKE) {\r\n this.points = [];\r\n return;\r\n }\r\n\r\n const simplified = simplifyPoints(this.points, this.smoothing);\r\n const stroke = createStroke({\r\n points: simplified,\r\n color: this.color,\r\n width: this.width,\r\n layerId: ctx.activeLayerId ?? '',\r\n });\r\n ctx.store.add(stroke);\r\n this.points = [];\r\n ctx.requestRender();\r\n }\r\n\r\n renderOverlay(ctx: CanvasRenderingContext2D): void {\r\n if (!this.drawing || this.points.length < 2) return;\r\n\r\n ctx.save();\r\n ctx.strokeStyle = this.color;\r\n ctx.lineCap = 'round';\r\n ctx.lineJoin = 'round';\r\n ctx.globalAlpha = 0.8;\r\n\r\n const segments = smoothToSegments(this.points);\r\n for (const seg of segments) {\r\n const w =\r\n (pressureToWidth(seg.start.pressure, this.width) +\r\n pressureToWidth(seg.end.pressure, this.width)) /\r\n 2;\r\n ctx.lineWidth = w;\r\n ctx.beginPath();\r\n ctx.moveTo(seg.start.x, seg.start.y);\r\n ctx.bezierCurveTo(seg.cp1.x, seg.cp1.y, seg.cp2.x, seg.cp2.y, seg.end.x, seg.end.y);\r\n ctx.stroke();\r\n }\r\n\r\n ctx.restore();\r\n }\r\n}\r\n","import type { Point } from '../core/types';\r\nimport type { Tool, ToolContext, PointerState } from './types';\r\nimport type { StrokeElement } from '../elements/types';\r\n\r\nexport interface EraserToolOptions {\r\n radius?: number;\r\n}\r\n\r\nconst DEFAULT_RADIUS = 20;\r\n\r\nfunction makeEraserCursor(radius: number): string {\r\n const size = radius * 2;\r\n const svg = `<svg xmlns='http://www.w3.org/2000/svg' width='${size}' height='${size}'><circle cx='${radius}' cy='${radius}' r='${radius - 1}' fill='none' stroke='%23666' stroke-width='1.5'/></svg>`;\r\n return `url(\"data:image/svg+xml,${svg}\") ${radius} ${radius}, crosshair`;\r\n}\r\n\r\nexport class EraserTool implements Tool {\r\n readonly name = 'eraser';\r\n private erasing = false;\r\n private readonly radius: number;\r\n private readonly cursor: string;\r\n\r\n constructor(options: EraserToolOptions = {}) {\r\n this.radius = options.radius ?? DEFAULT_RADIUS;\r\n this.cursor = makeEraserCursor(this.radius);\r\n }\r\n\r\n onActivate(ctx: ToolContext): void {\r\n ctx.setCursor?.(this.cursor);\r\n }\r\n\r\n onDeactivate(ctx: ToolContext): void {\r\n ctx.setCursor?.('default');\r\n }\r\n\r\n onPointerDown(state: PointerState, ctx: ToolContext): void {\r\n this.erasing = true;\r\n this.eraseAt(state, ctx);\r\n }\r\n\r\n onPointerMove(state: PointerState, ctx: ToolContext): void {\r\n if (!this.erasing) return;\r\n this.eraseAt(state, ctx);\r\n }\r\n\r\n onPointerUp(_state: PointerState, _ctx: ToolContext): void {\r\n this.erasing = false;\r\n }\r\n\r\n private eraseAt(state: PointerState, ctx: ToolContext): void {\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n const strokes = ctx.store.getElementsByType('stroke');\r\n let erased = false;\r\n\r\n for (const stroke of strokes) {\r\n if (ctx.isLayerVisible && !ctx.isLayerVisible(stroke.layerId)) continue;\r\n if (ctx.isLayerLocked && ctx.isLayerLocked(stroke.layerId)) continue;\r\n if (this.strokeIntersects(stroke, world)) {\r\n ctx.store.remove(stroke.id);\r\n erased = true;\r\n }\r\n }\r\n\r\n if (erased) ctx.requestRender();\r\n }\r\n\r\n private strokeIntersects(stroke: StrokeElement, point: Point): boolean {\r\n const radiusSq = this.radius * this.radius;\r\n return stroke.points.some((p) => {\r\n const dx = p.x + stroke.position.x - point.x;\r\n const dy = p.y + stroke.position.y - point.y;\r\n return dx * dx + dy * dy <= radiusSq;\r\n });\r\n }\r\n}\r\n","import type { Point } from '../core/types';\r\nimport type { ArrowElement, CanvasElement } from '../elements/types';\r\nimport type { ToolContext } from './types';\r\nimport { getArrowMidpoint, getBendFromPoint } from '../elements/arrow-geometry';\r\nimport { findBindTarget, getElementCenter, getElementBounds } from '../elements/arrow-binding';\r\n\r\nconst BIND_THRESHOLD = 20;\r\n\r\nexport type ArrowHandle = 'start' | 'mid' | 'end';\r\n\r\nconst HANDLE_RADIUS = 5;\r\nconst HANDLE_HIT_PADDING = 4;\r\n\r\nconst ARROW_HANDLE_CURSORS: Record<ArrowHandle, string> = {\r\n start: 'crosshair',\r\n end: 'crosshair',\r\n mid: 'grab',\r\n};\r\n\r\nexport function getArrowHandleCursor(handle: ArrowHandle, active: boolean): string {\r\n if (handle === 'mid' && active) return 'grabbing';\r\n return ARROW_HANDLE_CURSORS[handle];\r\n}\r\n\r\nexport function getArrowHandlePositions(arrow: ArrowElement): [ArrowHandle, Point][] {\r\n const mid = getArrowMidpoint(arrow.from, arrow.to, arrow.bend);\r\n return [\r\n ['start', arrow.from],\r\n ['mid', mid],\r\n ['end', arrow.to],\r\n ];\r\n}\r\n\r\nexport function hitTestArrowHandles(\r\n world: Point,\r\n selectedIds: string[],\r\n ctx: ToolContext,\r\n): { elementId: string; handle: ArrowHandle } | null {\r\n if (selectedIds.length === 0) return null;\r\n\r\n const zoom = ctx.camera.zoom;\r\n const hitRadius = (HANDLE_RADIUS + HANDLE_HIT_PADDING) / zoom;\r\n\r\n for (const id of selectedIds) {\r\n const el = ctx.store.getById(id);\r\n if (!el || el.type !== 'arrow') continue;\r\n\r\n const handles = getArrowHandlePositions(el);\r\n for (const [handle, pos] of handles) {\r\n const dx = world.x - pos.x;\r\n const dy = world.y - pos.y;\r\n if (dx * dx + dy * dy <= hitRadius * hitRadius) {\r\n return { elementId: id, handle };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nexport function applyArrowHandleDrag(\r\n handle: ArrowHandle,\r\n elementId: string,\r\n world: Point,\r\n ctx: ToolContext,\r\n): void {\r\n const el = ctx.store.getById(elementId);\r\n if (!el || el.type !== 'arrow') return;\r\n\r\n const threshold = BIND_THRESHOLD / ctx.camera.zoom;\r\n\r\n const layerFilter = (candidate: CanvasElement) => candidate.layerId === el.layerId;\r\n\r\n switch (handle) {\r\n case 'start': {\r\n const excludeId = el.toBinding?.elementId;\r\n const target = findBindTarget(world, ctx.store, threshold, excludeId, layerFilter);\r\n if (target) {\r\n const center = getElementCenter(target);\r\n ctx.store.update(elementId, {\r\n from: center,\r\n position: center,\r\n fromBinding: { elementId: target.id },\r\n });\r\n } else {\r\n ctx.store.update(elementId, {\r\n from: { x: world.x, y: world.y },\r\n position: { x: world.x, y: world.y },\r\n fromBinding: undefined,\r\n });\r\n }\r\n break;\r\n }\r\n case 'end': {\r\n const excludeId = el.fromBinding?.elementId;\r\n const target = findBindTarget(world, ctx.store, threshold, excludeId, layerFilter);\r\n if (target) {\r\n const center = getElementCenter(target);\r\n ctx.store.update(elementId, {\r\n to: center,\r\n toBinding: { elementId: target.id },\r\n });\r\n } else {\r\n ctx.store.update(elementId, {\r\n to: { x: world.x, y: world.y },\r\n toBinding: undefined,\r\n });\r\n }\r\n break;\r\n }\r\n case 'mid': {\r\n const bend = getBendFromPoint(el.from, el.to, world);\r\n ctx.store.update(elementId, { bend });\r\n break;\r\n }\r\n }\r\n\r\n ctx.requestRender();\r\n}\r\n\r\nexport function getArrowHandleDragTarget(\r\n handle: ArrowHandle,\r\n elementId: string,\r\n world: Point,\r\n ctx: ToolContext,\r\n): { x: number; y: number; w: number; h: number } | null {\r\n if (handle === 'mid') return null;\r\n\r\n const el = ctx.store.getById(elementId);\r\n if (!el || el.type !== 'arrow') return null;\r\n\r\n const threshold = BIND_THRESHOLD / ctx.camera.zoom;\r\n const excludeId = handle === 'start' ? el.toBinding?.elementId : el.fromBinding?.elementId;\r\n const layerFilter = (candidate: CanvasElement) => candidate.layerId === el.layerId;\r\n const target = findBindTarget(world, ctx.store, threshold, excludeId, layerFilter);\r\n if (!target) return null;\r\n\r\n return getElementBounds(target);\r\n}\r\n\r\nexport function renderArrowHandles(\r\n canvasCtx: CanvasRenderingContext2D,\r\n arrow: ArrowElement,\r\n zoom: number,\r\n): void {\r\n const radius = HANDLE_RADIUS / zoom;\r\n const handles = getArrowHandlePositions(arrow);\r\n\r\n canvasCtx.setLineDash([]);\r\n canvasCtx.lineWidth = 1.5 / zoom;\r\n\r\n for (const [handle, pos] of handles) {\r\n canvasCtx.fillStyle = handle === 'mid' ? '#2196F3' : '#ffffff';\r\n canvasCtx.strokeStyle = '#2196F3';\r\n\r\n canvasCtx.beginPath();\r\n canvasCtx.arc(pos.x, pos.y, radius, 0, Math.PI * 2);\r\n canvasCtx.fill();\r\n canvasCtx.stroke();\r\n }\r\n}\r\n","import type { Point } from '../core/types';\r\nimport type { Tool, ToolContext, PointerState } from './types';\r\nimport { snapPoint } from '../core/snap';\r\nimport type { CanvasElement, ArrowElement } from '../elements/types';\r\nimport { isNearBezier, getArrowBounds } from '../elements/arrow-geometry';\r\nimport type { Rect } from '../elements/arrow-geometry';\r\nimport { findBoundArrows, updateBoundArrow, getElementBounds } from '../elements/arrow-binding';\r\nimport {\r\n type ArrowHandle,\r\n hitTestArrowHandles,\r\n applyArrowHandleDrag,\r\n renderArrowHandles,\r\n getArrowHandleCursor,\r\n getArrowHandleDragTarget,\r\n} from './arrow-handles';\r\n\r\ntype HandlePosition = 'nw' | 'ne' | 'sw' | 'se';\r\n\r\nconst HANDLE_SIZE = 8;\r\nconst HANDLE_HIT_PADDING = 4;\r\nconst SELECTION_PAD = 4;\r\nconst MIN_ELEMENT_SIZE = 20;\r\n\r\nconst HANDLE_CURSORS: Record<HandlePosition, string> = {\r\n nw: 'nwse-resize',\r\n se: 'nwse-resize',\r\n ne: 'nesw-resize',\r\n sw: 'nesw-resize',\r\n};\r\n\r\ntype Mode =\r\n | { type: 'idle' }\r\n | { type: 'dragging' }\r\n | { type: 'marquee'; start: Point }\r\n | { type: 'resizing'; elementId: string; handle: HandlePosition }\r\n | { type: 'arrow-handle'; elementId: string; handle: ArrowHandle };\r\n\r\nexport class SelectTool implements Tool {\r\n readonly name = 'select';\r\n private _selectedIds: string[] = [];\r\n private mode: Mode = { type: 'idle' };\r\n private lastWorld: Point = { x: 0, y: 0 };\r\n private currentWorld: Point = { x: 0, y: 0 };\r\n private ctx: ToolContext | null = null;\r\n\r\n get selectedIds(): string[] {\r\n return [...this._selectedIds];\r\n }\r\n\r\n get isMarqueeActive(): boolean {\r\n return this.mode.type === 'marquee';\r\n }\r\n\r\n onActivate(ctx: ToolContext): void {\r\n this.ctx = ctx;\r\n }\r\n\r\n onDeactivate(ctx: ToolContext): void {\r\n this._selectedIds = [];\r\n this.mode = { type: 'idle' };\r\n ctx.setCursor?.('default');\r\n }\r\n\r\n private snap(point: Point, ctx: ToolContext): Point {\r\n return ctx.snapToGrid && ctx.gridSize ? snapPoint(point, ctx.gridSize) : point;\r\n }\r\n\r\n onPointerDown(state: PointerState, ctx: ToolContext): void {\r\n this.ctx = ctx;\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n this.lastWorld = this.snap(world, ctx);\r\n this.currentWorld = world;\r\n\r\n const arrowHit = hitTestArrowHandles(world, this._selectedIds, ctx);\r\n if (arrowHit) {\r\n this.mode = {\r\n type: 'arrow-handle',\r\n elementId: arrowHit.elementId,\r\n handle: arrowHit.handle,\r\n };\r\n ctx.requestRender();\r\n return;\r\n }\r\n\r\n const resizeHit = this.hitTestResizeHandle(world, ctx);\r\n if (resizeHit) {\r\n const el = ctx.store.getById(resizeHit.elementId);\r\n if (el) {\r\n this.mode = {\r\n type: 'resizing',\r\n elementId: resizeHit.elementId,\r\n handle: resizeHit.handle,\r\n };\r\n ctx.requestRender();\r\n return;\r\n }\r\n }\r\n\r\n const hit = this.hitTest(world, ctx);\r\n if (hit) {\r\n const alreadySelected = this._selectedIds.includes(hit.id);\r\n if (!alreadySelected) {\r\n this._selectedIds = [hit.id];\r\n }\r\n this.mode = hit.locked ? { type: 'idle' } : { type: 'dragging' };\r\n } else {\r\n this._selectedIds = [];\r\n this.mode = { type: 'marquee', start: world };\r\n }\r\n\r\n ctx.requestRender();\r\n }\r\n\r\n onPointerMove(state: PointerState, ctx: ToolContext): void {\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n this.currentWorld = world;\r\n\r\n if (this.mode.type === 'arrow-handle') {\r\n ctx.setCursor?.(getArrowHandleCursor(this.mode.handle, true));\r\n applyArrowHandleDrag(this.mode.handle, this.mode.elementId, world, ctx);\r\n return;\r\n }\r\n\r\n if (this.mode.type === 'resizing') {\r\n ctx.setCursor?.(HANDLE_CURSORS[this.mode.handle]);\r\n this.handleResize(world, ctx);\r\n return;\r\n }\r\n\r\n if (this.mode.type === 'dragging' && this._selectedIds.length > 0) {\r\n ctx.setCursor?.('move');\r\n const snapped = this.snap(world, ctx);\r\n const dx = snapped.x - this.lastWorld.x;\r\n const dy = snapped.y - this.lastWorld.y;\r\n this.lastWorld = snapped;\r\n\r\n for (const id of this._selectedIds) {\r\n const el = ctx.store.getById(id);\r\n if (!el || el.locked) continue;\r\n\r\n if (el.type === 'arrow') {\r\n if (el.fromBinding || el.toBinding) {\r\n // Arrow has bindings — don't allow independent dragging.\r\n // Use handle drag to detach individual endpoints.\r\n continue;\r\n }\r\n\r\n ctx.store.update(id, {\r\n position: { x: el.position.x + dx, y: el.position.y + dy },\r\n from: { x: el.from.x + dx, y: el.from.y + dy },\r\n to: { x: el.to.x + dx, y: el.to.y + dy },\r\n });\r\n } else {\r\n ctx.store.update(id, {\r\n position: { x: el.position.x + dx, y: el.position.y + dy },\r\n });\r\n }\r\n }\r\n\r\n // Update any arrows bound to moved elements\r\n const movedNonArrowIds = new Set<string>();\r\n for (const id of this._selectedIds) {\r\n const el = ctx.store.getById(id);\r\n if (el && el.type !== 'arrow') movedNonArrowIds.add(id);\r\n }\r\n\r\n if (movedNonArrowIds.size > 0) {\r\n const updatedArrows = new Set<string>();\r\n for (const id of movedNonArrowIds) {\r\n const boundArrows = findBoundArrows(id, ctx.store);\r\n for (const ba of boundArrows) {\r\n if (updatedArrows.has(ba.id)) continue;\r\n updatedArrows.add(ba.id);\r\n const updates = updateBoundArrow(ba, ctx.store);\r\n if (updates) ctx.store.update(ba.id, updates);\r\n }\r\n }\r\n }\r\n\r\n ctx.requestRender();\r\n return;\r\n }\r\n\r\n if (this.mode.type === 'marquee') {\r\n ctx.setCursor?.('crosshair');\r\n ctx.requestRender();\r\n return;\r\n }\r\n\r\n this.updateHoverCursor(world, ctx);\r\n }\r\n\r\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\r\n if (this.mode.type === 'marquee') {\r\n const rect = this.getMarqueeRect();\r\n if (rect) {\r\n this._selectedIds = this.findElementsInRect(rect, ctx);\r\n }\r\n ctx.requestRender();\r\n }\r\n\r\n this.mode = { type: 'idle' };\r\n ctx.setCursor?.('default');\r\n }\r\n\r\n onHover(state: PointerState, ctx: ToolContext): void {\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n this.updateHoverCursor(world, ctx);\r\n }\r\n\r\n renderOverlay(canvasCtx: CanvasRenderingContext2D): void {\r\n this.renderMarquee(canvasCtx);\r\n this.renderSelectionBoxes(canvasCtx);\r\n\r\n if (this.mode.type === 'arrow-handle' && this.ctx) {\r\n const target = getArrowHandleDragTarget(\r\n this.mode.handle,\r\n this.mode.elementId,\r\n this.currentWorld,\r\n this.ctx,\r\n );\r\n if (target) {\r\n canvasCtx.save();\r\n canvasCtx.strokeStyle = '#2196F3';\r\n canvasCtx.lineWidth = 2 / this.ctx.camera.zoom;\r\n canvasCtx.setLineDash([]);\r\n canvasCtx.strokeRect(target.x, target.y, target.w, target.h);\r\n canvasCtx.restore();\r\n }\r\n }\r\n }\r\n\r\n private updateHoverCursor(world: Point, ctx: ToolContext): void {\r\n const arrowHit = hitTestArrowHandles(world, this._selectedIds, ctx);\r\n if (arrowHit) {\r\n ctx.setCursor?.(getArrowHandleCursor(arrowHit.handle, false));\r\n return;\r\n }\r\n\r\n const resizeHit = this.hitTestResizeHandle(world, ctx);\r\n if (resizeHit) {\r\n ctx.setCursor?.(HANDLE_CURSORS[resizeHit.handle]);\r\n return;\r\n }\r\n\r\n const hit = this.hitTest(world, ctx);\r\n ctx.setCursor?.(hit ? 'move' : 'default');\r\n }\r\n\r\n private handleResize(world: Point, ctx: ToolContext): void {\r\n if (this.mode.type !== 'resizing') return;\r\n\r\n const el = ctx.store.getById(this.mode.elementId);\r\n if (!el || !('size' in el) || el.locked) return;\r\n\r\n const { handle } = this.mode;\r\n const dx = world.x - this.lastWorld.x;\r\n const dy = world.y - this.lastWorld.y;\r\n this.lastWorld = world;\r\n\r\n let { x, y, w, h } = { x: el.position.x, y: el.position.y, w: el.size.w, h: el.size.h };\r\n\r\n switch (handle) {\r\n case 'se':\r\n w += dx;\r\n h += dy;\r\n break;\r\n case 'sw':\r\n x += dx;\r\n w -= dx;\r\n h += dy;\r\n break;\r\n case 'ne':\r\n y += dy;\r\n w += dx;\r\n h -= dy;\r\n break;\r\n case 'nw':\r\n x += dx;\r\n y += dy;\r\n w -= dx;\r\n h -= dy;\r\n break;\r\n }\r\n\r\n if (w < MIN_ELEMENT_SIZE) {\r\n if (handle === 'nw' || handle === 'sw') x = el.position.x + el.size.w - MIN_ELEMENT_SIZE;\r\n w = MIN_ELEMENT_SIZE;\r\n }\r\n if (h < MIN_ELEMENT_SIZE) {\r\n if (handle === 'nw' || handle === 'ne') y = el.position.y + el.size.h - MIN_ELEMENT_SIZE;\r\n h = MIN_ELEMENT_SIZE;\r\n }\r\n\r\n ctx.store.update(this.mode.elementId, {\r\n position: { x, y },\r\n size: { w, h },\r\n });\r\n\r\n // Update arrows bound to the resized element\r\n const boundArrows = findBoundArrows(this.mode.elementId, ctx.store);\r\n for (const ba of boundArrows) {\r\n const updates = updateBoundArrow(ba, ctx.store);\r\n if (updates) ctx.store.update(ba.id, updates);\r\n }\r\n\r\n ctx.requestRender();\r\n }\r\n\r\n private hitTestResizeHandle(\r\n world: Point,\r\n ctx: ToolContext,\r\n ): { elementId: string; handle: HandlePosition } | null {\r\n if (this._selectedIds.length === 0) return null;\r\n\r\n const zoom = ctx.camera.zoom;\r\n const handleHalf = (HANDLE_SIZE / 2 + HANDLE_HIT_PADDING) / zoom;\r\n\r\n for (const id of this._selectedIds) {\r\n const el = ctx.store.getById(id);\r\n if (!el || !('size' in el)) continue;\r\n\r\n const bounds = this.getElementBounds(el);\r\n if (!bounds) continue;\r\n\r\n const corners = this.getHandlePositions(bounds);\r\n for (const [handle, pos] of corners) {\r\n if (Math.abs(world.x - pos.x) <= handleHalf && Math.abs(world.y - pos.y) <= handleHalf) {\r\n return { elementId: id, handle };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private getHandlePositions(bounds: Rect): [HandlePosition, Point][] {\r\n return [\r\n ['nw', { x: bounds.x, y: bounds.y }],\r\n ['ne', { x: bounds.x + bounds.w, y: bounds.y }],\r\n ['sw', { x: bounds.x, y: bounds.y + bounds.h }],\r\n ['se', { x: bounds.x + bounds.w, y: bounds.y + bounds.h }],\r\n ];\r\n }\r\n\r\n private renderMarquee(canvasCtx: CanvasRenderingContext2D): void {\r\n if (this.mode.type !== 'marquee') return;\r\n\r\n const rect = this.getMarqueeRect();\r\n if (!rect) return;\r\n\r\n canvasCtx.save();\r\n canvasCtx.strokeStyle = '#2196F3';\r\n canvasCtx.fillStyle = 'rgba(33, 150, 243, 0.08)';\r\n canvasCtx.lineWidth = 1;\r\n canvasCtx.setLineDash([4, 4]);\r\n canvasCtx.strokeRect(rect.x, rect.y, rect.w, rect.h);\r\n canvasCtx.fillRect(rect.x, rect.y, rect.w, rect.h);\r\n canvasCtx.restore();\r\n }\r\n\r\n private renderSelectionBoxes(canvasCtx: CanvasRenderingContext2D): void {\r\n if (this._selectedIds.length === 0 || !this.ctx) return;\r\n\r\n const zoom = this.ctx.camera.zoom;\r\n const handleWorldSize = HANDLE_SIZE / zoom;\r\n\r\n canvasCtx.save();\r\n canvasCtx.strokeStyle = '#2196F3';\r\n canvasCtx.lineWidth = 1.5 / zoom;\r\n canvasCtx.setLineDash([4 / zoom, 4 / zoom]);\r\n\r\n for (const id of this._selectedIds) {\r\n const el = this.ctx.store.getById(id);\r\n if (!el) continue;\r\n\r\n if (el.type === 'arrow') {\r\n renderArrowHandles(canvasCtx, el, zoom);\r\n this.renderBindingHighlights(canvasCtx, el, zoom);\r\n continue;\r\n }\r\n\r\n const bounds = this.getElementBounds(el);\r\n if (!bounds) continue;\r\n\r\n const pad = SELECTION_PAD / zoom;\r\n canvasCtx.strokeRect(bounds.x - pad, bounds.y - pad, bounds.w + pad * 2, bounds.h + pad * 2);\r\n\r\n if ('size' in el) {\r\n canvasCtx.setLineDash([]);\r\n canvasCtx.fillStyle = '#ffffff';\r\n const corners = this.getHandlePositions(bounds);\r\n for (const [, pos] of corners) {\r\n canvasCtx.fillRect(\r\n pos.x - handleWorldSize / 2,\r\n pos.y - handleWorldSize / 2,\r\n handleWorldSize,\r\n handleWorldSize,\r\n );\r\n canvasCtx.strokeRect(\r\n pos.x - handleWorldSize / 2,\r\n pos.y - handleWorldSize / 2,\r\n handleWorldSize,\r\n handleWorldSize,\r\n );\r\n }\r\n canvasCtx.setLineDash([4 / zoom, 4 / zoom]);\r\n }\r\n }\r\n\r\n canvasCtx.restore();\r\n }\r\n\r\n private renderBindingHighlights(\r\n canvasCtx: CanvasRenderingContext2D,\r\n arrow: ArrowElement,\r\n zoom: number,\r\n ): void {\r\n if (!this.ctx) return;\r\n if (!arrow.fromBinding && !arrow.toBinding) return;\r\n\r\n const pad = SELECTION_PAD / zoom;\r\n\r\n canvasCtx.save();\r\n canvasCtx.strokeStyle = '#2196F3';\r\n canvasCtx.lineWidth = 2 / zoom;\r\n canvasCtx.setLineDash([]);\r\n\r\n const drawn = new Set<string>();\r\n for (const binding of [arrow.fromBinding, arrow.toBinding]) {\r\n if (!binding || drawn.has(binding.elementId)) continue;\r\n drawn.add(binding.elementId);\r\n\r\n const target = this.ctx.store.getById(binding.elementId);\r\n if (!target) continue;\r\n\r\n const bounds = getElementBounds(target);\r\n if (!bounds) continue;\r\n\r\n canvasCtx.strokeRect(bounds.x - pad, bounds.y - pad, bounds.w + pad * 2, bounds.h + pad * 2);\r\n }\r\n\r\n canvasCtx.restore();\r\n }\r\n\r\n private getMarqueeRect(): Rect | null {\r\n if (this.mode.type !== 'marquee') return null;\r\n\r\n const { start } = this.mode;\r\n const end = this.currentWorld;\r\n const x = Math.min(start.x, end.x);\r\n const y = Math.min(start.y, end.y);\r\n const w = Math.abs(end.x - start.x);\r\n const h = Math.abs(end.y - start.y);\r\n\r\n if (w === 0 && h === 0) return null;\r\n return { x, y, w, h };\r\n }\r\n\r\n private findElementsInRect(marquee: Rect, ctx: ToolContext): string[] {\r\n const ids: string[] = [];\r\n for (const el of ctx.store.getAll()) {\r\n if (ctx.isLayerVisible && !ctx.isLayerVisible(el.layerId)) continue;\r\n if (ctx.isLayerLocked && ctx.isLayerLocked(el.layerId)) continue;\r\n if (el.type === 'grid') continue;\r\n const bounds = this.getElementBounds(el);\r\n if (bounds && this.rectsOverlap(marquee, bounds)) {\r\n ids.push(el.id);\r\n }\r\n }\r\n return ids;\r\n }\r\n\r\n private rectsOverlap(a: Rect, b: Rect): boolean {\r\n return a.x <= b.x + b.w && a.x + a.w >= b.x && a.y <= b.y + b.h && a.y + a.h >= b.y;\r\n }\r\n\r\n private getElementBounds(el: CanvasElement): Rect | null {\r\n if ('size' in el) {\r\n return { x: el.position.x, y: el.position.y, w: el.size.w, h: el.size.h };\r\n }\r\n if (el.type === 'stroke' && el.points.length > 0) {\r\n let minX = Infinity,\r\n minY = Infinity,\r\n maxX = -Infinity,\r\n maxY = -Infinity;\r\n for (const p of el.points) {\r\n const px = p.x + el.position.x;\r\n const py = p.y + el.position.y;\r\n if (px < minX) minX = px;\r\n if (py < minY) minY = py;\r\n if (px > maxX) maxX = px;\r\n if (py > maxY) maxY = py;\r\n }\r\n return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };\r\n }\r\n if (el.type === 'arrow') {\r\n return getArrowBounds(el.from, el.to, el.bend);\r\n }\r\n return null;\r\n }\r\n\r\n private hitTest(world: Point, ctx: ToolContext): CanvasElement | null {\r\n const elements = ctx.store.getAll().reverse();\r\n for (const el of elements) {\r\n if (ctx.isLayerVisible && !ctx.isLayerVisible(el.layerId)) continue;\r\n if (ctx.isLayerLocked && ctx.isLayerLocked(el.layerId)) continue;\r\n if (el.type === 'grid') continue;\r\n if (this.isInsideBounds(world, el)) return el;\r\n }\r\n return null;\r\n }\r\n\r\n private isInsideBounds(point: Point, el: CanvasElement): boolean {\r\n if (el.type === 'grid') return false;\r\n if ('size' in el) {\r\n const s = el.size;\r\n return (\r\n point.x >= el.position.x &&\r\n point.x <= el.position.x + s.w &&\r\n point.y >= el.position.y &&\r\n point.y <= el.position.y + s.h\r\n );\r\n }\r\n\r\n if (el.type === 'stroke') {\r\n const HIT_RADIUS = 10;\r\n return el.points.some((p) => {\r\n const dx = p.x + el.position.x - point.x;\r\n const dy = p.y + el.position.y - point.y;\r\n return dx * dx + dy * dy <= HIT_RADIUS * HIT_RADIUS;\r\n });\r\n }\r\n\r\n if (el.type === 'arrow') {\r\n return isNearBezier(point, el.from, el.to, el.bend, 10);\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n","import type { Point } from '../core/types';\r\nimport type { Binding, CanvasElement } from '../elements/types';\r\nimport type { Tool, ToolContext, PointerState } from './types';\r\nimport { createArrow } from '../elements/element-factory';\r\nimport { findBindTarget, getElementCenter, getElementBounds } from '../elements/arrow-binding';\r\nimport { snapPoint } from '../core/snap';\r\n\r\nconst BIND_THRESHOLD = 20;\r\n\r\nexport interface ArrowToolOptions {\r\n color?: string;\r\n width?: number;\r\n}\r\n\r\nexport class ArrowTool implements Tool {\r\n readonly name = 'arrow';\r\n private drawing = false;\r\n private start: Point = { x: 0, y: 0 };\r\n private end: Point = { x: 0, y: 0 };\r\n private color: string;\r\n private width: number;\r\n private fromBinding: Binding | undefined;\r\n private fromTarget: CanvasElement | null = null;\r\n private toTarget: CanvasElement | null = null;\r\n\r\n constructor(options: ArrowToolOptions = {}) {\r\n this.color = options.color ?? '#000000';\r\n this.width = options.width ?? 2;\r\n }\r\n\r\n setOptions(options: ArrowToolOptions): void {\r\n if (options.color !== undefined) this.color = options.color;\r\n if (options.width !== undefined) this.width = options.width;\r\n }\r\n\r\n private layerFilter(ctx: ToolContext): ((el: CanvasElement) => boolean) | undefined {\r\n const activeLayerId = ctx.activeLayerId;\r\n if (!activeLayerId && !ctx.isLayerVisible && !ctx.isLayerLocked) return undefined;\r\n return (el: CanvasElement) => {\r\n if (activeLayerId && el.layerId !== activeLayerId) return false;\r\n if (ctx.isLayerVisible && !ctx.isLayerVisible(el.layerId)) return false;\r\n if (ctx.isLayerLocked && ctx.isLayerLocked(el.layerId)) return false;\r\n return true;\r\n };\r\n }\r\n\r\n onPointerDown(state: PointerState, ctx: ToolContext): void {\r\n this.drawing = true;\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n const threshold = BIND_THRESHOLD / ctx.camera.zoom;\r\n const filter = this.layerFilter(ctx);\r\n\r\n const target = findBindTarget(world, ctx.store, threshold, undefined, filter);\r\n if (target) {\r\n this.start = getElementCenter(target);\r\n this.fromBinding = { elementId: target.id };\r\n this.fromTarget = target;\r\n } else {\r\n this.start = ctx.snapToGrid && ctx.gridSize ? snapPoint(world, ctx.gridSize) : world;\r\n this.fromBinding = undefined;\r\n this.fromTarget = null;\r\n }\r\n this.end = { ...this.start };\r\n this.toTarget = null;\r\n }\r\n\r\n onPointerMove(state: PointerState, ctx: ToolContext): void {\r\n if (!this.drawing) return;\r\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n const threshold = BIND_THRESHOLD / ctx.camera.zoom;\r\n const excludeId = this.fromBinding?.elementId;\r\n const filter = this.layerFilter(ctx);\r\n\r\n const target = findBindTarget(world, ctx.store, threshold, excludeId, filter);\r\n if (target) {\r\n this.end = getElementCenter(target);\r\n this.toTarget = target;\r\n } else {\r\n this.end = ctx.snapToGrid && ctx.gridSize ? snapPoint(world, ctx.gridSize) : world;\r\n this.toTarget = null;\r\n }\r\n ctx.requestRender();\r\n }\r\n\r\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\r\n if (!this.drawing) return;\r\n this.drawing = false;\r\n\r\n if (this.start.x === this.end.x && this.start.y === this.end.y) return;\r\n\r\n const arrow = createArrow({\r\n from: this.start,\r\n to: this.end,\r\n position: this.start,\r\n color: this.color,\r\n width: this.width,\r\n fromBinding: this.fromBinding,\r\n toBinding: this.toTarget ? { elementId: this.toTarget.id } : undefined,\r\n layerId: ctx.activeLayerId ?? '',\r\n });\r\n ctx.store.add(arrow);\r\n this.fromTarget = null;\r\n this.toTarget = null;\r\n ctx.requestRender();\r\n ctx.switchTool?.('select');\r\n }\r\n\r\n renderOverlay(ctx: CanvasRenderingContext2D): void {\r\n if (!this.drawing) return;\r\n if (this.start.x === this.end.x && this.start.y === this.end.y) return;\r\n\r\n ctx.save();\r\n\r\n if (this.fromTarget) {\r\n const bounds = getElementBounds(this.fromTarget);\r\n if (bounds) {\r\n ctx.strokeStyle = '#2196F3';\r\n ctx.lineWidth = 2;\r\n ctx.setLineDash([]);\r\n ctx.strokeRect(bounds.x, bounds.y, bounds.w, bounds.h);\r\n }\r\n }\r\n\r\n if (this.toTarget) {\r\n const bounds = getElementBounds(this.toTarget);\r\n if (bounds) {\r\n ctx.strokeStyle = '#2196F3';\r\n ctx.lineWidth = 2;\r\n ctx.setLineDash([]);\r\n ctx.strokeRect(bounds.x, bounds.y, bounds.w, bounds.h);\r\n }\r\n }\r\n\r\n ctx.strokeStyle = this.color;\r\n ctx.lineWidth = this.width;\r\n ctx.lineCap = 'round';\r\n ctx.globalAlpha = 0.6;\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(this.start.x, this.start.y);\r\n ctx.lineTo(this.end.x, this.end.y);\r\n ctx.stroke();\r\n\r\n const angle = Math.atan2(this.end.y - this.start.y, this.end.x - this.start.x);\r\n const headLen = 12;\r\n const headAngle = Math.PI / 6;\r\n\r\n ctx.fillStyle = this.color;\r\n ctx.beginPath();\r\n ctx.moveTo(this.end.x, this.end.y);\r\n ctx.lineTo(\r\n this.end.x - headLen * Math.cos(angle - headAngle),\r\n this.end.y - headLen * Math.sin(angle - headAngle),\r\n );\r\n ctx.lineTo(\r\n this.end.x - headLen * Math.cos(angle + headAngle),\r\n this.end.y - headLen * Math.sin(angle + headAngle),\r\n );\r\n ctx.closePath();\r\n ctx.fill();\r\n ctx.restore();\r\n }\r\n}\r\n","import type { Size } from '../core/types';\r\nimport type { Tool, ToolContext, PointerState } from './types';\r\nimport { createNote } from '../elements/element-factory';\r\nimport { snapPoint } from '../core/snap';\r\n\r\nexport interface NoteToolOptions {\r\n backgroundColor?: string;\r\n textColor?: string;\r\n size?: Size;\r\n}\r\n\r\nexport class NoteTool implements Tool {\r\n readonly name = 'note';\r\n private backgroundColor: string;\r\n private textColor: string;\r\n private size: Size;\r\n\r\n constructor(options: NoteToolOptions = {}) {\r\n this.backgroundColor = options.backgroundColor ?? '#ffeb3b';\r\n this.textColor = options.textColor ?? '#000000';\r\n this.size = options.size ?? { w: 200, h: 100 };\r\n }\r\n\r\n setOptions(options: NoteToolOptions): void {\r\n if (options.backgroundColor !== undefined) this.backgroundColor = options.backgroundColor;\r\n if (options.textColor !== undefined) this.textColor = options.textColor;\r\n if (options.size !== undefined) this.size = options.size;\r\n }\r\n\r\n onPointerDown(_state: PointerState, _ctx: ToolContext): void {\r\n // Note is placed on pointer up\r\n }\r\n\r\n onPointerMove(_state: PointerState, _ctx: ToolContext): void {\r\n // No drag behavior for note placement\r\n }\r\n\r\n onPointerUp(state: PointerState, ctx: ToolContext): void {\r\n let world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n if (ctx.snapToGrid && ctx.gridSize) {\r\n world = snapPoint(world, ctx.gridSize);\r\n }\r\n const note = createNote({\r\n position: world,\r\n size: { ...this.size },\r\n backgroundColor: this.backgroundColor,\r\n textColor: this.textColor,\r\n layerId: ctx.activeLayerId ?? '',\r\n });\r\n ctx.store.add(note);\r\n ctx.requestRender();\r\n\r\n ctx.switchTool?.('select');\r\n ctx.editElement?.(note.id);\r\n }\r\n}\r\n","import type { Tool, ToolContext, PointerState } from './types';\r\nimport { createText } from '../elements/element-factory';\r\nimport { snapPoint } from '../core/snap';\r\n\r\nexport interface TextToolOptions {\r\n fontSize?: number;\r\n color?: string;\r\n textAlign?: 'left' | 'center' | 'right';\r\n}\r\n\r\nexport class TextTool implements Tool {\r\n readonly name = 'text';\r\n private fontSize: number;\r\n private color: string;\r\n private textAlign: 'left' | 'center' | 'right';\r\n\r\n constructor(options: TextToolOptions = {}) {\r\n this.fontSize = options.fontSize ?? 16;\r\n this.color = options.color ?? '#1a1a1a';\r\n this.textAlign = options.textAlign ?? 'left';\r\n }\r\n\r\n setOptions(options: TextToolOptions): void {\r\n if (options.fontSize !== undefined) this.fontSize = options.fontSize;\r\n if (options.color !== undefined) this.color = options.color;\r\n if (options.textAlign !== undefined) this.textAlign = options.textAlign;\r\n }\r\n\r\n onActivate(ctx: ToolContext): void {\r\n ctx.setCursor?.('text');\r\n }\r\n\r\n onDeactivate(ctx: ToolContext): void {\r\n ctx.setCursor?.('default');\r\n }\r\n\r\n onPointerDown(_state: PointerState, _ctx: ToolContext): void {\r\n // Text is placed on pointer up\r\n }\r\n\r\n onPointerMove(_state: PointerState, _ctx: ToolContext): void {\r\n // No drag behavior for text placement\r\n }\r\n\r\n onPointerUp(state: PointerState, ctx: ToolContext): void {\r\n let world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\r\n if (ctx.snapToGrid && ctx.gridSize) {\r\n world = snapPoint(world, ctx.gridSize);\r\n }\r\n const textEl = createText({\r\n position: world,\r\n fontSize: this.fontSize,\r\n color: this.color,\r\n textAlign: this.textAlign,\r\n layerId: ctx.activeLayerId ?? '',\r\n });\r\n ctx.store.add(textEl);\r\n ctx.requestRender();\r\n\r\n ctx.switchTool?.('select');\r\n ctx.editElement?.(textEl.id);\r\n }\r\n}\r\n","import type { Size } from '../core/types';\nimport type { Tool, ToolContext, PointerState } from './types';\nimport { createImage } from '../elements/element-factory';\n\nexport interface ImageToolOptions {\n size?: Size;\n}\n\nexport class ImageTool implements Tool {\n readonly name = 'image';\n private size: Size;\n private src: string | null = null;\n\n constructor(options: ImageToolOptions = {}) {\n this.size = options.size ?? { w: 300, h: 200 };\n }\n\n setSrc(src: string): void {\n this.src = src;\n }\n\n onPointerDown(_state: PointerState, _ctx: ToolContext): void {\n // No action on pointer down — image is placed on pointer up\n }\n\n onPointerMove(_state: PointerState, _ctx: ToolContext): void {\n // No action on pointer move\n }\n\n onPointerUp(state: PointerState, ctx: ToolContext): void {\n if (!this.src) return;\n\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\n const image = createImage({\n position: world,\n size: { ...this.size },\n src: this.src,\n });\n ctx.store.add(image);\n ctx.requestRender();\n\n this.src = null;\n ctx.switchTool?.('select');\n }\n}\n","import type { Point } from '../core/types';\r\nimport type { ShapeKind } from '../elements/types';\r\nimport type { Tool, ToolContext, PointerState } from './types';\r\nimport { createShape } from '../elements/element-factory';\r\nimport { snapPoint } from '../core/snap';\r\n\r\nexport interface ShapeToolOptions {\r\n shape?: ShapeKind;\r\n strokeColor?: string;\r\n strokeWidth?: number;\r\n fillColor?: string;\r\n}\r\n\r\nexport class ShapeTool implements Tool {\r\n readonly name = 'shape';\r\n private drawing = false;\r\n private start: Point = { x: 0, y: 0 };\r\n private end: Point = { x: 0, y: 0 };\r\n private shiftHeld = false;\r\n private shape: ShapeKind;\r\n private strokeColor: string;\r\n private strokeWidth: number;\r\n private fillColor: string;\r\n\r\n constructor(options: ShapeToolOptions = {}) {\r\n this.shape = options.shape ?? 'rectangle';\r\n this.strokeColor = options.strokeColor ?? '#000000';\r\n this.strokeWidth = options.strokeWidth ?? 2;\r\n this.fillColor = options.fillColor ?? 'none';\r\n }\r\n\r\n setOptions(options: ShapeToolOptions): void {\r\n if (options.shape !== undefined) this.shape = options.shape;\r\n if (options.strokeColor !== undefined) this.strokeColor = options.strokeColor;\r\n if (options.strokeWidth !== undefined) this.strokeWidth = options.strokeWidth;\r\n if (options.fillColor !== undefined) this.fillColor = options.fillColor;\r\n }\r\n\r\n onActivate(_ctx: ToolContext): void {\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('keydown', this.onKeyDown);\r\n window.addEventListener('keyup', this.onKeyUp);\r\n }\r\n }\r\n\r\n onDeactivate(_ctx: ToolContext): void {\r\n this.shiftHeld = false;\r\n if (typeof window !== 'undefined') {\r\n window.removeEventListener('keydown', this.onKeyDown);\r\n window.removeEventListener('keyup', this.onKeyUp);\r\n }\r\n }\r\n\r\n onPointerDown(state: PointerState, ctx: ToolContext): void {\r\n this.drawing = true;\r\n this.start = this.snap(ctx.camera.screenToWorld({ x: state.x, y: state.y }), ctx);\r\n this.end = { ...this.start };\r\n }\r\n\r\n onPointerMove(state: PointerState, ctx: ToolContext): void {\r\n if (!this.drawing) return;\r\n this.end = this.snap(ctx.camera.screenToWorld({ x: state.x, y: state.y }), ctx);\r\n ctx.requestRender();\r\n }\r\n\r\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\r\n if (!this.drawing) return;\r\n this.drawing = false;\r\n\r\n const { position, size } = this.computeRect();\r\n if (size.w === 0 || size.h === 0) return;\r\n\r\n const shape = createShape({\r\n position,\r\n size,\r\n shape: this.shape,\r\n strokeColor: this.strokeColor,\r\n strokeWidth: this.strokeWidth,\r\n fillColor: this.fillColor,\r\n layerId: ctx.activeLayerId ?? '',\r\n });\r\n ctx.store.add(shape);\r\n ctx.requestRender();\r\n ctx.switchTool?.('select');\r\n }\r\n\r\n renderOverlay(ctx: CanvasRenderingContext2D): void {\r\n if (!this.drawing) return;\r\n\r\n const { position, size } = this.computeRect();\r\n if (size.w === 0 && size.h === 0) return;\r\n\r\n ctx.save();\r\n ctx.globalAlpha = 0.5;\r\n ctx.strokeStyle = this.strokeColor;\r\n ctx.lineWidth = this.strokeWidth;\r\n\r\n if (this.fillColor !== 'none') {\r\n ctx.fillStyle = this.fillColor;\r\n }\r\n\r\n switch (this.shape) {\r\n case 'rectangle':\r\n if (this.fillColor !== 'none') {\r\n ctx.fillRect(position.x, position.y, size.w, size.h);\r\n }\r\n ctx.strokeRect(position.x, position.y, size.w, size.h);\r\n break;\r\n case 'ellipse': {\r\n const cx = position.x + size.w / 2;\r\n const cy = position.y + size.h / 2;\r\n ctx.beginPath();\r\n ctx.ellipse(cx, cy, size.w / 2, size.h / 2, 0, 0, Math.PI * 2);\r\n if (this.fillColor !== 'none') ctx.fill();\r\n ctx.stroke();\r\n break;\r\n }\r\n }\r\n\r\n ctx.restore();\r\n }\r\n\r\n private computeRect(): { position: Point; size: { w: number; h: number } } {\r\n let x = Math.min(this.start.x, this.end.x);\r\n let y = Math.min(this.start.y, this.end.y);\r\n let w = Math.abs(this.end.x - this.start.x);\r\n let h = Math.abs(this.end.y - this.start.y);\r\n\r\n if (this.shiftHeld) {\r\n const side = Math.max(w, h);\r\n w = side;\r\n h = side;\r\n x = this.end.x >= this.start.x ? this.start.x : this.start.x - side;\r\n y = this.end.y >= this.start.y ? this.start.y : this.start.y - side;\r\n }\r\n\r\n return { position: { x, y }, size: { w, h } };\r\n }\r\n\r\n private snap(point: Point, ctx: ToolContext): Point {\r\n return ctx.snapToGrid && ctx.gridSize ? snapPoint(point, ctx.gridSize) : point;\r\n }\r\n\r\n private onKeyDown = (e: KeyboardEvent): void => {\r\n if (e.key === 'Shift') this.shiftHeld = true;\r\n };\r\n\r\n private onKeyUp = (e: KeyboardEvent): void => {\r\n if (e.key === 'Shift') this.shiftHeld = false;\r\n };\r\n}\r\n","import type { ElementStore } from '../elements/element-store';\r\nimport type { Command } from './types';\r\nimport type { LayerManager } from '../layers/layer-manager';\r\nimport type { Layer } from '../layers/types';\r\n\r\nexport class CreateLayerCommand implements Command {\r\n constructor(\r\n private readonly manager: LayerManager,\r\n private readonly layer: Layer,\r\n ) {}\r\n\r\n execute(_store: ElementStore): void {\r\n this.manager.addLayerDirect(this.layer);\r\n }\r\n\r\n undo(_store: ElementStore): void {\r\n this.manager.removeLayerDirect(this.layer.id);\r\n }\r\n}\r\n\r\nexport class RemoveLayerCommand implements Command {\r\n constructor(\r\n private readonly manager: LayerManager,\r\n private readonly layer: Layer,\r\n ) {}\r\n\r\n execute(_store: ElementStore): void {\r\n this.manager.removeLayerDirect(this.layer.id);\r\n }\r\n\r\n undo(_store: ElementStore): void {\r\n this.manager.addLayerDirect(this.layer);\r\n }\r\n}\r\n\r\nexport class UpdateLayerCommand implements Command {\r\n constructor(\r\n private readonly manager: LayerManager,\r\n private readonly layerId: string,\r\n private readonly previous: Layer,\r\n private readonly current: Layer,\r\n ) {}\r\n\r\n execute(_store: ElementStore): void {\r\n this.manager.updateLayerDirect(this.layerId, { ...this.current });\r\n }\r\n\r\n undo(_store: ElementStore): void {\r\n this.manager.updateLayerDirect(this.layerId, { ...this.previous });\r\n }\r\n}\r\n"],"mappings":"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","names":["minX","minY","HANDLE_HIT_PADDING","BIND_THRESHOLD"]}