@fieldnotes/core 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/core/event-bus.ts","../src/core/state-serializer.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/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/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/image-tool.ts"],"sourcesContent":["export const VERSION = '0.1.0';\n\nexport { EventBus } from './core/event-bus';\nexport type { Point, Size, Bounds } from './core/types';\nexport { exportState, parseState } from './core/state-serializer';\nexport type { CanvasState } from './core/state-serializer';\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';\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} from './elements/element-factory';\nexport {\n getArrowControlPoint,\n getArrowMidpoint,\n getBendFromPoint,\n getArrowTangentAngle,\n isNearBezier,\n getArrowBounds,\n} from './elements/arrow-geometry';\nexport type {\n CanvasElement,\n ElementType,\n StrokeElement,\n NoteElement,\n ArrowElement,\n ImageElement,\n HtmlElement,\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 { ImageTool } from './tools/image-tool';\nexport type { ImageToolOptions } from './tools/image-tool';\nexport type { Tool, ToolContext, PointerState, ToolName } from './tools/types';\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';\nimport type { Point } from './types';\n\nexport interface CanvasState {\n version: number;\n camera: {\n position: Point;\n zoom: number;\n };\n elements: CanvasElement[];\n}\n\nconst CURRENT_VERSION = 1;\n\nexport function exportState(\n elements: CanvasElement[],\n camera: { position: Point; zoom: number },\n): CanvasState {\n return {\n version: CURRENT_VERSION,\n camera: {\n position: { ...camera.position },\n zoom: camera.zoom,\n },\n elements: elements.map((el) => structuredClone(el)),\n };\n}\n\nexport function parseState(json: string): CanvasState {\n const data: unknown = JSON.parse(json);\n validateState(data);\n return data;\n}\n\nfunction validateState(data: unknown): asserts data is CanvasState {\n if (!data || typeof data !== 'object') {\n throw new Error('Invalid state: expected an object');\n }\n\n const obj = data as Record<string, unknown>;\n\n if (typeof obj['version'] !== 'number') {\n throw new Error('Invalid state: missing or invalid version');\n }\n\n if (!obj['camera'] || typeof obj['camera'] !== 'object') {\n throw new Error('Invalid state: missing camera');\n }\n\n const cam = obj['camera'] as Record<string, unknown>;\n if (!cam['position'] || typeof cam['position'] !== 'object') {\n throw new Error('Invalid state: missing camera.position');\n }\n\n const pos = cam['position'] as Record<string, unknown>;\n if (typeof pos['x'] !== 'number' || typeof pos['y'] !== 'number') {\n throw new Error('Invalid state: camera.position must have x and y numbers');\n }\n\n if (typeof cam['zoom'] !== 'number') {\n throw new Error('Invalid state: missing camera.zoom');\n }\n\n if (!Array.isArray(obj['elements'])) {\n throw new Error('Invalid state: elements must be an array');\n }\n\n for (const el of obj['elements'] as unknown[]) {\n validateElement(el);\n migrateElement(el as unknown as Record<string, unknown>);\n }\n}\n\nconst VALID_TYPES = new Set(['stroke', 'note', 'arrow', 'image', 'html']);\n\nfunction validateElement(el: unknown): asserts el is CanvasElement {\n if (!el || typeof el !== 'object') {\n throw new Error('Invalid element: expected an object');\n }\n\n const obj = el as Record<string, unknown>;\n\n if (typeof obj['id'] !== 'string') {\n throw new Error('Invalid element: missing id');\n }\n\n if (typeof obj['type'] !== 'string' || !VALID_TYPES.has(obj['type'])) {\n throw new Error(`Invalid element: unknown type \"${String(obj['type'])}\"`);\n }\n\n if (typeof obj['zIndex'] !== 'number') {\n throw new Error('Invalid element: missing zIndex');\n }\n}\n\nfunction migrateElement(obj: Record<string, unknown>): void {\n if (obj['type'] === 'arrow' && typeof obj['bend'] !== 'number') {\n obj['bend'] = 0;\n }\n}\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';\n\nexport type BackgroundPattern = 'dots' | 'grid' | 'none';\n\nexport interface BackgroundOptions {\n pattern?: BackgroundPattern;\n spacing?: number;\n color?: string;\n dotRadius?: number;\n lineWidth?: number;\n}\n\nconst DEFAULTS = {\n pattern: 'dots' as BackgroundPattern,\n spacing: 24,\n color: '#d0d0d0',\n dotRadius: 1,\n lineWidth: 0.5,\n};\n\nexport class Background {\n private readonly pattern: BackgroundPattern;\n private readonly spacing: number;\n private readonly color: string;\n private readonly dotRadius: number;\n private readonly lineWidth: number;\n\n constructor(options: BackgroundOptions = {}) {\n this.pattern = options.pattern ?? DEFAULTS.pattern;\n this.spacing = options.spacing ?? DEFAULTS.spacing;\n this.color = options.color ?? DEFAULTS.color;\n this.dotRadius = options.dotRadius ?? DEFAULTS.dotRadius;\n this.lineWidth = options.lineWidth ?? DEFAULTS.lineWidth;\n }\n\n render(ctx: CanvasRenderingContext2D, camera: Camera): void {\n const { width, height } = ctx.canvas;\n const dpr = typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;\n const cssWidth = width / dpr;\n const cssHeight = height / dpr;\n ctx.save();\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.clearRect(0, 0, cssWidth, cssHeight);\n\n if (this.pattern === 'dots') {\n this.renderDots(ctx, camera, cssWidth, cssHeight);\n } else if (this.pattern === 'grid') {\n this.renderGrid(ctx, camera, cssWidth, cssHeight);\n }\n\n ctx.restore();\n }\n\n private renderDots(\n ctx: CanvasRenderingContext2D,\n camera: Camera,\n width: number,\n height: number,\n ): void {\n const spacing = this.spacing * camera.zoom;\n const offsetX = camera.position.x % spacing;\n const offsetY = camera.position.y % spacing;\n const radius = this.dotRadius * Math.min(camera.zoom, 2);\n\n ctx.fillStyle = this.color;\n ctx.beginPath();\n\n for (let x = offsetX; x < width; x += spacing) {\n for (let y = offsetY; y < height; y += spacing) {\n ctx.moveTo(x + radius, y);\n ctx.arc(x, y, radius, 0, Math.PI * 2);\n }\n }\n\n ctx.fill();\n }\n\n private renderGrid(\n ctx: CanvasRenderingContext2D,\n camera: Camera,\n width: number,\n height: number,\n ): void {\n const spacing = this.spacing * camera.zoom;\n const offsetX = camera.position.x % spacing;\n const offsetY = camera.position.y % spacing;\n const lineW = this.lineWidth * Math.min(camera.zoom, 2);\n\n ctx.fillStyle = this.color;\n\n for (let x = offsetX; x < width; x += spacing) {\n ctx.fillRect(x, 0, lineW, height);\n }\n\n for (let y = offsetY; y < height; y += spacing) {\n ctx.fillRect(0, y, width, lineW);\n }\n }\n}\n","import type { Camera } from './camera';\nimport type { ToolManager } from '../tools/tool-manager';\nimport type { ToolContext, PointerState } from '../tools/types';\nimport type { SelectTool } from '../tools/select-tool';\nimport type { HistoryRecorder } from '../history/history-recorder';\nimport type { HistoryStack } from '../history/history-stack';\n\nconst ZOOM_SENSITIVITY = 0.001;\nconst MIDDLE_BUTTON = 1;\n\nexport interface InputHandlerOptions {\n toolManager?: ToolManager;\n toolContext?: ToolContext;\n historyRecorder?: HistoryRecorder;\n historyStack?: HistoryStack;\n}\n\nexport class InputHandler {\n private isPanning = false;\n private lastPointer = { x: 0, y: 0 };\n private spaceHeld = false;\n private activePointers = new Map<number, { x: number; y: number }>();\n private lastPinchDistance = 0;\n private lastPinchCenter = { x: 0, y: 0 };\n private toolManager: ToolManager | null;\n private toolContext: ToolContext | null;\n private historyRecorder: HistoryRecorder | null;\n private historyStack: HistoryStack | null;\n private isToolActive = false;\n private readonly abortController = new AbortController();\n\n constructor(\n private readonly element: HTMLElement,\n private readonly camera: Camera,\n options: InputHandlerOptions = {},\n ) {\n this.toolManager = options.toolManager ?? null;\n this.toolContext = options.toolContext ?? null;\n this.historyRecorder = options.historyRecorder ?? null;\n this.historyStack = options.historyStack ?? null;\n this.element.style.touchAction = 'none';\n this.bind();\n }\n\n setToolManager(toolManager: ToolManager, toolContext: ToolContext): void {\n this.toolManager = toolManager;\n this.toolContext = toolContext;\n }\n\n destroy(): void {\n this.abortController.abort();\n }\n\n private bind(): void {\n const opts = { signal: this.abortController.signal };\n\n this.element.addEventListener('wheel', this.onWheel, { ...opts, passive: false });\n this.element.addEventListener('pointerdown', this.onPointerDown, opts);\n this.element.addEventListener('pointermove', this.onPointerMove, opts);\n this.element.addEventListener('pointerup', this.onPointerUp, opts);\n this.element.addEventListener('pointerleave', this.onPointerUp, opts);\n this.element.addEventListener('pointercancel', this.onPointerUp, opts);\n window.addEventListener('keydown', this.onKeyDown, opts);\n window.addEventListener('keyup', this.onKeyUp, opts);\n }\n\n private onWheel = (e: WheelEvent): void => {\n e.preventDefault();\n const zoomFactor = 1 - e.deltaY * ZOOM_SENSITIVITY;\n const newZoom = this.camera.zoom * zoomFactor;\n this.camera.zoomAt(newZoom, { x: e.clientX, y: e.clientY });\n };\n\n private isInteractiveHtmlContent(e: PointerEvent): boolean {\n const target = e.target as HTMLElement | null;\n if (!target) return false;\n\n const node = target.closest<HTMLDivElement>('[data-element-id]');\n if (!node) return false;\n\n const elementId = node.dataset['elementId'];\n if (!elementId) return false;\n\n const store = this.toolContext?.store;\n if (!store) return false;\n\n const element = store.getById(elementId);\n if (!element || element.type !== 'html') return false;\n\n return true;\n }\n\n private onPointerDown = (e: PointerEvent): void => {\n this.activePointers.set(e.pointerId, { x: e.clientX, y: e.clientY });\n\n if (this.isInteractiveHtmlContent(e)) {\n return;\n }\n\n this.element.setPointerCapture?.(e.pointerId);\n\n if (this.activePointers.size === 2) {\n this.startPinch();\n this.cancelToolIfActive(e);\n return;\n }\n\n if (e.button === MIDDLE_BUTTON || (e.button === 0 && this.spaceHeld)) {\n this.isPanning = true;\n this.lastPointer = { x: e.clientX, y: e.clientY };\n return;\n }\n\n if (this.activePointers.size === 1 && e.button === 0) {\n this.dispatchToolDown(e);\n }\n };\n\n private onPointerMove = (e: PointerEvent): void => {\n if (this.activePointers.has(e.pointerId)) {\n this.activePointers.set(e.pointerId, { x: e.clientX, y: e.clientY });\n }\n\n if (this.activePointers.size === 2) {\n this.handlePinchMove();\n return;\n }\n\n if (this.isPanning) {\n const dx = e.clientX - this.lastPointer.x;\n const dy = e.clientY - this.lastPointer.y;\n this.lastPointer = { x: e.clientX, y: e.clientY };\n this.camera.pan(dx, dy);\n return;\n }\n\n if (this.isToolActive) {\n this.dispatchToolMove(e);\n } else if (this.activePointers.size === 0) {\n this.dispatchToolHover(e);\n }\n };\n\n private onPointerUp = (e: PointerEvent): void => {\n this.activePointers.delete(e.pointerId);\n\n if (this.activePointers.size < 2) {\n this.lastPinchDistance = 0;\n }\n\n if (this.isPanning && this.activePointers.size === 0) {\n this.isPanning = false;\n }\n\n if (this.isToolActive) {\n this.dispatchToolUp(e);\n this.isToolActive = false;\n }\n };\n\n private onKeyDown = (e: KeyboardEvent): void => {\n if ((e.target as HTMLElement)?.isContentEditable) return;\n\n if (e.key === ' ') {\n this.spaceHeld = true;\n }\n if (e.key === 'Delete' || e.key === 'Backspace') {\n this.deleteSelected();\n }\n if ((e.ctrlKey || e.metaKey) && e.key === 'z' && !e.shiftKey) {\n e.preventDefault();\n this.handleUndo();\n }\n if ((e.ctrlKey || e.metaKey) && (e.key === 'y' || (e.key === 'z' && e.shiftKey))) {\n e.preventDefault();\n this.handleRedo();\n }\n };\n\n private onKeyUp = (e: KeyboardEvent): void => {\n if (e.key === ' ') {\n this.spaceHeld = false;\n }\n };\n\n private startPinch(): void {\n this.isPanning = true;\n const [a, b] = this.getPinchPoints();\n this.lastPinchDistance = this.distance(a, b);\n this.lastPinchCenter = this.midpoint(a, b);\n this.lastPointer = { ...this.lastPinchCenter };\n }\n\n private handlePinchMove(): void {\n const [a, b] = this.getPinchPoints();\n const dist = this.distance(a, b);\n const center = this.midpoint(a, b);\n\n if (this.lastPinchDistance > 0) {\n const scale = dist / this.lastPinchDistance;\n const newZoom = this.camera.zoom * scale;\n this.camera.zoomAt(newZoom, center);\n }\n\n const dx = center.x - this.lastPointer.x;\n const dy = center.y - this.lastPointer.y;\n this.camera.pan(dx, dy);\n\n this.lastPinchDistance = dist;\n this.lastPinchCenter = center;\n this.lastPointer = { ...center };\n }\n\n private getPinchPoints(): [{ x: number; y: number }, { x: number; y: number }] {\n const pts = [...this.activePointers.values()];\n return [pts[0] ?? { x: 0, y: 0 }, pts[1] ?? { x: 0, y: 0 }];\n }\n\n private distance(a: { x: number; y: number }, b: { x: number; y: number }): number {\n const dx = a.x - b.x;\n const dy = a.y - b.y;\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n private midpoint(\n a: { x: number; y: number },\n b: { x: number; y: number },\n ): { x: number; y: number } {\n return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\n }\n\n private toPointerState(e: PointerEvent): PointerState {\n return { x: e.clientX, y: e.clientY, pressure: e.pressure };\n }\n\n private dispatchToolDown(e: PointerEvent): void {\n if (!this.toolManager || !this.toolContext) return;\n this.historyRecorder?.begin();\n this.isToolActive = true;\n this.toolManager.handlePointerDown(this.toPointerState(e), this.toolContext);\n }\n\n private dispatchToolMove(e: PointerEvent): void {\n if (!this.toolManager || !this.toolContext) return;\n this.toolManager.handlePointerMove(this.toPointerState(e), this.toolContext);\n }\n\n private dispatchToolHover(e: PointerEvent): void {\n if (!this.toolManager?.activeTool || !this.toolContext) return;\n const tool = this.toolManager.activeTool;\n if (tool.onHover) {\n tool.onHover(this.toPointerState(e), this.toolContext);\n }\n }\n\n private dispatchToolUp(e: PointerEvent): void {\n if (!this.toolManager || !this.toolContext) return;\n this.toolManager.handlePointerUp(this.toPointerState(e), this.toolContext);\n this.historyRecorder?.commit();\n }\n\n private deleteSelected(): void {\n if (!this.toolManager || !this.toolContext) return;\n const tool = this.toolManager.activeTool;\n if (tool?.name !== 'select') return;\n const selectTool = tool as SelectTool;\n const ids = selectTool.selectedIds;\n if (ids.length === 0) return;\n this.historyRecorder?.begin();\n for (const id of ids) {\n this.toolContext.store.remove(id);\n }\n this.historyRecorder?.commit();\n this.toolContext.requestRender();\n }\n\n private handleUndo(): void {\n if (!this.historyStack || !this.toolContext) return;\n this.historyRecorder?.pause();\n this.historyStack.undo(this.toolContext.store);\n this.historyRecorder?.resume();\n this.toolContext.requestRender();\n }\n\n private handleRedo(): void {\n if (!this.historyStack || !this.toolContext) return;\n this.historyRecorder?.pause();\n this.historyStack.redo(this.toolContext.store);\n this.historyRecorder?.resume();\n this.toolContext.requestRender();\n }\n\n private cancelToolIfActive(e: PointerEvent): void {\n if (this.isToolActive) {\n this.dispatchToolUp(e);\n this.isToolActive = false;\n }\n }\n}\n","import { EventBus } from '../core/event-bus';\nimport type { CanvasElement, ElementType } from './types';\n\nexport interface ElementUpdateEvent {\n previous: CanvasElement;\n current: CanvasElement;\n}\n\ninterface ElementStoreEvents {\n add: CanvasElement;\n remove: CanvasElement;\n update: ElementUpdateEvent;\n clear: null;\n}\n\nexport class ElementStore {\n private elements = new Map<string, CanvasElement>();\n private bus = new EventBus<ElementStoreEvents>();\n\n get count(): number {\n return this.elements.size;\n }\n\n getAll(): CanvasElement[] {\n return [...this.elements.values()].sort((a, b) => a.zIndex - b.zIndex);\n }\n\n getById(id: string): CanvasElement | undefined {\n return this.elements.get(id);\n }\n\n getElementsByType<T extends ElementType>(type: T): Extract<CanvasElement, { type: T }>[] {\n return this.getAll().filter(\n (el): el is Extract<CanvasElement, { type: T }> => el.type === type,\n );\n }\n\n add(element: CanvasElement): void {\n this.elements.set(element.id, element);\n this.bus.emit('add', element);\n }\n\n update(id: string, partial: Partial<CanvasElement>): void {\n const existing = this.elements.get(id);\n if (!existing) return;\n\n const updated = { ...existing, ...partial, id: existing.id, type: existing.type };\n this.elements.set(id, updated as CanvasElement);\n this.bus.emit('update', { previous: existing, current: updated as CanvasElement });\n }\n\n remove(id: string): void {\n const element = this.elements.get(id);\n if (!element) return;\n\n this.elements.delete(id);\n this.bus.emit('remove', element);\n }\n\n clear(): void {\n this.elements.clear();\n this.bus.emit('clear', null);\n }\n\n snapshot(): CanvasElement[] {\n return this.getAll().map((el) => ({ ...el }));\n }\n\n loadSnapshot(elements: CanvasElement[]): void {\n this.elements.clear();\n for (const el of elements) {\n this.elements.set(el.id, el);\n }\n }\n\n on<K extends keyof ElementStoreEvents>(\n event: K,\n listener: (data: ElementStoreEvents[K]) => void,\n ): () => void {\n return this.bus.on(event, listener);\n }\n}\n","import type { Point } from '../core/types';\n\ninterface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport function getArrowControlPoint(from: Point, to: Point, bend: number): Point {\n const midX = (from.x + to.x) / 2;\n const midY = (from.y + to.y) / 2;\n\n if (bend === 0) return { x: midX, y: midY };\n\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n const len = Math.sqrt(dx * dx + dy * dy);\n\n if (len === 0) return { x: midX, y: midY };\n\n const perpX = -dy / len;\n const perpY = dx / len;\n\n return {\n x: midX + perpX * bend,\n y: midY + perpY * bend,\n };\n}\n\nexport function getArrowMidpoint(from: Point, to: Point, bend: number): Point {\n const cp = getArrowControlPoint(from, to, bend);\n return {\n x: 0.25 * from.x + 0.5 * cp.x + 0.25 * to.x,\n y: 0.25 * from.y + 0.5 * cp.y + 0.25 * to.y,\n };\n}\n\nexport function getBendFromPoint(from: Point, to: Point, dragPoint: Point): number {\n const midX = (from.x + to.x) / 2;\n const midY = (from.y + to.y) / 2;\n\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n const len = Math.sqrt(dx * dx + dy * dy);\n\n if (len === 0) return 0;\n\n const perpX = -dy / len;\n const perpY = dx / len;\n\n return (dragPoint.x - midX) * perpX + (dragPoint.y - midY) * perpY;\n}\n\nexport function getArrowTangentAngle(from: Point, to: Point, bend: number, t: number): number {\n const cp = getArrowControlPoint(from, to, bend);\n\n const tangentX = 2 * (1 - t) * (cp.x - from.x) + 2 * t * (to.x - cp.x);\n const tangentY = 2 * (1 - t) * (cp.y - from.y) + 2 * t * (to.y - cp.y);\n\n return Math.atan2(tangentY, tangentX);\n}\n\nexport function isNearBezier(\n point: Point,\n from: Point,\n to: Point,\n bend: number,\n threshold: number,\n): boolean {\n if (bend === 0) return isNearLine(point, from, to, threshold);\n\n const cp = getArrowControlPoint(from, to, bend);\n const segments = 20;\n\n for (let i = 0; i < segments; i++) {\n const t0 = i / segments;\n const t1 = (i + 1) / segments;\n const a = bezierPoint(from, cp, to, t0);\n const b = bezierPoint(from, cp, to, t1);\n if (isNearLine(point, a, b, threshold)) return true;\n }\n\n return false;\n}\n\nexport function getArrowBounds(from: Point, to: Point, bend: number): Rect {\n if (bend === 0) {\n const minX = Math.min(from.x, to.x);\n const minY = Math.min(from.y, to.y);\n return {\n x: minX,\n y: minY,\n w: Math.abs(to.x - from.x),\n h: Math.abs(to.y - from.y),\n };\n }\n\n const cp = getArrowControlPoint(from, to, bend);\n const steps = 20;\n let minX = Math.min(from.x, to.x);\n let minY = Math.min(from.y, to.y);\n let maxX = Math.max(from.x, to.x);\n let maxY = Math.max(from.y, to.y);\n\n for (let i = 1; i < steps; i++) {\n const t = i / steps;\n const p = bezierPoint(from, cp, to, t);\n if (p.x < minX) minX = p.x;\n if (p.y < minY) minY = p.y;\n if (p.x > maxX) maxX = p.x;\n if (p.y > maxY) maxY = p.y;\n }\n\n return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };\n}\n\nfunction bezierPoint(from: Point, cp: Point, to: Point, t: number): Point {\n const mt = 1 - t;\n return {\n x: mt * mt * from.x + 2 * mt * t * cp.x + t * t * to.x,\n y: mt * mt * from.y + 2 * mt * t * cp.y + t * t * to.y,\n };\n}\n\nfunction isNearLine(point: Point, a: Point, b: Point, threshold: number): boolean {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const lenSq = dx * dx + dy * dy;\n\n if (lenSq === 0) {\n return Math.hypot(point.x - a.x, point.y - a.y) <= threshold;\n }\n\n const t = Math.max(0, Math.min(1, ((point.x - a.x) * dx + (point.y - a.y) * dy) / lenSq));\n const projX = a.x + t * dx;\n const projY = a.y + t * dy;\n return Math.hypot(point.x - projX, point.y - projY) <= threshold;\n}\n","import type { CanvasElement, StrokeElement, ArrowElement } from './types';\nimport { getArrowControlPoint, getArrowTangentAngle } from './arrow-geometry';\n\nconst DOM_ELEMENT_TYPES = new Set(['note', 'image', 'html']);\nconst ARROWHEAD_LENGTH = 12;\nconst ARROWHEAD_ANGLE = Math.PI / 6;\n\nexport class ElementRenderer {\n isDomElement(element: CanvasElement): boolean {\n return DOM_ELEMENT_TYPES.has(element.type);\n }\n\n renderCanvasElement(ctx: CanvasRenderingContext2D, element: CanvasElement): void {\n switch (element.type) {\n case 'stroke':\n this.renderStroke(ctx, element);\n break;\n case 'arrow':\n this.renderArrow(ctx, element);\n break;\n }\n }\n\n private renderStroke(ctx: CanvasRenderingContext2D, stroke: StrokeElement): void {\n if (stroke.points.length < 2) return;\n\n ctx.save();\n ctx.translate(stroke.position.x, stroke.position.y);\n ctx.strokeStyle = stroke.color;\n ctx.lineWidth = stroke.width;\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n ctx.globalAlpha = stroke.opacity;\n\n ctx.beginPath();\n const first = stroke.points[0];\n if (first) {\n ctx.moveTo(first.x, first.y);\n }\n for (let i = 1; i < stroke.points.length; i++) {\n const pt = stroke.points[i];\n if (pt) {\n ctx.lineTo(pt.x, pt.y);\n }\n }\n ctx.stroke();\n ctx.restore();\n }\n\n private renderArrow(ctx: CanvasRenderingContext2D, arrow: ArrowElement): void {\n ctx.save();\n ctx.strokeStyle = arrow.color;\n ctx.lineWidth = arrow.width;\n ctx.lineCap = 'round';\n\n ctx.beginPath();\n ctx.moveTo(arrow.from.x, arrow.from.y);\n\n if (arrow.bend !== 0) {\n const cp = getArrowControlPoint(arrow.from, arrow.to, arrow.bend);\n ctx.quadraticCurveTo(cp.x, cp.y, arrow.to.x, arrow.to.y);\n } else {\n ctx.lineTo(arrow.to.x, arrow.to.y);\n }\n ctx.stroke();\n\n this.renderArrowhead(ctx, arrow);\n ctx.restore();\n }\n\n private renderArrowhead(ctx: CanvasRenderingContext2D, arrow: ArrowElement): void {\n const angle = getArrowTangentAngle(arrow.from, arrow.to, arrow.bend, 1);\n\n ctx.beginPath();\n ctx.moveTo(arrow.to.x, arrow.to.y);\n ctx.lineTo(\n arrow.to.x - ARROWHEAD_LENGTH * Math.cos(angle - ARROWHEAD_ANGLE),\n arrow.to.y - ARROWHEAD_LENGTH * Math.sin(angle - ARROWHEAD_ANGLE),\n );\n ctx.lineTo(\n arrow.to.x - ARROWHEAD_LENGTH * Math.cos(angle + ARROWHEAD_ANGLE),\n arrow.to.y - ARROWHEAD_LENGTH * Math.sin(angle + ARROWHEAD_ANGLE),\n );\n ctx.closePath();\n ctx.fillStyle = arrow.color;\n ctx.fill();\n }\n}\n","import type { ElementStore } from './element-store';\n\nexport class NoteEditor {\n private editingId: string | null = null;\n private editingNode: HTMLDivElement | null = null;\n private blurHandler: (() => void) | null = null;\n private keyHandler: ((e: KeyboardEvent) => void) | null = null;\n private pointerHandler: ((e: PointerEvent) => void) | null = null;\n private pendingEditId: string | null = null;\n\n get isEditing(): boolean {\n return this.editingId !== null;\n }\n\n get editingElementId(): string | null {\n return this.editingId;\n }\n\n startEditing(node: HTMLDivElement, elementId: string, store: ElementStore): void {\n if (this.editingId === elementId) return;\n\n if (this.editingId) {\n this.stopEditing(store);\n }\n\n this.pendingEditId = elementId;\n\n requestAnimationFrame(() => {\n if (this.pendingEditId !== elementId) return;\n this.pendingEditId = null;\n this.activateEditing(node, elementId, store);\n });\n }\n\n stopEditing(store: ElementStore): void {\n this.pendingEditId = null;\n\n if (!this.editingId || !this.editingNode) return;\n\n const text = this.editingNode.textContent ?? '';\n store.update(this.editingId, { text });\n\n this.editingNode.contentEditable = 'false';\n Object.assign(this.editingNode.style, {\n userSelect: 'none',\n cursor: 'default',\n });\n\n if (this.blurHandler) {\n this.editingNode.removeEventListener('blur', this.blurHandler);\n }\n if (this.keyHandler) {\n this.editingNode.removeEventListener('keydown', this.keyHandler);\n }\n if (this.pointerHandler) {\n this.editingNode.removeEventListener('pointerdown', this.pointerHandler);\n }\n\n this.editingId = null;\n this.editingNode = null;\n this.blurHandler = null;\n this.keyHandler = null;\n this.pointerHandler = null;\n }\n\n destroy(store: ElementStore): void {\n this.pendingEditId = null;\n if (this.isEditing) {\n this.stopEditing(store);\n }\n }\n\n private activateEditing(node: HTMLDivElement, elementId: string, store: ElementStore): void {\n this.editingId = elementId;\n this.editingNode = node;\n\n node.contentEditable = 'true';\n Object.assign(node.style, {\n userSelect: 'text',\n cursor: 'text',\n outline: 'none',\n });\n node.focus();\n\n const selection = window.getSelection?.();\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(node);\n range.collapse(false);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n\n this.blurHandler = () => this.stopEditing(store);\n this.keyHandler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n node.blur();\n }\n e.stopPropagation();\n };\n this.pointerHandler = (e: PointerEvent) => {\n e.stopPropagation();\n };\n\n node.addEventListener('blur', this.blurHandler);\n node.addEventListener('keydown', this.keyHandler);\n node.addEventListener('pointerdown', this.pointerHandler);\n }\n}\n","import type { Tool, ToolContext, PointerState } from './types';\n\nexport class ToolManager {\n private tools = new Map<string, Tool>();\n private current: Tool | null = null;\n private changeListeners = new Set<(name: string) => void>();\n\n get activeTool(): Tool | null {\n return this.current;\n }\n\n get toolNames(): string[] {\n return [...this.tools.keys()];\n }\n\n register(tool: Tool): void {\n this.tools.set(tool.name, tool);\n }\n\n setTool(name: string, ctx: ToolContext): void {\n const tool = this.tools.get(name);\n if (!tool) return;\n\n this.current?.onDeactivate?.(ctx);\n this.current = tool;\n this.current.onActivate?.(ctx);\n this.changeListeners.forEach((fn) => fn(name));\n }\n\n handlePointerDown(state: PointerState, ctx: ToolContext): void {\n this.current?.onPointerDown(state, ctx);\n }\n\n handlePointerMove(state: PointerState, ctx: ToolContext): void {\n this.current?.onPointerMove(state, ctx);\n }\n\n handlePointerUp(state: PointerState, ctx: ToolContext): void {\n this.current?.onPointerUp(state, ctx);\n }\n\n onChange(listener: (name: string) => void): () => void {\n this.changeListeners.add(listener);\n return () => this.changeListeners.delete(listener);\n }\n}\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 } from '../core/types';\nimport type { StrokeElement, NoteElement, ArrowElement, ImageElement, HtmlElement } from './types';\nimport { createId } from './create-id';\n\ninterface BaseDefaults {\n position?: Point;\n zIndex?: number;\n locked?: boolean;\n}\n\ninterface StrokeInput extends BaseDefaults {\n points: Point[];\n color?: string;\n width?: number;\n opacity?: number;\n}\n\ninterface NoteInput extends BaseDefaults {\n position: Point;\n size?: Size;\n text?: string;\n backgroundColor?: string;\n}\n\ninterface ArrowInput extends BaseDefaults {\n from: Point;\n to: Point;\n bend?: number;\n color?: string;\n width?: number;\n}\n\ninterface ImageInput extends BaseDefaults {\n position: Point;\n size: Size;\n src: string;\n}\n\ninterface HtmlInput extends BaseDefaults {\n position: Point;\n size: Size;\n}\n\nexport function createStroke(input: StrokeInput): StrokeElement {\n return {\n id: createId('stroke'),\n type: 'stroke',\n position: input.position ?? { x: 0, y: 0 },\n zIndex: input.zIndex ?? 0,\n locked: input.locked ?? false,\n points: input.points,\n color: input.color ?? '#000000',\n width: input.width ?? 2,\n opacity: input.opacity ?? 1,\n };\n}\n\nexport function createNote(input: NoteInput): NoteElement {\n return {\n id: createId('note'),\n type: 'note',\n position: input.position,\n zIndex: input.zIndex ?? 0,\n locked: input.locked ?? false,\n size: input.size ?? { w: 200, h: 100 },\n text: input.text ?? '',\n backgroundColor: input.backgroundColor ?? '#ffeb3b',\n };\n}\n\nexport function createArrow(input: ArrowInput): ArrowElement {\n return {\n id: createId('arrow'),\n type: 'arrow',\n position: input.position ?? { x: 0, y: 0 },\n zIndex: input.zIndex ?? 0,\n locked: input.locked ?? false,\n from: input.from,\n to: input.to,\n bend: input.bend ?? 0,\n color: input.color ?? '#000000',\n width: input.width ?? 2,\n };\n}\n\nexport function createImage(input: ImageInput): ImageElement {\n return {\n id: createId('image'),\n type: 'image',\n position: input.position,\n zIndex: input.zIndex ?? 0,\n locked: input.locked ?? false,\n size: input.size,\n src: input.src,\n };\n}\n\nexport function createHtmlElement(input: HtmlInput): HtmlElement {\n return {\n id: createId('html'),\n type: 'html',\n position: input.position,\n zIndex: input.zIndex ?? 0,\n locked: input.locked ?? false,\n size: input.size,\n };\n}\n","import { Camera } from './camera';\nimport type { CameraOptions } from './camera';\nimport { InputHandler } from './input-handler';\nimport { Background } from './background';\nimport type { BackgroundOptions } from './background';\nimport { ElementStore } from '../elements/element-store';\nimport { ElementRenderer } from '../elements/element-renderer';\nimport { NoteEditor } from '../elements/note-editor';\nimport type { CanvasElement } from '../elements/types';\nimport { ToolManager } from '../tools/tool-manager';\nimport type { ToolContext } from '../tools/types';\nimport { HistoryStack } from '../history/history-stack';\nimport { HistoryRecorder } from '../history/history-recorder';\nimport { createImage, createHtmlElement } from '../elements/element-factory';\nimport { exportState, parseState } from '../core/state-serializer';\nimport type { CanvasState } from '../core/state-serializer';\n\nexport interface ViewportOptions {\n camera?: CameraOptions;\n background?: BackgroundOptions;\n}\n\nexport class Viewport {\n readonly camera: Camera;\n readonly store: ElementStore;\n readonly toolManager: ToolManager;\n readonly history: HistoryStack;\n readonly domLayer: HTMLDivElement;\n private readonly canvasEl: HTMLCanvasElement;\n private readonly wrapper: HTMLDivElement;\n private readonly unsubCamera: () => void;\n private readonly unsubStore: (() => void)[];\n private readonly inputHandler: InputHandler;\n private readonly background: Background;\n private readonly renderer: ElementRenderer;\n private readonly noteEditor: NoteEditor;\n private readonly historyRecorder: HistoryRecorder;\n readonly toolContext: ToolContext;\n private resizeObserver: ResizeObserver | null = null;\n private animFrameId = 0;\n private needsRender = true;\n private domNodes = new Map<string, HTMLDivElement>();\n private htmlContent = new Map<string, HTMLElement>();\n\n constructor(\n private readonly container: HTMLElement,\n options: ViewportOptions = {},\n ) {\n this.camera = new Camera(options.camera);\n this.background = new Background(options.background);\n this.store = new ElementStore();\n this.toolManager = new ToolManager();\n this.renderer = new ElementRenderer();\n this.noteEditor = new NoteEditor();\n this.history = new HistoryStack();\n this.historyRecorder = new HistoryRecorder(this.store, this.history);\n\n this.wrapper = this.createWrapper();\n this.canvasEl = this.createCanvas();\n this.domLayer = this.createDomLayer();\n\n this.wrapper.appendChild(this.canvasEl);\n this.wrapper.appendChild(this.domLayer);\n this.container.appendChild(this.wrapper);\n\n this.toolContext = {\n camera: this.camera,\n store: this.store,\n requestRender: () => this.requestRender(),\n switchTool: (name: string) => this.toolManager.setTool(name, this.toolContext),\n editElement: (id: string) => this.startEditingNote(id),\n setCursor: (cursor: string) => {\n this.wrapper.style.cursor = cursor;\n },\n };\n\n this.inputHandler = new InputHandler(this.wrapper, this.camera, {\n toolManager: this.toolManager,\n toolContext: this.toolContext,\n historyRecorder: this.historyRecorder,\n historyStack: this.history,\n });\n\n this.unsubCamera = this.camera.onChange(() => {\n this.applyCameraTransform();\n this.requestRender();\n });\n\n this.unsubStore = [\n this.store.on('add', () => this.requestRender()),\n this.store.on('remove', (el) => this.removeDomNode(el.id)),\n this.store.on('update', () => this.requestRender()),\n this.store.on('clear', () => this.clearDomNodes()),\n ];\n\n this.wrapper.addEventListener('dblclick', this.onDblClick);\n this.wrapper.addEventListener('dragover', this.onDragOver);\n this.wrapper.addEventListener('drop', this.onDrop);\n this.observeResize();\n this.syncCanvasSize();\n this.startRenderLoop();\n }\n\n get ctx(): CanvasRenderingContext2D | null {\n return this.canvasEl.getContext('2d');\n }\n\n requestRender(): void {\n this.needsRender = true;\n }\n\n exportState(): CanvasState {\n return exportState(this.store.snapshot(), this.camera);\n }\n\n exportJSON(): string {\n return JSON.stringify(this.exportState());\n }\n\n loadState(state: CanvasState): void {\n this.historyRecorder.pause();\n this.noteEditor.destroy(this.store);\n this.clearDomNodes();\n this.store.loadSnapshot(state.elements);\n this.history.clear();\n this.historyRecorder.resume();\n this.camera.moveTo(state.camera.position.x, state.camera.position.y);\n this.camera.setZoom(state.camera.zoom);\n }\n\n loadJSON(json: string): void {\n this.loadState(parseState(json));\n }\n\n undo(): boolean {\n this.historyRecorder.pause();\n const result = this.history.undo(this.store);\n this.historyRecorder.resume();\n if (result) this.requestRender();\n return result;\n }\n\n redo(): boolean {\n this.historyRecorder.pause();\n const result = this.history.redo(this.store);\n this.historyRecorder.resume();\n if (result) this.requestRender();\n return result;\n }\n\n addImage(src: string, position: { x: number; y: number }, size = { w: 300, h: 200 }): void {\n const image = createImage({ position, size, src });\n this.historyRecorder.begin();\n this.store.add(image);\n this.historyRecorder.commit();\n this.requestRender();\n }\n\n addHtmlElement(\n dom: HTMLElement,\n position: { x: number; y: number },\n size = { w: 200, h: 150 },\n ): string {\n const el = createHtmlElement({ position, size });\n this.htmlContent.set(el.id, dom);\n this.historyRecorder.begin();\n this.store.add(el);\n this.historyRecorder.commit();\n this.requestRender();\n return el.id;\n }\n\n destroy(): void {\n cancelAnimationFrame(this.animFrameId);\n this.noteEditor.destroy(this.store);\n this.historyRecorder.destroy();\n this.wrapper.removeEventListener('dblclick', this.onDblClick);\n this.wrapper.removeEventListener('dragover', this.onDragOver);\n this.wrapper.removeEventListener('drop', this.onDrop);\n this.inputHandler.destroy();\n this.unsubCamera();\n this.unsubStore.forEach((fn) => fn());\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.wrapper.remove();\n }\n\n private startRenderLoop(): void {\n const loop = (): void => {\n if (this.needsRender) {\n this.render();\n this.needsRender = false;\n }\n this.animFrameId = requestAnimationFrame(loop);\n };\n this.animFrameId = requestAnimationFrame(loop);\n }\n\n private render(): void {\n const ctx = this.ctx;\n if (!ctx) return;\n\n const dpr = typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;\n ctx.save();\n ctx.scale(dpr, dpr);\n\n this.background.render(ctx, this.camera);\n\n ctx.save();\n ctx.translate(this.camera.position.x, this.camera.position.y);\n ctx.scale(this.camera.zoom, this.camera.zoom);\n\n for (const element of this.store.getAll()) {\n if (this.renderer.isDomElement(element)) {\n this.syncDomNode(element);\n } else {\n this.renderer.renderCanvasElement(ctx, element);\n }\n }\n\n const activeTool = this.toolManager.activeTool;\n if (activeTool?.renderOverlay) {\n activeTool.renderOverlay(ctx);\n }\n\n ctx.restore();\n ctx.restore();\n }\n\n private startEditingNote(id: string): void {\n const element = this.store.getById(id);\n if (!element || element.type !== 'note') return;\n\n this.render();\n\n const node = this.domNodes.get(id);\n if (node) {\n this.noteEditor.startEditing(node, id, this.store);\n }\n }\n\n private onDblClick = (e: MouseEvent): void => {\n const el = document.elementFromPoint(e.clientX, e.clientY);\n if (!el) return;\n\n const nodeEl = (el as HTMLElement).closest<HTMLDivElement>('[data-element-id]');\n if (!nodeEl) return;\n\n const elementId = nodeEl.dataset['elementId'];\n if (elementId) this.startEditingNote(elementId);\n };\n\n private onDragOver = (e: DragEvent): void => {\n e.preventDefault();\n };\n\n private onDrop = (e: DragEvent): void => {\n e.preventDefault();\n const files = e.dataTransfer?.files;\n if (!files) return;\n\n const rect = this.wrapper.getBoundingClientRect();\n\n for (const file of files) {\n if (!file.type.startsWith('image/')) continue;\n\n const reader = new FileReader();\n reader.onload = () => {\n const src = reader.result;\n if (typeof src !== 'string') return;\n\n const screenPos = { x: e.clientX - rect.left, y: e.clientY - rect.top };\n const worldPos = this.camera.screenToWorld(screenPos);\n this.addImage(src, worldPos);\n };\n reader.readAsDataURL(file);\n }\n };\n\n private syncDomNode(element: CanvasElement): void {\n let node = this.domNodes.get(element.id);\n if (!node) {\n node = document.createElement('div');\n node.dataset['elementId'] = element.id;\n Object.assign(node.style, {\n position: 'absolute',\n pointerEvents: 'auto',\n });\n this.domLayer.appendChild(node);\n this.domNodes.set(element.id, node);\n }\n\n const size = 'size' in element ? element.size : null;\n Object.assign(node.style, {\n left: `${element.position.x}px`,\n top: `${element.position.y}px`,\n width: size ? `${size.w}px` : 'auto',\n height: size ? `${size.h}px` : 'auto',\n });\n\n this.renderDomContent(node, element);\n }\n\n private renderDomContent(node: HTMLDivElement, element: CanvasElement): void {\n if (element.type === 'note') {\n if (!node.dataset['initialized']) {\n node.dataset['initialized'] = 'true';\n Object.assign(node.style, {\n backgroundColor: element.backgroundColor,\n padding: '8px',\n borderRadius: '4px',\n boxShadow: '0 2px 8px rgba(0,0,0,0.15)',\n fontSize: '14px',\n overflow: 'hidden',\n cursor: 'default',\n userSelect: 'none',\n wordWrap: 'break-word',\n });\n node.textContent = element.text || '';\n\n node.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n const id = node.dataset['elementId'];\n if (id) this.startEditingNote(id);\n });\n }\n\n if (!this.noteEditor.isEditing || this.noteEditor.editingElementId !== element.id) {\n if (node.textContent !== element.text) {\n node.textContent = element.text || '';\n }\n node.style.backgroundColor = element.backgroundColor;\n }\n }\n\n if (element.type === 'image') {\n if (!node.dataset['initialized']) {\n node.dataset['initialized'] = 'true';\n const img = document.createElement('img');\n img.src = element.src;\n Object.assign(img.style, {\n width: '100%',\n height: '100%',\n objectFit: 'contain',\n pointerEvents: 'none',\n });\n img.draggable = false;\n node.appendChild(img);\n } else {\n const img = node.querySelector('img');\n if (img && img.src !== element.src) {\n img.src = element.src;\n }\n }\n }\n\n if (element.type === 'html' && !node.dataset['initialized']) {\n const content = this.htmlContent.get(element.id);\n if (content) {\n node.dataset['initialized'] = 'true';\n Object.assign(node.style, {\n overflow: 'hidden',\n });\n node.appendChild(content);\n }\n }\n }\n\n private removeDomNode(id: string): void {\n this.htmlContent.delete(id);\n const node = this.domNodes.get(id);\n if (node) {\n node.remove();\n this.domNodes.delete(id);\n }\n this.requestRender();\n }\n\n private clearDomNodes(): void {\n this.domNodes.forEach((node) => node.remove());\n this.domNodes.clear();\n this.htmlContent.clear();\n this.requestRender();\n }\n\n private createWrapper(): HTMLDivElement {\n const el = document.createElement('div');\n Object.assign(el.style, {\n position: 'relative',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n });\n return el;\n }\n\n private createCanvas(): HTMLCanvasElement {\n const el = document.createElement('canvas');\n Object.assign(el.style, {\n position: 'absolute',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n });\n return el;\n }\n\n private createDomLayer(): HTMLDivElement {\n const el = document.createElement('div');\n Object.assign(el.style, {\n position: 'absolute',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n transformOrigin: '0 0',\n });\n return el;\n }\n\n private applyCameraTransform(): void {\n this.domLayer.style.transform = this.camera.toCSSTransform();\n }\n\n private syncCanvasSize(): void {\n const rect = this.container.getBoundingClientRect();\n const dpr = typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;\n this.canvasEl.width = rect.width * dpr;\n this.canvasEl.height = rect.height * dpr;\n this.requestRender();\n }\n\n private observeResize(): void {\n if (typeof ResizeObserver === 'undefined') return;\n this.resizeObserver = new ResizeObserver(() => this.syncCanvasSize());\n this.resizeObserver.observe(this.container);\n }\n}\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 { Point } from '../core/types';\nimport type { Tool, ToolContext, PointerState } from './types';\nimport { createStroke } from '../elements/element-factory';\n\nexport interface PencilToolOptions {\n color?: string;\n width?: number;\n}\n\nconst MIN_POINTS_FOR_STROKE = 2;\n\nexport class PencilTool implements Tool {\n readonly name = 'pencil';\n private drawing = false;\n private points: Point[] = [];\n private color: string;\n private width: number;\n\n constructor(options: PencilToolOptions = {}) {\n this.color = options.color ?? '#000000';\n this.width = options.width ?? 2;\n }\n\n onActivate(ctx: ToolContext): void {\n ctx.setCursor?.('crosshair');\n }\n\n onDeactivate(ctx: ToolContext): void {\n ctx.setCursor?.('default');\n }\n\n setOptions(options: PencilToolOptions): void {\n if (options.color !== undefined) this.color = options.color;\n if (options.width !== undefined) this.width = options.width;\n }\n\n onPointerDown(state: PointerState, ctx: ToolContext): void {\n this.drawing = true;\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\n this.points = [world];\n }\n\n onPointerMove(state: PointerState, ctx: ToolContext): void {\n if (!this.drawing) return;\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\n this.points.push(world);\n ctx.requestRender();\n }\n\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\n if (!this.drawing) return;\n this.drawing = false;\n\n if (this.points.length < MIN_POINTS_FOR_STROKE) {\n this.points = [];\n return;\n }\n\n const stroke = createStroke({\n points: this.points,\n color: this.color,\n width: this.width,\n });\n ctx.store.add(stroke);\n this.points = [];\n ctx.requestRender();\n }\n\n renderOverlay(ctx: CanvasRenderingContext2D): void {\n if (!this.drawing || this.points.length < 2) return;\n\n ctx.save();\n ctx.strokeStyle = this.color;\n ctx.lineWidth = this.width;\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n ctx.globalAlpha = 0.8;\n\n ctx.beginPath();\n const first = this.points[0];\n if (!first) return;\n ctx.moveTo(first.x, first.y);\n for (let i = 1; i < this.points.length; i++) {\n const p = this.points[i];\n if (p) ctx.lineTo(p.x, p.y);\n }\n ctx.stroke();\n ctx.restore();\n }\n}\n","import type { Point } from '../core/types';\nimport type { Tool, ToolContext, PointerState } from './types';\nimport type { StrokeElement } from '../elements/types';\n\nexport interface EraserToolOptions {\n radius?: number;\n}\n\nconst DEFAULT_RADIUS = 20;\n\nfunction makeEraserCursor(radius: number): string {\n const size = radius * 2;\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>`;\n return `url(\"data:image/svg+xml,${svg}\") ${radius} ${radius}, crosshair`;\n}\n\nexport class EraserTool implements Tool {\n readonly name = 'eraser';\n private erasing = false;\n private readonly radius: number;\n private readonly cursor: string;\n\n constructor(options: EraserToolOptions = {}) {\n this.radius = options.radius ?? DEFAULT_RADIUS;\n this.cursor = makeEraserCursor(this.radius);\n }\n\n onActivate(ctx: ToolContext): void {\n ctx.setCursor?.(this.cursor);\n }\n\n onDeactivate(ctx: ToolContext): void {\n ctx.setCursor?.('default');\n }\n\n onPointerDown(state: PointerState, ctx: ToolContext): void {\n this.erasing = true;\n this.eraseAt(state, ctx);\n }\n\n onPointerMove(state: PointerState, ctx: ToolContext): void {\n if (!this.erasing) return;\n this.eraseAt(state, ctx);\n }\n\n onPointerUp(_state: PointerState, _ctx: ToolContext): void {\n this.erasing = false;\n }\n\n private eraseAt(state: PointerState, ctx: ToolContext): void {\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\n const strokes = ctx.store.getElementsByType('stroke');\n let erased = false;\n\n for (const stroke of strokes) {\n if (this.strokeIntersects(stroke, world)) {\n ctx.store.remove(stroke.id);\n erased = true;\n }\n }\n\n if (erased) ctx.requestRender();\n }\n\n private strokeIntersects(stroke: StrokeElement, point: Point): boolean {\n const radiusSq = this.radius * this.radius;\n return stroke.points.some((p) => {\n const dx = p.x + stroke.position.x - point.x;\n const dy = p.y + stroke.position.y - point.y;\n return dx * dx + dy * dy <= radiusSq;\n });\n }\n}\n","import type { Point } from '../core/types';\nimport type { ArrowElement } from '../elements/types';\nimport type { ToolContext } from './types';\nimport { getArrowMidpoint, getBendFromPoint } from '../elements/arrow-geometry';\n\nexport type ArrowHandle = 'start' | 'mid' | 'end';\n\nconst HANDLE_RADIUS = 5;\nconst HANDLE_HIT_PADDING = 4;\n\nconst ARROW_HANDLE_CURSORS: Record<ArrowHandle, string> = {\n start: 'crosshair',\n end: 'crosshair',\n mid: 'grab',\n};\n\nexport function getArrowHandleCursor(handle: ArrowHandle, active: boolean): string {\n if (handle === 'mid' && active) return 'grabbing';\n return ARROW_HANDLE_CURSORS[handle];\n}\n\nexport function getArrowHandlePositions(arrow: ArrowElement): [ArrowHandle, Point][] {\n const mid = getArrowMidpoint(arrow.from, arrow.to, arrow.bend);\n return [\n ['start', arrow.from],\n ['mid', mid],\n ['end', arrow.to],\n ];\n}\n\nexport function hitTestArrowHandles(\n world: Point,\n selectedIds: string[],\n ctx: ToolContext,\n): { elementId: string; handle: ArrowHandle } | null {\n if (selectedIds.length === 0) return null;\n\n const zoom = ctx.camera.zoom;\n const hitRadius = (HANDLE_RADIUS + HANDLE_HIT_PADDING) / zoom;\n\n for (const id of selectedIds) {\n const el = ctx.store.getById(id);\n if (!el || el.type !== 'arrow') continue;\n\n const handles = getArrowHandlePositions(el);\n for (const [handle, pos] of handles) {\n const dx = world.x - pos.x;\n const dy = world.y - pos.y;\n if (dx * dx + dy * dy <= hitRadius * hitRadius) {\n return { elementId: id, handle };\n }\n }\n }\n\n return null;\n}\n\nexport function applyArrowHandleDrag(\n handle: ArrowHandle,\n elementId: string,\n world: Point,\n ctx: ToolContext,\n): void {\n const el = ctx.store.getById(elementId);\n if (!el || el.type !== 'arrow') return;\n\n switch (handle) {\n case 'start':\n ctx.store.update(elementId, {\n from: { x: world.x, y: world.y },\n position: { x: world.x, y: world.y },\n });\n break;\n case 'end':\n ctx.store.update(elementId, {\n to: { x: world.x, y: world.y },\n });\n break;\n case 'mid': {\n const bend = getBendFromPoint(el.from, el.to, world);\n ctx.store.update(elementId, { bend });\n break;\n }\n }\n\n ctx.requestRender();\n}\n\nexport function renderArrowHandles(\n canvasCtx: CanvasRenderingContext2D,\n arrow: ArrowElement,\n zoom: number,\n): void {\n const radius = HANDLE_RADIUS / zoom;\n const handles = getArrowHandlePositions(arrow);\n\n canvasCtx.setLineDash([]);\n canvasCtx.lineWidth = 1.5 / zoom;\n\n for (const [handle, pos] of handles) {\n canvasCtx.fillStyle = handle === 'mid' ? '#2196F3' : '#ffffff';\n canvasCtx.strokeStyle = '#2196F3';\n\n canvasCtx.beginPath();\n canvasCtx.arc(pos.x, pos.y, radius, 0, Math.PI * 2);\n canvasCtx.fill();\n canvasCtx.stroke();\n }\n}\n","import type { Point } from '../core/types';\nimport type { Tool, ToolContext, PointerState } from './types';\nimport type { CanvasElement } from '../elements/types';\nimport { isNearBezier, getArrowBounds } from '../elements/arrow-geometry';\nimport {\n type ArrowHandle,\n hitTestArrowHandles,\n applyArrowHandleDrag,\n renderArrowHandles,\n getArrowHandleCursor,\n} from './arrow-handles';\n\ninterface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\ntype HandlePosition = 'nw' | 'ne' | 'sw' | 'se';\n\nconst HANDLE_SIZE = 8;\nconst HANDLE_HIT_PADDING = 4;\nconst SELECTION_PAD = 4;\nconst MIN_ELEMENT_SIZE = 20;\n\nconst HANDLE_CURSORS: Record<HandlePosition, string> = {\n nw: 'nwse-resize',\n se: 'nwse-resize',\n ne: 'nesw-resize',\n sw: 'nesw-resize',\n};\n\ntype Mode =\n | { type: 'idle' }\n | { type: 'dragging' }\n | { type: 'marquee'; start: Point }\n | { type: 'resizing'; elementId: string; handle: HandlePosition }\n | { type: 'arrow-handle'; elementId: string; handle: ArrowHandle };\n\nexport class SelectTool implements Tool {\n readonly name = 'select';\n private _selectedIds: string[] = [];\n private mode: Mode = { type: 'idle' };\n private lastWorld: Point = { x: 0, y: 0 };\n private currentWorld: Point = { x: 0, y: 0 };\n private ctx: ToolContext | null = null;\n\n get selectedIds(): string[] {\n return [...this._selectedIds];\n }\n\n get isMarqueeActive(): boolean {\n return this.mode.type === 'marquee';\n }\n\n onActivate(ctx: ToolContext): void {\n this.ctx = ctx;\n }\n\n onDeactivate(ctx: ToolContext): void {\n this._selectedIds = [];\n this.mode = { type: 'idle' };\n ctx.setCursor?.('default');\n }\n\n onPointerDown(state: PointerState, ctx: ToolContext): void {\n this.ctx = ctx;\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\n this.lastWorld = world;\n this.currentWorld = world;\n\n const arrowHit = hitTestArrowHandles(world, this._selectedIds, ctx);\n if (arrowHit) {\n this.mode = {\n type: 'arrow-handle',\n elementId: arrowHit.elementId,\n handle: arrowHit.handle,\n };\n ctx.requestRender();\n return;\n }\n\n const resizeHit = this.hitTestResizeHandle(world, ctx);\n if (resizeHit) {\n const el = ctx.store.getById(resizeHit.elementId);\n if (el) {\n this.mode = {\n type: 'resizing',\n elementId: resizeHit.elementId,\n handle: resizeHit.handle,\n };\n ctx.requestRender();\n return;\n }\n }\n\n const hit = this.hitTest(world, ctx);\n if (hit) {\n const alreadySelected = this._selectedIds.includes(hit.id);\n if (!alreadySelected) {\n this._selectedIds = [hit.id];\n }\n this.mode = hit.locked ? { type: 'idle' } : { type: 'dragging' };\n } else {\n this._selectedIds = [];\n this.mode = { type: 'marquee', start: world };\n }\n\n ctx.requestRender();\n }\n\n onPointerMove(state: PointerState, ctx: ToolContext): void {\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\n this.currentWorld = world;\n\n if (this.mode.type === 'arrow-handle') {\n ctx.setCursor?.(getArrowHandleCursor(this.mode.handle, true));\n applyArrowHandleDrag(this.mode.handle, this.mode.elementId, world, ctx);\n return;\n }\n\n if (this.mode.type === 'resizing') {\n ctx.setCursor?.(HANDLE_CURSORS[this.mode.handle]);\n this.handleResize(world, ctx);\n return;\n }\n\n if (this.mode.type === 'dragging' && this._selectedIds.length > 0) {\n ctx.setCursor?.('move');\n const dx = world.x - this.lastWorld.x;\n const dy = world.y - this.lastWorld.y;\n this.lastWorld = world;\n\n for (const id of this._selectedIds) {\n const el = ctx.store.getById(id);\n if (!el || el.locked) continue;\n\n if (el.type === 'arrow') {\n ctx.store.update(id, {\n position: { x: el.position.x + dx, y: el.position.y + dy },\n from: { x: el.from.x + dx, y: el.from.y + dy },\n to: { x: el.to.x + dx, y: el.to.y + dy },\n });\n } else {\n ctx.store.update(id, {\n position: { x: el.position.x + dx, y: el.position.y + dy },\n });\n }\n }\n ctx.requestRender();\n return;\n }\n\n if (this.mode.type === 'marquee') {\n ctx.setCursor?.('crosshair');\n ctx.requestRender();\n return;\n }\n\n this.updateHoverCursor(world, ctx);\n }\n\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\n if (this.mode.type === 'marquee') {\n const rect = this.getMarqueeRect();\n if (rect) {\n this._selectedIds = this.findElementsInRect(rect, ctx);\n }\n ctx.requestRender();\n }\n\n this.mode = { type: 'idle' };\n ctx.setCursor?.('default');\n }\n\n onHover(state: PointerState, ctx: ToolContext): void {\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\n this.updateHoverCursor(world, ctx);\n }\n\n renderOverlay(canvasCtx: CanvasRenderingContext2D): void {\n this.renderMarquee(canvasCtx);\n this.renderSelectionBoxes(canvasCtx);\n }\n\n private updateHoverCursor(world: Point, ctx: ToolContext): void {\n const arrowHit = hitTestArrowHandles(world, this._selectedIds, ctx);\n if (arrowHit) {\n ctx.setCursor?.(getArrowHandleCursor(arrowHit.handle, false));\n return;\n }\n\n const resizeHit = this.hitTestResizeHandle(world, ctx);\n if (resizeHit) {\n ctx.setCursor?.(HANDLE_CURSORS[resizeHit.handle]);\n return;\n }\n\n const hit = this.hitTest(world, ctx);\n ctx.setCursor?.(hit ? 'move' : 'default');\n }\n\n private handleResize(world: Point, ctx: ToolContext): void {\n if (this.mode.type !== 'resizing') return;\n\n const el = ctx.store.getById(this.mode.elementId);\n if (!el || !('size' in el)) return;\n\n const { handle } = this.mode;\n const dx = world.x - this.lastWorld.x;\n const dy = world.y - this.lastWorld.y;\n this.lastWorld = world;\n\n let { x, y, w, h } = { x: el.position.x, y: el.position.y, w: el.size.w, h: el.size.h };\n\n switch (handle) {\n case 'se':\n w += dx;\n h += dy;\n break;\n case 'sw':\n x += dx;\n w -= dx;\n h += dy;\n break;\n case 'ne':\n y += dy;\n w += dx;\n h -= dy;\n break;\n case 'nw':\n x += dx;\n y += dy;\n w -= dx;\n h -= dy;\n break;\n }\n\n if (w < MIN_ELEMENT_SIZE) {\n if (handle === 'nw' || handle === 'sw') x = el.position.x + el.size.w - MIN_ELEMENT_SIZE;\n w = MIN_ELEMENT_SIZE;\n }\n if (h < MIN_ELEMENT_SIZE) {\n if (handle === 'nw' || handle === 'ne') y = el.position.y + el.size.h - MIN_ELEMENT_SIZE;\n h = MIN_ELEMENT_SIZE;\n }\n\n ctx.store.update(this.mode.elementId, {\n position: { x, y },\n size: { w, h },\n });\n ctx.requestRender();\n }\n\n private hitTestResizeHandle(\n world: Point,\n ctx: ToolContext,\n ): { elementId: string; handle: HandlePosition } | null {\n if (this._selectedIds.length === 0) return null;\n\n const zoom = ctx.camera.zoom;\n const handleHalf = (HANDLE_SIZE / 2 + HANDLE_HIT_PADDING) / zoom;\n\n for (const id of this._selectedIds) {\n const el = ctx.store.getById(id);\n if (!el || !('size' in el)) continue;\n\n const bounds = this.getElementBounds(el);\n if (!bounds) continue;\n\n const corners = this.getHandlePositions(bounds);\n for (const [handle, pos] of corners) {\n if (Math.abs(world.x - pos.x) <= handleHalf && Math.abs(world.y - pos.y) <= handleHalf) {\n return { elementId: id, handle };\n }\n }\n }\n\n return null;\n }\n\n private getHandlePositions(bounds: Rect): [HandlePosition, Point][] {\n return [\n ['nw', { x: bounds.x, y: bounds.y }],\n ['ne', { x: bounds.x + bounds.w, y: bounds.y }],\n ['sw', { x: bounds.x, y: bounds.y + bounds.h }],\n ['se', { x: bounds.x + bounds.w, y: bounds.y + bounds.h }],\n ];\n }\n\n private renderMarquee(canvasCtx: CanvasRenderingContext2D): void {\n if (this.mode.type !== 'marquee') return;\n\n const rect = this.getMarqueeRect();\n if (!rect) return;\n\n canvasCtx.save();\n canvasCtx.strokeStyle = '#2196F3';\n canvasCtx.fillStyle = 'rgba(33, 150, 243, 0.08)';\n canvasCtx.lineWidth = 1;\n canvasCtx.setLineDash([4, 4]);\n canvasCtx.strokeRect(rect.x, rect.y, rect.w, rect.h);\n canvasCtx.fillRect(rect.x, rect.y, rect.w, rect.h);\n canvasCtx.restore();\n }\n\n private renderSelectionBoxes(canvasCtx: CanvasRenderingContext2D): void {\n if (this._selectedIds.length === 0 || !this.ctx) return;\n\n const zoom = this.ctx.camera.zoom;\n const handleWorldSize = HANDLE_SIZE / zoom;\n\n canvasCtx.save();\n canvasCtx.strokeStyle = '#2196F3';\n canvasCtx.lineWidth = 1.5 / zoom;\n canvasCtx.setLineDash([4 / zoom, 4 / zoom]);\n\n for (const id of this._selectedIds) {\n const el = this.ctx.store.getById(id);\n if (!el) continue;\n\n if (el.type === 'arrow') {\n renderArrowHandles(canvasCtx, el, zoom);\n continue;\n }\n\n const bounds = this.getElementBounds(el);\n if (!bounds) continue;\n\n const pad = SELECTION_PAD / zoom;\n canvasCtx.strokeRect(bounds.x - pad, bounds.y - pad, bounds.w + pad * 2, bounds.h + pad * 2);\n\n if ('size' in el) {\n canvasCtx.setLineDash([]);\n canvasCtx.fillStyle = '#ffffff';\n const corners = this.getHandlePositions(bounds);\n for (const [, pos] of corners) {\n canvasCtx.fillRect(\n pos.x - handleWorldSize / 2,\n pos.y - handleWorldSize / 2,\n handleWorldSize,\n handleWorldSize,\n );\n canvasCtx.strokeRect(\n pos.x - handleWorldSize / 2,\n pos.y - handleWorldSize / 2,\n handleWorldSize,\n handleWorldSize,\n );\n }\n canvasCtx.setLineDash([4 / zoom, 4 / zoom]);\n }\n }\n\n canvasCtx.restore();\n }\n\n private getMarqueeRect(): Rect | null {\n if (this.mode.type !== 'marquee') return null;\n\n const { start } = this.mode;\n const end = this.currentWorld;\n const x = Math.min(start.x, end.x);\n const y = Math.min(start.y, end.y);\n const w = Math.abs(end.x - start.x);\n const h = Math.abs(end.y - start.y);\n\n if (w === 0 && h === 0) return null;\n return { x, y, w, h };\n }\n\n private findElementsInRect(marquee: Rect, ctx: ToolContext): string[] {\n const ids: string[] = [];\n for (const el of ctx.store.getAll()) {\n const bounds = this.getElementBounds(el);\n if (bounds && this.rectsOverlap(marquee, bounds)) {\n ids.push(el.id);\n }\n }\n return ids;\n }\n\n private rectsOverlap(a: Rect, b: Rect): boolean {\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;\n }\n\n private getElementBounds(el: CanvasElement): Rect | null {\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 if (el.type === 'stroke' && el.points.length > 0) {\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n for (const p of el.points) {\n const px = p.x + el.position.x;\n const py = p.y + el.position.y;\n if (px < minX) minX = px;\n if (py < minY) minY = py;\n if (px > maxX) maxX = px;\n if (py > maxY) maxY = py;\n }\n return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };\n }\n if (el.type === 'arrow') {\n return getArrowBounds(el.from, el.to, el.bend);\n }\n return null;\n }\n\n private hitTest(world: Point, ctx: ToolContext): CanvasElement | null {\n const elements = ctx.store.getAll().reverse();\n for (const el of elements) {\n if (this.isInsideBounds(world, el)) return el;\n }\n return null;\n }\n\n private isInsideBounds(point: Point, el: CanvasElement): boolean {\n if ('size' in el) {\n const s = el.size;\n return (\n point.x >= el.position.x &&\n point.x <= el.position.x + s.w &&\n point.y >= el.position.y &&\n point.y <= el.position.y + s.h\n );\n }\n\n if (el.type === 'stroke') {\n const HIT_RADIUS = 10;\n return el.points.some((p) => {\n const dx = p.x + el.position.x - point.x;\n const dy = p.y + el.position.y - point.y;\n return dx * dx + dy * dy <= HIT_RADIUS * HIT_RADIUS;\n });\n }\n\n if (el.type === 'arrow') {\n return isNearBezier(point, el.from, el.to, el.bend, 10);\n }\n\n return false;\n }\n}\n","import type { Point } from '../core/types';\nimport type { Tool, ToolContext, PointerState } from './types';\nimport { createArrow } from '../elements/element-factory';\n\nexport interface ArrowToolOptions {\n color?: string;\n width?: number;\n}\n\nexport class ArrowTool implements Tool {\n readonly name = 'arrow';\n private drawing = false;\n private start: Point = { x: 0, y: 0 };\n private end: Point = { x: 0, y: 0 };\n private color: string;\n private width: number;\n\n constructor(options: ArrowToolOptions = {}) {\n this.color = options.color ?? '#000000';\n this.width = options.width ?? 2;\n }\n\n onPointerDown(state: PointerState, ctx: ToolContext): void {\n this.drawing = true;\n this.start = ctx.camera.screenToWorld({ x: state.x, y: state.y });\n this.end = { ...this.start };\n }\n\n onPointerMove(state: PointerState, ctx: ToolContext): void {\n if (!this.drawing) return;\n this.end = ctx.camera.screenToWorld({ x: state.x, y: state.y });\n ctx.requestRender();\n }\n\n onPointerUp(_state: PointerState, ctx: ToolContext): void {\n if (!this.drawing) return;\n this.drawing = false;\n\n if (this.start.x === this.end.x && this.start.y === this.end.y) return;\n\n const arrow = createArrow({\n from: this.start,\n to: this.end,\n color: this.color,\n width: this.width,\n });\n ctx.store.add(arrow);\n ctx.requestRender();\n }\n\n renderOverlay(ctx: CanvasRenderingContext2D): void {\n if (!this.drawing) return;\n if (this.start.x === this.end.x && this.start.y === this.end.y) return;\n\n ctx.save();\n ctx.strokeStyle = this.color;\n ctx.lineWidth = this.width;\n ctx.lineCap = 'round';\n ctx.globalAlpha = 0.6;\n\n ctx.beginPath();\n ctx.moveTo(this.start.x, this.start.y);\n ctx.lineTo(this.end.x, this.end.y);\n ctx.stroke();\n\n const angle = Math.atan2(this.end.y - this.start.y, this.end.x - this.start.x);\n const headLen = 12;\n const headAngle = Math.PI / 6;\n\n ctx.fillStyle = this.color;\n ctx.beginPath();\n ctx.moveTo(this.end.x, this.end.y);\n ctx.lineTo(\n this.end.x - headLen * Math.cos(angle - headAngle),\n this.end.y - headLen * Math.sin(angle - headAngle),\n );\n ctx.lineTo(\n this.end.x - headLen * Math.cos(angle + headAngle),\n this.end.y - headLen * Math.sin(angle + headAngle),\n );\n ctx.closePath();\n ctx.fill();\n ctx.restore();\n }\n}\n","import type { Size } from '../core/types';\nimport type { Tool, ToolContext, PointerState } from './types';\nimport { createNote } from '../elements/element-factory';\n\nexport interface NoteToolOptions {\n backgroundColor?: string;\n size?: Size;\n}\n\nexport class NoteTool implements Tool {\n readonly name = 'note';\n private backgroundColor: string;\n private size: Size;\n\n constructor(options: NoteToolOptions = {}) {\n this.backgroundColor = options.backgroundColor ?? '#ffeb3b';\n this.size = options.size ?? { w: 200, h: 100 };\n }\n\n onPointerDown(_state: PointerState, _ctx: ToolContext): void {\n // Note is placed on pointer up\n }\n\n onPointerMove(_state: PointerState, _ctx: ToolContext): void {\n // No drag behavior for note placement\n }\n\n onPointerUp(state: PointerState, ctx: ToolContext): void {\n const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });\n const note = createNote({\n position: world,\n size: { ...this.size },\n backgroundColor: this.backgroundColor,\n });\n ctx.store.add(note);\n ctx.requestRender();\n\n ctx.switchTool?.('select');\n ctx.editElement?.(note.id);\n }\n}\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"],"mappings":"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","names":["minX","minY","HANDLE_HIT_PADDING"]}