@jucie.io/engine-painter 1.0.32 → 1.0.33
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.
- package/dist/main.js.map +2 -2
- package/package.json +1 -1
package/dist/main.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/ContextTypes.js", "../src/HitRegistry.js", "../src/CanvasEvents.js", "../src/usePointerSurface.js", "../src/Painter.js"],
|
|
4
|
-
"sourcesContent": ["export const ContextTypes = {\n '2D': '2d',\n 'WEBGL': 'webgl',\n 'WEBGL2': 'webgl2',\n 'BITMAPRENDERER': 'bitmaprenderer'\n};", "export class HitRegistry {\n #areas = new Map();\n\n register(id, area) {\n if (!id) {\n throw new Error('Hit area must have an id');\n }\n this.#areas.set(id, { id, ...area });\n return () => this.unregister(id);\n }\n\n unregister(id) {\n this.#areas.delete(id);\n }\n\n get(id) {\n return this.#areas.get(id);\n }\n\n has(id) {\n return this.#areas.has(id);\n }\n\n get areas() {\n return Array.from(this.#areas.values());\n }\n\n clear() {\n this.#areas.clear();\n }\n}", "import { ServiceProvider } from '@jucie.io/engine';\n\nexport class CanvasEvents extends ServiceProvider {\n #canvas = null;\n #offscreenCanvas = null;\n #cachedRect = null;\n #resizeObserver = null;\n #subscribers = new Set();\n #resizeSubscribers = new Set();\n #pendingMove = null;\n #rafId = null;\n #hasTransferredControl = false;\n \n // Internal state for semantic event interpretation\n #state = {\n isPressed: false,\n button: null,\n dragStartX: null,\n dragStartY: null,\n isDragging: false,\n dragThreshold: 5,\n prevX: null,\n prevY: null\n };\n\n static manifest = {\n name: 'CanvasEvents',\n namespace: 'canvasEvents',\n version: '1.0.0'\n };\n\n actions() {\n return {\n setCanvas: (canvas) => this.setCanvas(canvas),\n subscribe: (listener) => this.subscribe(listener),\n onResize: (listener) => this.onResize(listener),\n transferControlToOffscreen: () => this.transferControlToOffscreen()\n };\n }\n\n setCanvas(canvas) {\n if (this.#canvas) {\n this.#removeListeners();\n }\n \n this.#canvas = canvas;\n this.#updateCachedRect();\n this.#initializeListeners();\n }\n\n subscribe(subscriber) {\n this.#subscribers.add(subscriber);\n return () => this.#subscribers.delete(subscriber);\n }\n\n onResize(subscriber) {\n this.#resizeSubscribers.add(subscriber);\n return () => this.#resizeSubscribers.delete(subscriber);\n }\n\n transferControlToOffscreen() {\n if (!this.#canvas) {\n throw new Error('Canvas must be set before transferring control to offscreen');\n }\n\n if (this.#hasTransferredControl) {\n throw new Error('Control has already been transferred to offscreen');\n }\n\n // Transfer control\n this.#offscreenCanvas = this.#canvas.transferControlToOffscreen();\n this.#hasTransferredControl = true;\n\n // Set initial dimensions on offscreen canvas\n this.#offscreenCanvas.width = this.#canvas.width;\n this.#offscreenCanvas.height = this.#canvas.height;\n\n // Emit initial resize event with actual canvas dimensions\n this.#emitResize({\n width: this.#canvas.width,\n height: this.#canvas.height\n });\n\n return this.#offscreenCanvas;\n }\n\n #updateCachedRect() {\n if (this.#canvas) {\n this.#cachedRect = this.#canvas.getBoundingClientRect();\n }\n }\n\n #initializeListeners() {\n if (!this.#canvas) return;\n\n this.#updateCachedRect();\n\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n if (entry.target !== this.#canvas) {\n continue;\n }\n const { width, height } = entry.contentRect;\n this.#emitResize({\n width: width,\n height: height\n });\n }\n this.#updateCachedRect();\n });\n this.#resizeObserver.observe(this.#canvas);\n\n document.addEventListener('wheel', this.#handleScroll, { passive: false });\n document.addEventListener('pointermove', this.#handleMove);\n document.addEventListener('pointerdown', this.#handleDown);\n document.addEventListener('pointerup', this.#handleUp);\n document.addEventListener('pointercancel', this.#handleUp);\n document.addEventListener('dblclick', this.#handleDblClick);\n }\n\n #removeListeners() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n\n document.removeEventListener('wheel', this.#handleScroll);\n document.removeEventListener('pointermove', this.#handleMove);\n document.removeEventListener('pointerdown', this.#handleDown);\n document.removeEventListener('pointerup', this.#handleUp);\n document.removeEventListener('pointercancel', this.#handleUp);\n document.removeEventListener('dblclick', this.#handleDblClick);\n }\n\n #handleScroll = (event) => {\n if (event.target !== this.#canvas) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n \n if (event.ctrlKey) {\n const normalized = this.#normalizeEvent(event, 'zoom');\n this.#emit(normalized);\n } else {\n const normalized = this.#normalizeEvent(event, 'scroll');\n this.#emit(normalized);\n }\n }\n\n #handleMove = (event) => {\n // Store latest raw event and throttle with RAF\n this.#pendingMove = event;\n if (this.#rafId) return;\n \n this.#rafId = requestAnimationFrame(() => {\n if (this.#pendingMove) {\n const rawEvent = this.#pendingMove;\n this.#pendingMove = null;\n \n // Determine event type based on state\n let type = 'move';\n const position = this.#getPosition(rawEvent);\n \n // Check for drag start\n if (this.#state.isPressed && !this.#state.isDragging) {\n const dx = position.x - this.#state.dragStartX;\n const dy = position.y - this.#state.dragStartY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n \n if (distance > this.#state.dragThreshold) {\n this.#state.isDragging = true;\n type = 'dragstart';\n }\n } else if (this.#state.isDragging) {\n type = 'drag';\n }\n \n const normalized = this.#normalizeEvent(rawEvent, type);\n this.#emit(normalized);\n }\n this.#rafId = null;\n });\n }\n\n #handleDown = (event) => {\n // Only capture if starting on canvas\n if (event.target === this.#canvas) {\n const position = this.#getPosition(event);\n \n // Update state\n this.#state.isPressed = true;\n this.#state.button = event.button ?? null;\n this.#state.dragStartX = position.x;\n this.#state.dragStartY = position.y;\n this.#state.isDragging = false;\n \n const normalized = this.#normalizeEvent(event, 'down');\n this.#emit(normalized); // Immediate\n }\n }\n\n #handleUp = (event) => {\n // Emit dragend if we were dragging\n if (this.#state.isDragging) {\n const dragend = this.#normalizeEvent(event, 'dragend');\n this.#emit(dragend);\n }\n \n // Always emit up event\n const normalized = this.#normalizeEvent(event, 'up');\n this.#emit(normalized); // Immediate\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.isDragging = false;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n }\n\n #handleDblClick = (event) => {\n const normalized = this.#normalizeEvent(event, 'dblclick');\n this.#emit(normalized);\n }\n\n #emit(event) {\n for (const subscriber of this.#subscribers) {\n subscriber(event);\n }\n }\n\n #emitResize(resizeData) {\n for (const subscriber of this.#resizeSubscribers) {\n subscriber(resizeData);\n }\n }\n \n #getPosition(event) {\n const isOverCanvas = event.target === this.#canvas;\n \n let x, y;\n if (isOverCanvas) {\n x = event.offsetX;\n y = event.offsetY;\n } else if (this.#cachedRect) {\n x = event.clientX - this.#cachedRect.left;\n y = event.clientY - this.#cachedRect.top;\n } else {\n x = event.clientX;\n y = event.clientY;\n }\n \n return { x, y, isOverCanvas };\n }\n\n #normalizeEvent(event, type) {\n const { x, y, isOverCanvas } = this.#getPosition(event);\n \n const isWithinBounds = isOverCanvas || (\n this.#cachedRect &&\n x >= 0 && \n x <= this.#cachedRect.width && \n y >= 0 && \n y <= this.#cachedRect.height\n );\n \n // Calculate deltas based on event type\n let deltaX = 0;\n let deltaY = 0;\n let deltaZ = 0;\n let deltaMode = 0;\n \n if (type === 'scroll') {\n // Scroll events use wheel deltas\n deltaX = event.deltaX;\n deltaY = event.deltaY;\n deltaZ = event.deltaZ;\n deltaMode = event.deltaMode;\n } else if (type === 'zoom') {\n // Zoom uses simplified delta\n deltaX = 0;\n deltaY = event.deltaY;\n deltaZ = 0;\n } else if (type === 'move' || type === 'drag' || type === 'dragstart') {\n // Position-based events calculate deltas from previous position\n if (this.#state.prevX !== null && this.#state.prevY !== null) {\n deltaX = x - this.#state.prevX;\n deltaY = y - this.#state.prevY;\n }\n }\n \n // Calculate drag distance if dragging\n let dragDistance = 0;\n if (this.#state.isDragging && this.#state.dragStartX !== null && this.#state.dragStartY !== null) {\n const dx = x - this.#state.dragStartX;\n const dy = y - this.#state.dragStartY;\n dragDistance = Math.sqrt(dx * dx + dy * dy);\n }\n\n const normalized = {\n // Position\n x,\n y,\n clientX: event.clientX,\n clientY: event.clientY,\n prevX: this.#state.prevX,\n prevY: this.#state.prevY,\n \n // Event metadata\n type,\n timestamp: Date.now(),\n isOverCanvas,\n isWithinBounds,\n \n // Deltas (appropriate to event type)\n deltaX,\n deltaY,\n deltaZ,\n deltaMode,\n \n // Button state\n button: event.button ?? this.#state.button,\n buttons: event.buttons ?? 0,\n isPressed: this.#state.isPressed,\n \n // Drag state\n isDragging: this.#state.isDragging,\n dragStartX: this.#state.dragStartX,\n dragStartY: this.#state.dragStartY,\n dragDistance,\n \n // Modifiers\n shiftKey: event.shiftKey || false,\n ctrlKey: event.ctrlKey || false,\n altKey: event.altKey || false,\n metaKey: event.metaKey || false\n };\n \n // Update previous position for next delta calculation\n this.#state.prevX = x;\n this.#state.prevY = y;\n\n return normalized;\n }\n\n destroy() {\n if (this.#rafId) {\n cancelAnimationFrame(this.#rafId);\n this.#rafId = null;\n }\n this.#removeListeners();\n this.#canvas = null;\n this.#offscreenCanvas = null;\n this.#cachedRect = null;\n this.#subscribers.clear();\n this.#resizeSubscribers.clear();\n this.#hasTransferredControl = false;\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.button = null;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n this.#state.isDragging = false;\n this.#state.prevX = null;\n this.#state.prevY = null;\n }\n}\n", "import { defineSurface } from '@jucie.io/reactive';\n\nexport const usePointerSurface = defineSurface((setup) => {\n // Current normalized event from CanvasEvents\n const currentEvent = setup.value(null);\n \n // Hit registry integration (still managed here)\n const hoveredArea = setup.value(null);\n const activeArea = setup.value(null);\n \n // Main handler - just stores the event\n const handleEvent = setup.action((ctx, normalizedEvent) => {\n currentEvent.value = normalizedEvent;\n });\n \n const setHoveredArea = setup.action((ctx, area) => {\n hoveredArea.value = area;\n });\n \n const setActiveArea = setup.action((ctx, area) => {\n activeArea.value = area;\n });\n \n const reset = setup.action(() => {\n currentEvent.value = null;\n hoveredArea.value = null;\n activeArea.value = null;\n });\n \n return {\n event: currentEvent, // Access as: surface.event.value.x\n hoveredArea,\n activeArea,\n handleEvent,\n setHoveredArea,\n setActiveArea,\n reset\n };\n});\n", "import { ServiceProvider } from '@jucie.io/engine';\nimport { ContextTypes } from './ContextTypes.js';\nimport { createComputed, destroyComputed, addEffect } from '@jucie.io/reactive';\nimport { createDefinition, definitionType } from '@jucie.io/engine';\nimport { HitRegistry } from './HitRegistry.js';\nimport { CanvasEvents } from './CanvasEvents.js';\nimport { usePointerSurface } from './usePointerSurface.js';\n\nexport const defineBrush = createDefinition('BRUSH', [Object]);\nexport const defineLayer = createDefinition('LAYER', [Object]);\n\nexport class Painter extends ServiceProvider {\n #layers = new Map();\n #canvas = null; // Always OffscreenCanvas\n #contexts = new Map();\n #reactors = new Map();\n #assets = new Map();\n #isRunning = false;\n #frameId = null;\n #isRendering = false;\n #renderScheduled = false;\n\n // Mutable runtime config (separate from frozen config)\n #runtimeConfig = {\n targetFPS: 60,\n fixedTimeStep: 1000 / 60,\n timeScale: 1.0,\n debug: {\n enabled: false,\n showFPS: true,\n showBounds: true,\n showLayerTiming: true\n }\n };\n\n // Timing state\n #timing = {\n lastFrameTime: 0,\n deltaTime: 0,\n elapsedTime: 0,\n frameCount: 0\n };\n\n // Debug metrics\n #metrics = {\n fps: 0,\n frameTime: 0,\n layerTimes: new Map(),\n brushTimes: new Map(),\n skippedFrames: 0\n };\n\n // Hit detection state\n #hitRegistry = new HitRegistry();\n #pointerSurface = usePointerSurface();\n #canvasEvents = null; // Only created in main thread mode\n #pointerUnsubscribe = null;\n #resizeObserver = null; // For main thread canvas resize watching\n #subscribers = new Map(); // Map<event, Set<callback>>\n \n // Track state for event emission\n #wasOverCanvas = false;\n\n static manifest = {\n name: 'Painter',\n namespace: 'painter',\n version: '1.0.0',\n defaults: {\n // Timing configuration\n targetFPS: 60,\n fixedTimeStep: 1000 / 60,\n timeScale: 1.0,\n // Debug configuration\n debug: {\n enabled: false,\n showFPS: true,\n showBounds: true,\n showLayerTiming: true\n }\n }\n };\n\n getters () {\n return {\n pointer: () => this.#pointerSurface,\n };\n }\n\n actions() {\n // Initialize runtime config from frozen config\n if (this.config) {\n Object.assign(this.#runtimeConfig, this.config);\n }\n \n return {\n addLayer: (layerDef) => this.addLayer(layerDef),\n addLayers: (...layers) => {\n for (const layer of layers) {\n this.addLayer(layer);\n }\n },\n updateCanvas: (fn) => this.updateCanvas(fn),\n setCanvas: (canvas) => this.setCanvas(canvas),\n setOffscreenCanvas: (offscreenCanvas) => this.setOffscreenCanvas(offscreenCanvas),\n setAssets: (assets) => this.setAssets(assets),\n removeLayer: (name) => this.removeLayer(name),\n start: () => this.start(),\n stop: () => this.stop(),\n render: () => this.render(),\n setTargetFPS: (fps) => this.setTargetFPS(fps),\n setTimeScale: (scale) => this.setTimeScale(scale),\n setFixedTimeStep: (step) => this.setFixedTimeStep(step),\n setDebug: (options) => this.setDebug(options),\n getMetrics: () => this.getMetrics(),\n handleResize: (width, height) => this.handleResize(width, height),\n subscribe: (event, callback) => this.subscribe(event, callback),\n // Pointer API - receives normalized events from main thread\n handlePointerEvent: (normalizedEvent) => this.handlePointerEvent(normalizedEvent),\n subscribeToPointer: (callback) => this.#pointerSurface.$subscribe(callback),\n bindPointer: (path) => this.#pointerSurface.$bind(path),\n // Test helper - only for testing\n _testEmitPointerEvent: (normalizedEvent) => this._testEmitPointerEvent(normalizedEvent)\n };\n }\n\n // Main thread mode: Pass regular canvas, we create OffscreenCanvas + CanvasEvents\n setCanvas(canvas) {\n // Store reference to DOM canvas for resize observation\n const domCanvas = canvas;\n \n // Transfer control to offscreen\n const offscreenCanvas = canvas.transferControlToOffscreen();\n \n // Set initial dimensions\n offscreenCanvas.width = domCanvas.width;\n offscreenCanvas.height = domCanvas.height;\n \n this.#canvas = offscreenCanvas;\n \n // Create contexts for each type\n Object.values(ContextTypes).forEach(type => {\n try {\n const ctx = offscreenCanvas.getContext(type);\n if (ctx) this.#contexts.set(type, ctx);\n } catch (e) {\n console.warn(`Context type ${type} not supported`);\n }\n });\n\n // Create and set up canvas events (main thread only)\n if (!this.#canvasEvents) {\n this.#canvasEvents = new CanvasEvents();\n }\n \n this.#canvasEvents.setCanvas(domCanvas);\n\n // Watch for canvas resizes and sync to offscreen canvas\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n }\n \n this.#resizeObserver = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry && entry.target === domCanvas) {\n // Sync dimensions to offscreen canvas\n offscreenCanvas.width = domCanvas.width;\n offscreenCanvas.height = domCanvas.height;\n \n // Notify layers of resize\n this.handleResize(domCanvas.width, domCanvas.height);\n }\n });\n \n this.#resizeObserver.observe(domCanvas);\n\n // Connect canvas events to surface\n if (this.#pointerUnsubscribe) {\n this.#pointerUnsubscribe();\n }\n\n this.#pointerUnsubscribe = this.#canvasEvents.subscribe((normalizedEvent) => {\n this.handlePointerEvent(normalizedEvent);\n });\n }\n\n // Worker thread mode: Accept pre-created OffscreenCanvas, expect external events\n setOffscreenCanvas(offscreenCanvas) {\n this.#canvas = offscreenCanvas;\n \n // Create contexts for each type\n Object.values(ContextTypes).forEach(type => {\n try {\n const ctx = offscreenCanvas.getContext(type);\n if (ctx) this.#contexts.set(type, ctx);\n } catch (e) {\n console.warn(`Context type ${type} not supported`);\n }\n });\n\n // Don't create CanvasEvents - events will come from external source\n // via handlePointerEvent()\n }\n\n updateCanvas(fn) {\n const result = fn(this.#canvas);\n if (result) {\n this.#canvas = result;\n }\n }\n\n setAssets(assets) {\n this.#assets = assets;\n }\n\n start() {\n if (!this.#isRunning) {\n this.#isRunning = true;\n this.#scheduleRender();\n }\n }\n\n stop() {\n if (this.#isRunning) {\n this.#isRunning = false;\n if (this.#frameId) {\n cancelAnimationFrame(this.#frameId);\n this.#frameId = null;\n }\n }\n }\n\n addLayer(layerDef) {\n if (definitionType(layerDef) !== 'LAYER') {\n throw new Error('Invalid layer definition');\n }\n\n const name = layerDef._name;\n const config = layerDef(this.useContext, this.#hitRegistry);\n \n // Set up layer computed if it has data paths\n if (config.data) {\n const dataReactor = this.#createDataReactor(`layer_${name}`, config.data);\n if (dataReactor) {\n this.#reactors.set(`layer_${name}`, dataReactor);\n }\n }\n\n // Set up brush reactors and structure\n const brushes = config.children.map(child => {\n if (definitionType(child) === 'BRUSH') {\n const name = child._name;\n const brushConfig = child(this.useContext, this.#hitRegistry);\n \n // Only create data computed if data exists\n const dataReactor = brushConfig.data \n ? this.#createDataReactor(`brush_${name}`, brushConfig.data)\n : () => undefined;\n \n const whenReactor = brushConfig.when \n ? createComputed(brushConfig.when, {\n immediate: true,\n context: () => this.#pointerSurface\n })\n : null;\n\n const brush = {\n name,\n ...brushConfig,\n dataReactor,\n whenReactor\n };\n\n // Call brush mount hook\n if (brush.lifecycle?.onMount) {\n try {\n brush.lifecycle.onMount(this.#contexts.get(brush.context || config.context));\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" onMount:`, error);\n }\n }\n\n return brush;\n }\n // Handle nested layers recursively\n return this.addLayer(child);\n });\n\n const layer = {\n ...config,\n name,\n brushes,\n context: this.#contexts.get(config.context)\n };\n\n this.#layers.set(name, layer);\n\n // Call layer mount hook\n if (layer.lifecycle?.onMount) {\n try {\n layer.lifecycle.onMount(layer.context);\n } catch (error) {\n console.error(`Error in layer \"${name}\" onMount:`, error);\n }\n }\n\n return layer;\n }\n\n removeLayer(name) {\n const layer = this.#layers.get(name);\n if (!layer) return;\n\n // Call layer unmount hook\n if (layer.lifecycle?.onUnmount) {\n try {\n layer.lifecycle.onUnmount(layer.context);\n } catch (error) {\n console.error(`Error in layer \"${name}\" onUnmount:`, error);\n }\n }\n\n // Call brush unmount hooks and clean up reactors\n layer.brushes.forEach(brush => {\n if (brush.lifecycle?.onUnmount) {\n try {\n brush.lifecycle.onUnmount(\n this.#contexts.get(brush.context || layer.context)\n );\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" onUnmount:`, error);\n }\n }\n // Clean up brush computed and subscription\n const reactorData = this.#reactors.get(`painter_brush_${brush.name}`);\n if (reactorData) {\n reactorData.unsubscribe();\n if (reactorData.computed) {\n destroyComputed(reactorData.computed);\n }\n this.#reactors.delete(`painter_brush_${brush.name}`);\n }\n });\n\n // Clean up layer computed and subscription\n const layerReactorData = this.#reactors.get(`painter_layer_${name}`);\n if (layerReactorData) {\n layerReactorData.unsubscribe();\n if (layerReactorData.computed) {\n destroyComputed(layerReactorData.computed);\n }\n this.#reactors.delete(`painter_layer_${name}`);\n }\n\n this.#layers.delete(name);\n }\n\n #scheduleRender() {\n if (this.#renderScheduled || this.#isRendering) return;\n \n this.#renderScheduled = true;\n \n this.#frameId = requestAnimationFrame(() => {\n this.#renderScheduled = false;\n this.#frameId = null;\n this.#render();\n });\n }\n\n async #render() {\n if (!this.#canvas) return;\n this.#isRendering = true;\n \n try {\n // Clear hit registry at start of render\n this.#hitRegistry.clear();\n \n const renderStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n // Clear all contexts\n this.#contexts.forEach(ctx => {\n ctx.clearRect(0, 0, this.#canvas.width, this.#canvas.height);\n });\n\n // Render layers in order\n for (const layer of this.#layers.values()) {\n const layerStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n // Check layer condition\n if (layer.whenReactor) {\n const layerReactor = this.#reactors.get(`painter_layer_${layer.name}`)?.computed;\n if (!layer.when(layerReactor())) continue;\n }\n\n const ctx = layer.context;\n\n if (!ctx) continue;\n\n // Layer beforeRender hook\n if (layer.lifecycle?.beforeRender) {\n try {\n layer.lifecycle.beforeRender(ctx, this.#timing);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" beforeRender:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n\n // Apply layer settings\n ctx.save();\n if (layer.settings) {\n Object.entries(layer.settings).forEach(([key, value]) => {\n if (typeof ctx[key] === 'function') {\n ctx[key](...(Array.isArray(value) ? value : [value]));\n } else {\n ctx[key] = value;\n }\n });\n }\n\n // Render brushes\n for (const brush of layer.brushes) {\n const brushStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n if (brush.whenReactor && !brush.whenReactor()) continue;\n\n\n const brushCtx = brush.context ? \n this.#contexts.get(brush.context) : \n ctx;\n\n if (!brushCtx) continue;\n\n // Brush beforeRender hook\n if (brush.lifecycle?.beforeRender) {\n try {\n brush.lifecycle.beforeRender(brushCtx, this.#timing);\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" beforeRender:`, error);\n if (brush.lifecycle?.onError) brush.lifecycle.onError(error);\n continue;\n }\n }\n\n brushCtx.save();\n \n if (brush.settings) {\n Object.entries(brush.settings).forEach(([key, value]) => {\n if (typeof brushCtx[key] === 'function') {\n brushCtx[key](...(Array.isArray(value) ? value : [value]));\n } else {\n brushCtx[key] = value;\n }\n });\n }\n \n try {\n const requiredAssets = {};\n if (brush.assets) {\n for (const key of brush.assets) {\n requiredAssets[key] = this.#assets.get(key);\n }\n }\n brush.render(brushCtx, brush.dataReactor ? brush.dataReactor() : undefined, requiredAssets, this.#timing);\n\n // Brush afterRender hook\n if (brush.lifecycle?.afterRender) {\n brush.lifecycle.afterRender(brushCtx, this.#timing);\n }\n\n if (this.#runtimeConfig.debug?.enabled) {\n const brushTime = performance.now() - brushStart;\n this.#metrics.brushTimes.set(brush.name, brushTime);\n\n if (this.#runtimeConfig.debug?.showBounds) {\n this.#renderBrushBounds(brushCtx, brush);\n }\n }\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\":`, error);\n if (brush.lifecycle?.onError) brush.lifecycle.onError(error);\n } finally {\n brushCtx.restore();\n }\n }\n\n ctx.restore();\n\n // Layer afterRender hook\n if (layer.lifecycle?.afterRender) {\n try {\n layer.lifecycle.afterRender(ctx, this.#timing);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" afterRender:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n\n if (this.#runtimeConfig.debug?.enabled) {\n const layerTime = performance.now() - layerStart;\n this.#metrics.layerTimes.set(layer.name, layerTime);\n\n if (this.#runtimeConfig.debug?.showBounds) {\n this.#renderLayerBounds(ctx, layer);\n }\n }\n }\n\n // Render debug overlay if enabled\n if (this.#runtimeConfig.debug?.enabled) {\n this.#renderDebugOverlay();\n }\n \n } finally {\n this.#isRendering = false;\n }\n }\n\n #renderBrushBounds(ctx, brush) {\n ctx.save();\n ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';\n ctx.lineWidth = 1;\n ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n ctx.restore();\n }\n\n #renderLayerBounds(ctx, layer) {\n ctx.save();\n ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';\n ctx.lineWidth = 2;\n ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n ctx.restore();\n }\n\n #renderDebugOverlay() {\n const ctx = this.#contexts.get(ContextTypes['2D']);\n if (!ctx) return;\n\n ctx.save();\n ctx.resetTransform();\n ctx.font = '12px monospace';\n ctx.fillStyle = 'white';\n ctx.strokeStyle = 'black';\n ctx.lineWidth = 3;\n\n let y = 20;\n const lineHeight = 15;\n\n if (this.#runtimeConfig.debug?.showFPS) {\n const text = `FPS: ${Math.round(this.#metrics.fps)} (${this.#timing.deltaTime.toFixed(2)}ms)`;\n ctx.strokeText(text, 10, y);\n ctx.fillText(text, 10, y);\n y += lineHeight;\n }\n\n if (this.#runtimeConfig.debug?.showLayerTiming) {\n ctx.fillText('Layer Times:', 10, y);\n y += lineHeight;\n\n for (const [name, time] of this.#metrics.layerTimes) {\n const text = ` ${name}: ${time.toFixed(2)}ms`;\n ctx.strokeText(text, 10, y);\n ctx.fillText(text, 10, y);\n y += lineHeight;\n }\n\n ctx.fillText(this.state.get(['_transitions', 'pointer', 'currentState']), 10, y);\n }\n\n ctx.restore();\n }\n\n handleResize(width, height) {\n // Call onResize hooks for all layers\n for (const layer of this.#layers.values()) {\n if (layer.lifecycle?.onResize) {\n try {\n layer.lifecycle.onResize(width, height, layer.context);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" onResize:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n }\n }\n\n #createDataReactor(id, data) {\n const computed = createComputed(data, {\n immediate: true,\n context: () => this.#pointerSurface\n });\n\n const unsubscribe = addEffect(computed, () => this.#scheduleRender());\n\n this.#reactors.set(`painter_${id}`, {\n computed,\n unsubscribe\n });\n\n return computed;\n }\n\n destroy() {\n this.stop();\n\n // Clean up pointer system\n if (this.#pointerUnsubscribe) {\n this.#pointerUnsubscribe();\n this.#pointerUnsubscribe = null;\n }\n if (this.#canvasEvents) {\n this.#canvasEvents.destroy();\n this.#canvasEvents = null;\n }\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n if (this.#pointerSurface) {\n this.#pointerSurface.$destroy();\n }\n\n // Clean up all layers and reactors\n for (const name of this.#layers.keys()) {\n this.removeLayer(name);\n }\n }\n\n setTargetFPS(fps) {\n this.#runtimeConfig.targetFPS = fps;\n this.#runtimeConfig.fixedTimeStep = 1000 / fps;\n }\n\n setTimeScale(scale) {\n this.#runtimeConfig.timeScale = Math.max(0, scale);\n }\n\n setFixedTimeStep(step) {\n this.#runtimeConfig.fixedTimeStep = step;\n }\n\n setDebug(options = {}) {\n if (!this.#runtimeConfig.debug) {\n this.#runtimeConfig.debug = {};\n }\n Object.assign(this.#runtimeConfig.debug, options);\n }\n\n getMetrics() {\n return {\n ...this.#metrics,\n deltaTime: this.#timing.deltaTime,\n elapsedTime: this.#timing.elapsedTime,\n frameCount: this.#timing.frameCount\n };\n }\n\n // Public method to receive pointer events from main thread\n handlePointerEvent(normalizedEvent) {\n // Feed normalized events into surface\n this.#pointerSurface.handleEvent(normalizedEvent);\n\n // Handle hit testing and interactions\n this.#handlePointerInteraction(normalizedEvent);\n \n // Emit generic pointer events for external subscribers\n this.#emitPointerEvents(normalizedEvent);\n }\n\n #emitPointerEvents(normalizedEvent) {\n const { type } = normalizedEvent;\n const pointer = this.#pointerSurface;\n const event = pointer.event.value;\n \n // Emit basic pointer events\n switch (type) {\n case 'down':\n this.#emit('pointer:down', pointer);\n break;\n \n case 'up':\n this.#emit('pointer:up', pointer);\n \n // Emit click if it wasn't a drag\n if (event && !event.isDragging) {\n this.#emit('pointer:click', pointer);\n }\n break;\n \n case 'move':\n this.#emit('pointer:move', pointer);\n break;\n \n case 'dragstart':\n this.#emit('pointer:drag:start', pointer);\n break;\n \n case 'drag':\n this.#emit('pointer:drag:move', pointer);\n break;\n \n case 'dragend':\n this.#emit('pointer:drag:end', pointer);\n break;\n \n case 'scroll':\n this.#emit('pointer:scroll', pointer);\n break;\n \n case 'zoom':\n this.#emit('pointer:zoom', pointer);\n break;\n \n case 'dblclick':\n this.#emit('pointer:dblclick', pointer);\n break;\n }\n \n // Check for canvas enter/leave\n const wasOverCanvas = this.#wasOverCanvas;\n const isOverCanvas = event?.isOverCanvas || false;\n \n if (isOverCanvas && !wasOverCanvas) {\n this.#emit('pointer:enter', pointer);\n } else if (!isOverCanvas && wasOverCanvas) {\n this.#emit('pointer:leave', pointer);\n }\n \n this.#wasOverCanvas = isOverCanvas;\n }\n\n #handlePointerInteraction(normalizedEvent) {\n const { type, x, y } = normalizedEvent;\n const pointer = this.#pointerSurface;\n\n switch (type) {\n case 'down': {\n const hitArea = this.#hitTest(x, y);\n pointer.setActiveArea(hitArea);\n\n if (hitArea?.onPointerDown?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerDown.handler({\n ...pointer,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'up': {\n const activeArea = pointer.activeArea;\n if (activeArea?.onPointerUp?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onPointerUp.handler({\n ...pointer,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'move': {\n const hitArea = this.#hitTest(x, y);\n const prevHovered = pointer.hoveredArea;\n\n // Handle drag on active area\n const activeArea = pointer.activeArea;\n if (activeArea?.onPointerMove?.handler && pointer.isDragging) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onPointerMove.handler({\n ...pointer,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n // Handle hover changes\n if (hitArea?.id !== prevHovered?.id) {\n if (prevHovered?.onPointerLeave?.handler) {\n const ctx = this.#getContextForArea(prevHovered);\n prevHovered.onPointerLeave.handler({\n ...pointer,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n if (hitArea?.onPointerEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerEnter.handler({\n ...pointer,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n pointer.setHoveredArea(hitArea);\n }\n break;\n }\n\n case 'scroll':\n case 'zoom':\n // These are already emitted in #emitPointerEvents\n break;\n\n case 'dblclick':\n // This is already emitted in #emitPointerEvents\n break;\n }\n }\n\n #getContextForArea(area) {\n if (!area) return null;\n return area.context \n ? this.#contexts.get(area.context) \n : this.#contexts.get(ContextTypes['2D']);\n }\n\n subscribe(event, callback) {\n if (!this.#subscribers.has(event)) {\n this.#subscribers.set(event, new Set());\n }\n this.#subscribers.get(event).add(callback);\n \n return () => {\n const callbacks = this.#subscribers.get(event);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) {\n this.#subscribers.delete(event);\n }\n }\n };\n }\n\n #hitTest(x, y) {\n // Sort by priority (highest first) and test\n const sorted = this.#hitRegistry.areas.sort((a, b) => \n (b.priority || 0) - (a.priority || 0)\n );\n \n for (const area of sorted) {\n if (this.#isPointInBounds(x, y, area.bounds)) {\n return area;\n }\n }\n return null;\n }\n\n #isPointInBounds(x, y, bounds) {\n return x >= bounds.x && \n x <= bounds.x + bounds.width &&\n y >= bounds.y && \n y <= bounds.y + bounds.height;\n }\n\n #emit(event, data) {\n const callbacks = this.#subscribers.get(event);\n if (callbacks) {\n for (const callback of callbacks) {\n callback(data);\n }\n }\n }\n\n // Test helper - only for testing, simulates normalized pointer events\n _testEmitPointerEvent(normalizedEvent) {\n this.#pointerSurface.handleEvent(normalizedEvent);\n this.#handlePointerInteraction(normalizedEvent);\n }\n}"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["export const ContextTypes = {\n '2D': '2d',\n 'WEBGL': 'webgl',\n 'WEBGL2': 'webgl2',\n 'BITMAPRENDERER': 'bitmaprenderer'\n};", "export class HitRegistry {\n #areas = new Map();\n\n register(id, area) {\n if (!id) {\n throw new Error('Hit area must have an id');\n }\n this.#areas.set(id, { id, ...area });\n return () => this.unregister(id);\n }\n\n unregister(id) {\n this.#areas.delete(id);\n }\n\n get(id) {\n return this.#areas.get(id);\n }\n\n has(id) {\n return this.#areas.has(id);\n }\n\n get areas() {\n return Array.from(this.#areas.values());\n }\n\n clear() {\n this.#areas.clear();\n }\n}", "import { ServiceProvider } from '@jucie.io/engine';\n\nexport class CanvasEvents extends ServiceProvider {\n #canvas = null;\n #offscreenCanvas = null;\n #cachedRect = null;\n #resizeObserver = null;\n #subscribers = new Set();\n #resizeSubscribers = new Set();\n #pendingMove = null;\n #rafId = null;\n #hasTransferredControl = false;\n\n // Internal state for semantic event interpretation\n #state = {\n isPressed: false,\n button: null,\n dragStartX: null,\n dragStartY: null,\n isDragging: false,\n dragThreshold: 5,\n prevX: null,\n prevY: null\n };\n\n static manifest = {\n name: 'CanvasEvents',\n namespace: 'canvasEvents',\n version: '1.0.0'\n };\n\n actions() {\n return {\n setCanvas: (canvas) => this.setCanvas(canvas),\n subscribe: (listener) => this.subscribe(listener),\n onResize: (listener) => this.onResize(listener),\n transferControlToOffscreen: () => this.transferControlToOffscreen()\n };\n }\n\n setCanvas(canvas) {\n if (this.#canvas) {\n this.#removeListeners();\n }\n \n this.#canvas = canvas;\n this.#updateCachedRect();\n this.#initializeListeners();\n }\n\n subscribe(subscriber) {\n this.#subscribers.add(subscriber);\n return () => this.#subscribers.delete(subscriber);\n }\n\n onResize(subscriber) {\n this.#resizeSubscribers.add(subscriber);\n return () => this.#resizeSubscribers.delete(subscriber);\n }\n\n transferControlToOffscreen() {\n if (!this.#canvas) {\n throw new Error('Canvas must be set before transferring control to offscreen');\n }\n\n if (this.#hasTransferredControl) {\n throw new Error('Control has already been transferred to offscreen');\n }\n\n // Transfer control\n this.#offscreenCanvas = this.#canvas.transferControlToOffscreen();\n this.#hasTransferredControl = true;\n\n // Set initial dimensions on offscreen canvas\n this.#offscreenCanvas.width = this.#canvas.width;\n this.#offscreenCanvas.height = this.#canvas.height;\n\n // Emit initial resize event with actual canvas dimensions\n this.#emitResize({\n width: this.#canvas.width,\n height: this.#canvas.height\n });\n\n return this.#offscreenCanvas;\n }\n\n #updateCachedRect() {\n if (this.#canvas) {\n this.#cachedRect = this.#canvas.getBoundingClientRect();\n }\n }\n\n #initializeListeners() {\n if (!this.#canvas) return;\n\n this.#updateCachedRect();\n\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n if (entry.target !== this.#canvas) {\n continue;\n }\n const { width, height } = entry.contentRect;\n this.#emitResize({\n width: width,\n height: height\n });\n }\n this.#updateCachedRect();\n });\n this.#resizeObserver.observe(this.#canvas);\n\n document.addEventListener('wheel', this.#handleScroll, { passive: false });\n document.addEventListener('pointermove', this.#handleMove);\n document.addEventListener('pointerdown', this.#handleDown);\n document.addEventListener('pointerup', this.#handleUp);\n document.addEventListener('pointercancel', this.#handleUp);\n document.addEventListener('dblclick', this.#handleDblClick);\n }\n\n #removeListeners() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n\n document.removeEventListener('wheel', this.#handleScroll);\n document.removeEventListener('pointermove', this.#handleMove);\n document.removeEventListener('pointerdown', this.#handleDown);\n document.removeEventListener('pointerup', this.#handleUp);\n document.removeEventListener('pointercancel', this.#handleUp);\n document.removeEventListener('dblclick', this.#handleDblClick);\n }\n\n #handleScroll = (event) => {\n if (event.target !== this.#canvas) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n \n if (event.ctrlKey) {\n const normalized = this.#normalizeEvent(event, 'zoom');\n this.#emit(normalized);\n } else {\n const normalized = this.#normalizeEvent(event, 'scroll');\n this.#emit(normalized);\n }\n }\n\n #handleMove = (event) => {\n // Store latest raw event and throttle with RAF\n this.#pendingMove = event;\n if (this.#rafId) return;\n \n this.#rafId = requestAnimationFrame(() => {\n if (this.#pendingMove) {\n const rawEvent = this.#pendingMove;\n this.#pendingMove = null;\n \n // Determine event type based on state\n let type = 'move';\n const position = this.#getPosition(rawEvent);\n \n // Check for drag start\n if (this.#state.isPressed && !this.#state.isDragging) {\n const dx = position.x - this.#state.dragStartX;\n const dy = position.y - this.#state.dragStartY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n \n if (distance > this.#state.dragThreshold) {\n this.#state.isDragging = true;\n type = 'dragstart';\n }\n } else if (this.#state.isDragging) {\n type = 'drag';\n }\n \n const normalized = this.#normalizeEvent(rawEvent, type);\n this.#emit(normalized);\n }\n this.#rafId = null;\n });\n }\n\n #handleDown = (event) => {\n // Only capture if starting on canvas\n if (event.target === this.#canvas) {\n const position = this.#getPosition(event);\n \n // Update state\n this.#state.isPressed = true;\n this.#state.button = event.button ?? null;\n this.#state.dragStartX = position.x;\n this.#state.dragStartY = position.y;\n this.#state.isDragging = false;\n \n const normalized = this.#normalizeEvent(event, 'down');\n this.#emit(normalized); // Immediate\n }\n }\n\n #handleUp = (event) => {\n // Emit dragend if we were dragging\n if (this.#state.isDragging) {\n const dragend = this.#normalizeEvent(event, 'dragend');\n this.#emit(dragend);\n }\n \n // Always emit up event\n const normalized = this.#normalizeEvent(event, 'up');\n this.#emit(normalized); // Immediate\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.isDragging = false;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n }\n\n #handleDblClick = (event) => {\n const normalized = this.#normalizeEvent(event, 'dblclick');\n this.#emit(normalized);\n }\n\n #emit(event) {\n for (const subscriber of this.#subscribers) {\n subscriber(event);\n }\n }\n\n #emitResize(resizeData) {\n for (const subscriber of this.#resizeSubscribers) {\n subscriber(resizeData);\n }\n }\n\n #getPosition(event) {\n const isOverCanvas = event.target === this.#canvas;\n \n let x, y;\n if (isOverCanvas) {\n x = event.offsetX;\n y = event.offsetY;\n } else if (this.#cachedRect) {\n x = event.clientX - this.#cachedRect.left;\n y = event.clientY - this.#cachedRect.top;\n } else {\n x = event.clientX;\n y = event.clientY;\n }\n \n return { x, y, isOverCanvas };\n }\n\n #normalizeEvent(event, type) {\n const { x, y, isOverCanvas } = this.#getPosition(event);\n\n const isWithinBounds = isOverCanvas || (\n this.#cachedRect &&\n x >= 0 && \n x <= this.#cachedRect.width && \n y >= 0 && \n y <= this.#cachedRect.height\n );\n \n // Calculate deltas based on event type\n let deltaX = 0;\n let deltaY = 0;\n let deltaZ = 0;\n let deltaMode = 0;\n \n if (type === 'scroll') {\n // Scroll events use wheel deltas\n deltaX = event.deltaX;\n deltaY = event.deltaY;\n deltaZ = event.deltaZ;\n deltaMode = event.deltaMode;\n } else if (type === 'zoom') {\n // Zoom uses simplified delta\n deltaX = 0;\n deltaY = event.deltaY;\n deltaZ = 0;\n } else if (type === 'move' || type === 'drag' || type === 'dragstart') {\n // Position-based events calculate deltas from previous position\n if (this.#state.prevX !== null && this.#state.prevY !== null) {\n deltaX = x - this.#state.prevX;\n deltaY = y - this.#state.prevY;\n }\n }\n \n // Calculate drag distance if dragging\n let dragDistance = 0;\n if (this.#state.isDragging && this.#state.dragStartX !== null && this.#state.dragStartY !== null) {\n const dx = x - this.#state.dragStartX;\n const dy = y - this.#state.dragStartY;\n dragDistance = Math.sqrt(dx * dx + dy * dy);\n }\n\n const normalized = {\n // Position\n x,\n y,\n clientX: event.clientX,\n clientY: event.clientY,\n prevX: this.#state.prevX,\n prevY: this.#state.prevY,\n \n // Event metadata\n type,\n timestamp: Date.now(),\n isOverCanvas,\n isWithinBounds,\n \n // Deltas (appropriate to event type)\n deltaX,\n deltaY,\n deltaZ,\n deltaMode,\n \n // Button state\n button: event.button ?? this.#state.button,\n buttons: event.buttons ?? 0,\n isPressed: this.#state.isPressed,\n \n // Drag state\n isDragging: this.#state.isDragging,\n dragStartX: this.#state.dragStartX,\n dragStartY: this.#state.dragStartY,\n dragDistance,\n \n // Modifiers\n shiftKey: event.shiftKey || false,\n ctrlKey: event.ctrlKey || false,\n altKey: event.altKey || false,\n metaKey: event.metaKey || false\n };\n \n // Update previous position for next delta calculation\n this.#state.prevX = x;\n this.#state.prevY = y;\n\n return normalized;\n }\n\n destroy() {\n if (this.#rafId) {\n cancelAnimationFrame(this.#rafId);\n this.#rafId = null;\n }\n this.#removeListeners();\n this.#canvas = null;\n this.#offscreenCanvas = null;\n this.#cachedRect = null;\n this.#subscribers.clear();\n this.#resizeSubscribers.clear();\n this.#hasTransferredControl = false;\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.button = null;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n this.#state.isDragging = false;\n this.#state.prevX = null;\n this.#state.prevY = null;\n }\n}\n", "import { defineSurface } from '@jucie.io/reactive';\n\nexport const usePointerSurface = defineSurface((setup) => {\n // Current normalized event from CanvasEvents\n const currentEvent = setup.value(null);\n \n // Hit registry integration (still managed here)\n const hoveredArea = setup.value(null);\n const activeArea = setup.value(null);\n \n // Main handler - just stores the event\n const handleEvent = setup.action((ctx, normalizedEvent) => {\n currentEvent.value = normalizedEvent;\n });\n \n const setHoveredArea = setup.action((ctx, area) => {\n hoveredArea.value = area;\n });\n \n const setActiveArea = setup.action((ctx, area) => {\n activeArea.value = area;\n });\n \n const reset = setup.action(() => {\n currentEvent.value = null;\n hoveredArea.value = null;\n activeArea.value = null;\n });\n \n return {\n event: currentEvent, // Access as: surface.event.value.x\n hoveredArea,\n activeArea,\n handleEvent,\n setHoveredArea,\n setActiveArea,\n reset\n };\n});\n", "import { ServiceProvider } from '@jucie.io/engine';\nimport { ContextTypes } from './ContextTypes.js';\nimport { createComputed, destroyComputed, addEffect } from '@jucie.io/reactive';\nimport { createDefinition, definitionType } from '@jucie.io/engine';\nimport { HitRegistry } from './HitRegistry.js';\nimport { CanvasEvents } from './CanvasEvents.js';\nimport { usePointerSurface } from './usePointerSurface.js';\n\nexport const defineBrush = createDefinition('BRUSH', [Object]);\nexport const defineLayer = createDefinition('LAYER', [Object]);\n\nexport class Painter extends ServiceProvider {\n #layers = new Map();\n #canvas = null; // Always OffscreenCanvas\n #contexts = new Map();\n #reactors = new Map();\n #assets = new Map();\n #isRunning = false;\n #frameId = null;\n #isRendering = false;\n #renderScheduled = false;\n\n // Mutable runtime config (separate from frozen config)\n #runtimeConfig = {\n targetFPS: 60,\n fixedTimeStep: 1000 / 60,\n timeScale: 1.0,\n debug: {\n enabled: false,\n showFPS: true,\n showBounds: true,\n showLayerTiming: true\n }\n };\n\n // Timing state\n #timing = {\n lastFrameTime: 0,\n deltaTime: 0,\n elapsedTime: 0,\n frameCount: 0\n };\n\n // Debug metrics\n #metrics = {\n fps: 0,\n frameTime: 0,\n layerTimes: new Map(),\n brushTimes: new Map(),\n skippedFrames: 0\n };\n\n // Hit detection state\n #hitRegistry = new HitRegistry();\n #pointerSurface = usePointerSurface();\n #canvasEvents = null; // Only created in main thread mode\n #pointerUnsubscribe = null;\n #resizeObserver = null; // For main thread canvas resize watching\n #subscribers = new Map(); // Map<event, Set<callback>>\n \n // Track state for event emission\n #wasOverCanvas = false;\n\n static manifest = {\n name: 'Painter',\n namespace: 'painter',\n version: '1.0.0',\n defaults: {\n // Timing configuration\n targetFPS: 60,\n fixedTimeStep: 1000 / 60,\n timeScale: 1.0,\n // Debug configuration\n debug: {\n enabled: false,\n showFPS: true,\n showBounds: true,\n showLayerTiming: true\n }\n }\n };\n\n getters () {\n return {\n pointer: () => this.#pointerSurface,\n };\n }\n\n actions() {\n // Initialize runtime config from frozen config\n if (this.config) {\n Object.assign(this.#runtimeConfig, this.config);\n }\n \n return {\n addLayer: (layerDef) => this.addLayer(layerDef),\n addLayers: (...layers) => {\n for (const layer of layers) {\n this.addLayer(layer);\n }\n },\n updateCanvas: (fn) => this.updateCanvas(fn),\n setCanvas: (canvas) => this.setCanvas(canvas),\n setOffscreenCanvas: (offscreenCanvas) => this.setOffscreenCanvas(offscreenCanvas),\n setAssets: (assets) => this.setAssets(assets),\n removeLayer: (name) => this.removeLayer(name),\n start: () => this.start(),\n stop: () => this.stop(),\n render: () => this.render(),\n setTargetFPS: (fps) => this.setTargetFPS(fps),\n setTimeScale: (scale) => this.setTimeScale(scale),\n setFixedTimeStep: (step) => this.setFixedTimeStep(step),\n setDebug: (options) => this.setDebug(options),\n getMetrics: () => this.getMetrics(),\n handleResize: (width, height) => this.handleResize(width, height),\n subscribe: (event, callback) => this.subscribe(event, callback),\n // Pointer API - receives normalized events from main thread\n handlePointerEvent: (normalizedEvent) => this.handlePointerEvent(normalizedEvent),\n subscribeToPointer: (callback) => this.#pointerSurface.$subscribe(callback),\n bindPointer: (path) => this.#pointerSurface.$bind(path),\n // Test helper - only for testing\n _testEmitPointerEvent: (normalizedEvent) => this._testEmitPointerEvent(normalizedEvent)\n };\n }\n\n // Main thread mode: Pass regular canvas, we create OffscreenCanvas + CanvasEvents\n setCanvas(canvas) {\n // Store reference to DOM canvas for resize observation\n const domCanvas = canvas;\n \n // Transfer control to offscreen\n const offscreenCanvas = canvas.transferControlToOffscreen();\n \n // Set initial dimensions\n offscreenCanvas.width = domCanvas.width;\n offscreenCanvas.height = domCanvas.height;\n \n this.#canvas = offscreenCanvas;\n \n // Create contexts for each type\n Object.values(ContextTypes).forEach(type => {\n try {\n const ctx = offscreenCanvas.getContext(type);\n if (ctx) this.#contexts.set(type, ctx);\n } catch (e) {\n console.warn(`Context type ${type} not supported`);\n }\n });\n\n // Create and set up canvas events (main thread only)\n if (!this.#canvasEvents) {\n this.#canvasEvents = new CanvasEvents();\n }\n \n this.#canvasEvents.setCanvas(domCanvas);\n\n // Watch for canvas resizes and sync to offscreen canvas\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n }\n \n this.#resizeObserver = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry && entry.target === domCanvas) {\n // Sync dimensions to offscreen canvas\n offscreenCanvas.width = domCanvas.width;\n offscreenCanvas.height = domCanvas.height;\n \n // Notify layers of resize\n this.handleResize(domCanvas.width, domCanvas.height);\n }\n });\n \n this.#resizeObserver.observe(domCanvas);\n\n // Connect canvas events to surface\n if (this.#pointerUnsubscribe) {\n this.#pointerUnsubscribe();\n }\n\n this.#pointerUnsubscribe = this.#canvasEvents.subscribe((normalizedEvent) => {\n this.handlePointerEvent(normalizedEvent);\n });\n }\n\n // Worker thread mode: Accept pre-created OffscreenCanvas, expect external events\n setOffscreenCanvas(offscreenCanvas) {\n this.#canvas = offscreenCanvas;\n \n // Create contexts for each type\n Object.values(ContextTypes).forEach(type => {\n try {\n const ctx = offscreenCanvas.getContext(type);\n if (ctx) this.#contexts.set(type, ctx);\n } catch (e) {\n console.warn(`Context type ${type} not supported`);\n }\n });\n\n // Don't create CanvasEvents - events will come from external source\n // via handlePointerEvent()\n }\n\n updateCanvas(fn) {\n const result = fn(this.#canvas);\n if (result) {\n this.#canvas = result;\n }\n }\n\n setAssets(assets) {\n this.#assets = assets;\n }\n\n start() {\n if (!this.#isRunning) {\n this.#isRunning = true;\n this.#scheduleRender();\n }\n }\n\n stop() {\n if (this.#isRunning) {\n this.#isRunning = false;\n if (this.#frameId) {\n cancelAnimationFrame(this.#frameId);\n this.#frameId = null;\n }\n }\n }\n\n addLayer(layerDef) {\n if (definitionType(layerDef) !== 'LAYER') {\n throw new Error('Invalid layer definition');\n }\n\n const name = layerDef._name;\n const config = layerDef(this.useContext, this.#hitRegistry);\n \n // Set up layer computed if it has data paths\n if (config.data) {\n const dataReactor = this.#createDataReactor(`layer_${name}`, config.data);\n if (dataReactor) {\n this.#reactors.set(`layer_${name}`, dataReactor);\n }\n }\n\n // Set up brush reactors and structure\n const brushes = config.children.map(child => {\n if (definitionType(child) === 'BRUSH') {\n const name = child._name;\n const brushConfig = child(this.useContext, this.#hitRegistry);\n \n // Only create data computed if data exists\n const dataReactor = brushConfig.data \n ? this.#createDataReactor(`brush_${name}`, brushConfig.data)\n : () => undefined;\n \n const whenReactor = brushConfig.when \n ? createComputed(brushConfig.when, {\n immediate: true,\n context: () => this.#pointerSurface\n })\n : null;\n\n const brush = {\n name,\n ...brushConfig,\n dataReactor,\n whenReactor\n };\n\n // Call brush mount hook\n if (brush.lifecycle?.onMount) {\n try {\n brush.lifecycle.onMount(this.#contexts.get(brush.context || config.context));\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" onMount:`, error);\n }\n }\n\n return brush;\n }\n // Handle nested layers recursively\n return this.addLayer(child);\n });\n\n const layer = {\n ...config,\n name,\n brushes,\n context: this.#contexts.get(config.context)\n };\n\n this.#layers.set(name, layer);\n\n // Call layer mount hook\n if (layer.lifecycle?.onMount) {\n try {\n layer.lifecycle.onMount(layer.context);\n } catch (error) {\n console.error(`Error in layer \"${name}\" onMount:`, error);\n }\n }\n\n return layer;\n }\n\n removeLayer(name) {\n const layer = this.#layers.get(name);\n if (!layer) return;\n\n // Call layer unmount hook\n if (layer.lifecycle?.onUnmount) {\n try {\n layer.lifecycle.onUnmount(layer.context);\n } catch (error) {\n console.error(`Error in layer \"${name}\" onUnmount:`, error);\n }\n }\n\n // Call brush unmount hooks and clean up reactors\n layer.brushes.forEach(brush => {\n if (brush.lifecycle?.onUnmount) {\n try {\n brush.lifecycle.onUnmount(\n this.#contexts.get(brush.context || layer.context)\n );\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" onUnmount:`, error);\n }\n }\n // Clean up brush computed and subscription\n const reactorData = this.#reactors.get(`painter_brush_${brush.name}`);\n if (reactorData) {\n reactorData.unsubscribe();\n if (reactorData.computed) {\n destroyComputed(reactorData.computed);\n }\n this.#reactors.delete(`painter_brush_${brush.name}`);\n }\n });\n\n // Clean up layer computed and subscription\n const layerReactorData = this.#reactors.get(`painter_layer_${name}`);\n if (layerReactorData) {\n layerReactorData.unsubscribe();\n if (layerReactorData.computed) {\n destroyComputed(layerReactorData.computed);\n }\n this.#reactors.delete(`painter_layer_${name}`);\n }\n\n this.#layers.delete(name);\n }\n\n #scheduleRender() {\n if (this.#renderScheduled || this.#isRendering) return;\n \n this.#renderScheduled = true;\n \n this.#frameId = requestAnimationFrame(() => {\n this.#renderScheduled = false;\n this.#frameId = null;\n this.#render();\n });\n }\n\n async #render() {\n if (!this.#canvas) return;\n this.#isRendering = true;\n \n try {\n // Clear hit registry at start of render\n this.#hitRegistry.clear();\n \n const renderStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n // Clear all contexts\n this.#contexts.forEach(ctx => {\n ctx.clearRect(0, 0, this.#canvas.width, this.#canvas.height);\n });\n\n // Render layers in order\n for (const layer of this.#layers.values()) {\n const layerStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n // Check layer condition\n if (layer.whenReactor) {\n const layerReactor = this.#reactors.get(`painter_layer_${layer.name}`)?.computed;\n if (!layer.when(layerReactor())) continue;\n }\n\n const ctx = layer.context;\n\n if (!ctx) continue;\n\n // Layer beforeRender hook\n if (layer.lifecycle?.beforeRender) {\n try {\n layer.lifecycle.beforeRender(ctx, this.#timing);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" beforeRender:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n\n // Apply layer settings\n ctx.save();\n if (layer.settings) {\n Object.entries(layer.settings).forEach(([key, value]) => {\n if (typeof ctx[key] === 'function') {\n ctx[key](...(Array.isArray(value) ? value : [value]));\n } else {\n ctx[key] = value;\n }\n });\n }\n\n // Render brushes\n for (const brush of layer.brushes) {\n const brushStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n if (brush.whenReactor && !brush.whenReactor()) continue;\n\n\n const brushCtx = brush.context ? \n this.#contexts.get(brush.context) : \n ctx;\n\n if (!brushCtx) continue;\n\n // Brush beforeRender hook\n if (brush.lifecycle?.beforeRender) {\n try {\n brush.lifecycle.beforeRender(brushCtx, this.#timing);\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" beforeRender:`, error);\n if (brush.lifecycle?.onError) brush.lifecycle.onError(error);\n continue;\n }\n }\n\n brushCtx.save();\n \n if (brush.settings) {\n Object.entries(brush.settings).forEach(([key, value]) => {\n if (typeof brushCtx[key] === 'function') {\n brushCtx[key](...(Array.isArray(value) ? value : [value]));\n } else {\n brushCtx[key] = value;\n }\n });\n }\n \n try {\n const requiredAssets = {};\n if (brush.assets) {\n for (const key of brush.assets) {\n requiredAssets[key] = this.#assets.get(key);\n }\n }\n brush.render(brushCtx, brush.dataReactor ? brush.dataReactor() : undefined, requiredAssets, this.#timing);\n\n // Brush afterRender hook\n if (brush.lifecycle?.afterRender) {\n brush.lifecycle.afterRender(brushCtx, this.#timing);\n }\n\n if (this.#runtimeConfig.debug?.enabled) {\n const brushTime = performance.now() - brushStart;\n this.#metrics.brushTimes.set(brush.name, brushTime);\n\n if (this.#runtimeConfig.debug?.showBounds) {\n this.#renderBrushBounds(brushCtx, brush);\n }\n }\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\":`, error);\n if (brush.lifecycle?.onError) brush.lifecycle.onError(error);\n } finally {\n brushCtx.restore();\n }\n }\n\n ctx.restore();\n\n // Layer afterRender hook\n if (layer.lifecycle?.afterRender) {\n try {\n layer.lifecycle.afterRender(ctx, this.#timing);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" afterRender:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n\n if (this.#runtimeConfig.debug?.enabled) {\n const layerTime = performance.now() - layerStart;\n this.#metrics.layerTimes.set(layer.name, layerTime);\n\n if (this.#runtimeConfig.debug?.showBounds) {\n this.#renderLayerBounds(ctx, layer);\n }\n }\n }\n\n // Render debug overlay if enabled\n if (this.#runtimeConfig.debug?.enabled) {\n this.#renderDebugOverlay();\n }\n \n } finally {\n this.#isRendering = false;\n }\n }\n\n #renderBrushBounds(ctx, brush) {\n ctx.save();\n ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';\n ctx.lineWidth = 1;\n ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n ctx.restore();\n }\n\n #renderLayerBounds(ctx, layer) {\n ctx.save();\n ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';\n ctx.lineWidth = 2;\n ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n ctx.restore();\n }\n\n #renderDebugOverlay() {\n const ctx = this.#contexts.get(ContextTypes['2D']);\n if (!ctx) return;\n\n ctx.save();\n ctx.resetTransform();\n ctx.font = '12px monospace';\n ctx.fillStyle = 'white';\n ctx.strokeStyle = 'black';\n ctx.lineWidth = 3;\n\n let y = 20;\n const lineHeight = 15;\n\n if (this.#runtimeConfig.debug?.showFPS) {\n const text = `FPS: ${Math.round(this.#metrics.fps)} (${this.#timing.deltaTime.toFixed(2)}ms)`;\n ctx.strokeText(text, 10, y);\n ctx.fillText(text, 10, y);\n y += lineHeight;\n }\n\n if (this.#runtimeConfig.debug?.showLayerTiming) {\n ctx.fillText('Layer Times:', 10, y);\n y += lineHeight;\n\n for (const [name, time] of this.#metrics.layerTimes) {\n const text = ` ${name}: ${time.toFixed(2)}ms`;\n ctx.strokeText(text, 10, y);\n ctx.fillText(text, 10, y);\n y += lineHeight;\n }\n\n ctx.fillText(this.state.get(['_transitions', 'pointer', 'currentState']), 10, y);\n }\n\n ctx.restore();\n }\n\n handleResize(width, height) {\n // Call onResize hooks for all layers\n for (const layer of this.#layers.values()) {\n if (layer.lifecycle?.onResize) {\n try {\n layer.lifecycle.onResize(width, height, layer.context);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" onResize:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n }\n }\n\n #createDataReactor(id, data) {\n const computed = createComputed(data, {\n immediate: true,\n context: () => this.#pointerSurface\n });\n\n const unsubscribe = addEffect(computed, () => this.#scheduleRender());\n\n this.#reactors.set(`painter_${id}`, {\n computed,\n unsubscribe\n });\n\n return computed;\n }\n\n destroy() {\n this.stop();\n\n // Clean up pointer system\n if (this.#pointerUnsubscribe) {\n this.#pointerUnsubscribe();\n this.#pointerUnsubscribe = null;\n }\n if (this.#canvasEvents) {\n this.#canvasEvents.destroy();\n this.#canvasEvents = null;\n }\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n if (this.#pointerSurface) {\n this.#pointerSurface.$destroy();\n }\n\n // Clean up all layers and reactors\n for (const name of this.#layers.keys()) {\n this.removeLayer(name);\n }\n }\n\n setTargetFPS(fps) {\n this.#runtimeConfig.targetFPS = fps;\n this.#runtimeConfig.fixedTimeStep = 1000 / fps;\n }\n\n setTimeScale(scale) {\n this.#runtimeConfig.timeScale = Math.max(0, scale);\n }\n\n setFixedTimeStep(step) {\n this.#runtimeConfig.fixedTimeStep = step;\n }\n\n setDebug(options = {}) {\n if (!this.#runtimeConfig.debug) {\n this.#runtimeConfig.debug = {};\n }\n Object.assign(this.#runtimeConfig.debug, options);\n }\n\n getMetrics() {\n return {\n ...this.#metrics,\n deltaTime: this.#timing.deltaTime,\n elapsedTime: this.#timing.elapsedTime,\n frameCount: this.#timing.frameCount\n };\n }\n\n // Public method to receive pointer events from main thread\n handlePointerEvent(normalizedEvent) {\n // Feed normalized events into surface\n this.#pointerSurface.handleEvent(normalizedEvent);\n\n // Handle hit testing and interactions\n this.#handlePointerInteraction(normalizedEvent);\n \n // Emit generic pointer events for external subscribers\n this.#emitPointerEvents(normalizedEvent);\n }\n\n #emitPointerEvents(normalizedEvent) {\n const { type } = normalizedEvent;\n const pointer = this.#pointerSurface;\n const event = pointer.event.value;\n \n // Emit basic pointer events\n switch (type) {\n case 'down':\n this.#emit('pointer:down', pointer);\n break;\n \n case 'up':\n this.#emit('pointer:up', pointer);\n \n // Emit click if it wasn't a drag\n if (event && !event.isDragging) {\n this.#emit('pointer:click', pointer);\n }\n break;\n \n case 'move':\n this.#emit('pointer:move', pointer);\n break;\n \n case 'dragstart':\n this.#emit('pointer:drag:start', pointer);\n break;\n \n case 'drag':\n this.#emit('pointer:drag:move', pointer);\n break;\n \n case 'dragend':\n this.#emit('pointer:drag:end', pointer);\n break;\n \n case 'scroll':\n this.#emit('pointer:scroll', pointer);\n break;\n \n case 'zoom':\n this.#emit('pointer:zoom', pointer);\n break;\n \n case 'dblclick':\n this.#emit('pointer:dblclick', pointer);\n break;\n }\n \n // Check for canvas enter/leave\n const wasOverCanvas = this.#wasOverCanvas;\n const isOverCanvas = event?.isOverCanvas || false;\n \n if (isOverCanvas && !wasOverCanvas) {\n this.#emit('pointer:enter', pointer);\n } else if (!isOverCanvas && wasOverCanvas) {\n this.#emit('pointer:leave', pointer);\n }\n \n this.#wasOverCanvas = isOverCanvas;\n }\n\n #handlePointerInteraction(normalizedEvent) {\n const { type, x, y } = normalizedEvent;\n const pointer = this.#pointerSurface;\n\n switch (type) {\n case 'down': {\n const hitArea = this.#hitTest(x, y);\n pointer.setActiveArea(hitArea);\n\n if (hitArea?.onPointerDown?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerDown.handler({\n ...pointer,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'up': {\n const activeArea = pointer.activeArea;\n if (activeArea?.onPointerUp?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onPointerUp.handler({\n ...pointer,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'move': {\n const hitArea = this.#hitTest(x, y);\n const prevHovered = pointer.hoveredArea;\n\n // Handle drag on active area\n const activeArea = pointer.activeArea;\n if (activeArea?.onPointerMove?.handler && pointer.isDragging) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onPointerMove.handler({\n ...pointer,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n // Handle hover changes\n if (hitArea?.id !== prevHovered?.id) {\n if (prevHovered?.onPointerLeave?.handler) {\n const ctx = this.#getContextForArea(prevHovered);\n prevHovered.onPointerLeave.handler({\n ...pointer,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n if (hitArea?.onPointerEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerEnter.handler({\n ...pointer,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n pointer.setHoveredArea(hitArea);\n }\n break;\n }\n\n case 'scroll':\n case 'zoom':\n // These are already emitted in #emitPointerEvents\n break;\n\n case 'dblclick':\n // This is already emitted in #emitPointerEvents\n break;\n }\n }\n\n #getContextForArea(area) {\n if (!area) return null;\n return area.context \n ? this.#contexts.get(area.context) \n : this.#contexts.get(ContextTypes['2D']);\n }\n\n subscribe(event, callback) {\n if (!this.#subscribers.has(event)) {\n this.#subscribers.set(event, new Set());\n }\n this.#subscribers.get(event).add(callback);\n \n return () => {\n const callbacks = this.#subscribers.get(event);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) {\n this.#subscribers.delete(event);\n }\n }\n };\n }\n\n #hitTest(x, y) {\n // Sort by priority (highest first) and test\n const sorted = this.#hitRegistry.areas.sort((a, b) => \n (b.priority || 0) - (a.priority || 0)\n );\n \n for (const area of sorted) {\n if (this.#isPointInBounds(x, y, area.bounds)) {\n return area;\n }\n }\n return null;\n }\n\n #isPointInBounds(x, y, bounds) {\n return x >= bounds.x && \n x <= bounds.x + bounds.width &&\n y >= bounds.y && \n y <= bounds.y + bounds.height;\n }\n\n #emit(event, data) {\n const callbacks = this.#subscribers.get(event);\n if (callbacks) {\n for (const callback of callbacks) {\n callback(data);\n }\n }\n }\n\n // Test helper - only for testing, simulates normalized pointer events\n _testEmitPointerEvent(normalizedEvent) {\n this.#pointerSurface.handleEvent(normalizedEvent);\n this.#handlePointerInteraction(normalizedEvent);\n }\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["ContextTypes", "HitRegistry", "#areas", "id", "area", "ServiceProvider", "CanvasEvents", "#canvas", "#offscreenCanvas", "#cachedRect", "#resizeObserver", "#subscribers", "#resizeSubscribers", "#pendingMove", "#rafId", "#hasTransferredControl", "#state", "canvas", "listener", "#removeListeners", "#updateCachedRect", "#initializeListeners", "subscriber", "#emitResize", "entries", "entry", "width", "height", "#handleScroll", "#handleMove", "#handleDown", "#handleUp", "#handleDblClick", "event", "normalized", "#normalizeEvent", "#emit", "rawEvent", "type", "position", "#getPosition", "dx", "dy", "dragend", "resizeData", "isOverCanvas", "x", "y", "isWithinBounds", "deltaX", "deltaY", "deltaZ", "deltaMode", "dragDistance", "defineSurface", "usePointerSurface", "setup", "currentEvent", "hoveredArea", "activeArea", "handleEvent", "ctx", "normalizedEvent", "setHoveredArea", "area", "setActiveArea", "reset", "ServiceProvider", "createComputed", "destroyComputed", "addEffect", "createDefinition", "definitionType", "defineBrush", "defineLayer", "Painter", "#layers", "#canvas", "#contexts", "#reactors", "#assets", "#isRunning", "#frameId", "#isRendering", "#renderScheduled", "#runtimeConfig", "#timing", "#metrics", "#hitRegistry", "HitRegistry", "#pointerSurface", "usePointerSurface", "#canvasEvents", "#pointerUnsubscribe", "#resizeObserver", "#subscribers", "#wasOverCanvas", "layerDef", "layers", "layer", "fn", "canvas", "offscreenCanvas", "assets", "name", "fps", "scale", "step", "options", "width", "height", "event", "callback", "normalizedEvent", "path", "domCanvas", "ContextTypes", "type", "ctx", "CanvasEvents", "entries", "entry", "result", "#scheduleRender", "config", "dataReactor", "#createDataReactor", "brushes", "child", "brushConfig", "whenReactor", "brush", "error", "reactorData", "layerReactorData", "#render", "renderStart", "layerStart", "layerReactor", "key", "value", "brushStart", "brushCtx", "requiredAssets", "brushTime", "#renderBrushBounds", "layerTime", "#renderLayerBounds", "#renderDebugOverlay", "y", "lineHeight", "text", "time", "id", "data", "computed", "unsubscribe", "#handlePointerInteraction", "#emitPointerEvents", "pointer", "#emit", "wasOverCanvas", "isOverCanvas", "x", "hitArea", "#hitTest", "#getContextForArea", "activeArea", "prevHovered", "area", "callbacks", "sorted", "a", "b", "#isPointInBounds", "bounds"]
|
|
7
7
|
}
|