@ue-too/board 0.9.5 → 0.11.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.
Files changed (57) hide show
  1. package/README.md +66 -2
  2. package/boardify/index.d.ts +280 -9
  3. package/camera/base.d.ts +364 -68
  4. package/camera/camera-edge-auto-input.d.ts +105 -0
  5. package/camera/camera-mux/animation-and-lock/animation-and-lock.d.ts +316 -14
  6. package/camera/camera-mux/animation-and-lock/index.d.ts +27 -0
  7. package/camera/camera-mux/animation-and-lock/pan-control-state-machine.d.ts +143 -60
  8. package/camera/camera-mux/animation-and-lock/rotation-control-state-machine.d.ts +143 -55
  9. package/camera/camera-mux/animation-and-lock/zoom-control-state-machine.d.ts +205 -58
  10. package/camera/camera-mux/index.d.ts +26 -0
  11. package/camera/camera-mux/interface.d.ts +161 -5
  12. package/camera/camera-mux/relay.d.ts +79 -16
  13. package/camera/camera-rig/camera-rig.d.ts +536 -94
  14. package/camera/camera-rig/index.d.ts +26 -1
  15. package/camera/camera-rig/pan-handler.d.ts +508 -48
  16. package/camera/camera-rig/rotation-handler.d.ts +353 -31
  17. package/camera/camera-rig/zoom-handler.d.ts +369 -32
  18. package/camera/default-camera.d.ts +173 -26
  19. package/camera/index.d.ts +20 -0
  20. package/camera/interface.d.ts +202 -2
  21. package/camera/update-publisher.d.ts +128 -38
  22. package/camera/utils/coordinate-conversion.d.ts +323 -26
  23. package/camera/utils/index.d.ts +22 -0
  24. package/camera/utils/matrix.d.ts +217 -14
  25. package/camera/utils/position.d.ts +249 -11
  26. package/camera/utils/rotation.d.ts +139 -9
  27. package/camera/utils/zoom.d.ts +72 -4
  28. package/index.d.ts +37 -0
  29. package/index.js +2 -4796
  30. package/index.js.map +39 -38
  31. package/input-interpretation/index.d.ts +29 -0
  32. package/input-interpretation/input-orchestrator.d.ts +197 -0
  33. package/input-interpretation/input-state-machine/index.d.ts +18 -0
  34. package/input-interpretation/input-state-machine/kmt-input-context.d.ts +191 -38
  35. package/input-interpretation/input-state-machine/kmt-input-state-machine.d.ts +201 -85
  36. package/input-interpretation/input-state-machine/touch-input-context.d.ts +76 -10
  37. package/input-interpretation/input-state-machine/touch-input-state-machine.d.ts +138 -17
  38. package/input-interpretation/raw-input-parser/index.d.ts +19 -0
  39. package/input-interpretation/raw-input-parser/vanilla-kmt-event-parser.d.ts +107 -21
  40. package/input-interpretation/raw-input-parser/vanilla-touch-event-parser.d.ts +71 -8
  41. package/input-interpretation/raw-input-publisher/index.d.ts +18 -0
  42. package/input-interpretation/raw-input-publisher/raw-input-publisher.d.ts +133 -37
  43. package/package.json +3 -3
  44. package/utils/canvas-position-dimension.d.ts +282 -1
  45. package/utils/coordinate-conversions/canvas-viewport.d.ts +79 -0
  46. package/utils/coordinate-conversions/viewport-world.d.ts +101 -0
  47. package/utils/coordinate-conversions/window-canvas.d.ts +90 -0
  48. package/utils/coorindate-conversion.d.ts +91 -0
  49. package/utils/drawing.d.ts +151 -3
  50. package/utils/index.d.ts +21 -0
  51. package/utils/observable.d.ts +179 -0
  52. package/utils/ruler.d.ts +36 -0
  53. package/utils/zoomlevel-adjustment.d.ts +144 -8
  54. package/camera/camera-rig/update-batcher/index.d.ts +0 -3
  55. package/camera/camera-rig/update-batcher/position-update-batcher.d.ts +0 -58
  56. package/camera/camera-rig/update-batcher/rotation-update-batcher.d.ts +0 -54
  57. package/camera/camera-rig/update-batcher/zoom-udpate-batcher.d.ts +0 -60
@@ -1,68 +1,90 @@
1
1
  import type { Point } from "@ue-too/math";
2
- import { CameraMux } from "../../camera/camera-mux";
3
- import { ObservableBoardCamera } from "../../camera/interface";
4
2
  /**
5
- * @description The unsubscribe to user raw input.
3
+ * Function to unsubscribe from raw user input events.
6
4
  *
7
- * @category Event Parser
5
+ * @remarks
6
+ * Calling this function removes the subscriber from the event stream.
7
+ *
8
+ * @category Raw Input Publisher
8
9
  */
9
10
  export type UnsubscribeToUserRawInput = () => void;
10
11
  /**
11
- * @description The raw user pan input event payload.
12
+ * Payload for pan input events.
13
+ *
14
+ * @property diff - The pan delta in viewport pixels
12
15
  *
13
- * @category Event Parser
16
+ * @category Raw Input Publisher
14
17
  */
15
18
  export type RawUserPanInputEventPayload = {
16
19
  diff: Point;
17
20
  };
18
21
  /**
19
- * @description The raw user pan input event.
20
- * Use type to discriminate between pan, zoom, and rotate events.
22
+ * Pan input event with discriminated type.
21
23
  *
22
- * @category Event Parser
24
+ * @remarks
25
+ * The `type` property allows TypeScript discriminated unions to distinguish
26
+ * between different event types when subscribing to the "all" event stream.
27
+ *
28
+ * @category Raw Input Publisher
23
29
  */
24
30
  export type RawUserPanInputEvent = {
25
31
  type: "pan";
26
32
  } & RawUserPanInputEventPayload;
27
33
  /**
28
- * @description The raw user zoom input event payload.
34
+ * Payload for zoom input events.
35
+ *
36
+ * @property deltaZoomAmount - The zoom delta (scale change)
37
+ * @property anchorPoint - The zoom anchor point in viewport coordinates
29
38
  *
30
- * @category Event Parser
39
+ * @category Raw Input Publisher
31
40
  */
32
41
  export type RawUserZoomInputEventPayload = {
33
42
  deltaZoomAmount: number;
34
43
  anchorPoint: Point;
35
44
  };
36
45
  /**
37
- * @description The raw user zoom input event.
38
- * Use type to discriminate between pan, zoom, and rotate events.
46
+ * Zoom input event with discriminated type.
39
47
  *
40
- * @category Event Parser
48
+ * @remarks
49
+ * The `type` property allows TypeScript discriminated unions to distinguish
50
+ * between different event types when subscribing to the "all" event stream.
51
+ *
52
+ * @category Raw Input Publisher
41
53
  */
42
54
  export type RawUserZoomInputEvent = {
43
55
  type: "zoom";
44
56
  } & RawUserZoomInputEventPayload;
45
57
  /**
46
- * @description The raw user rotate input event payload.
58
+ * Payload for rotate input events.
59
+ *
60
+ * @property deltaRotation - The rotation delta in radians
47
61
  *
48
- * @category Event Parser
62
+ * @category Raw Input Publisher
49
63
  */
50
64
  export type RawUserRotateInputEventPayload = {
51
65
  deltaRotation: number;
52
66
  };
53
67
  /**
54
- * @description The raw user rotate input event.
55
- * Use type to discriminate between pan, zoom, and rotate events.
68
+ * Rotate input event with discriminated type.
69
+ *
70
+ * @remarks
71
+ * The `type` property allows TypeScript discriminated unions to distinguish
72
+ * between different event types when subscribing to the "all" event stream.
56
73
  *
57
- * @category Event Parser
74
+ * @category Raw Input Publisher
58
75
  */
59
76
  export type RawUserRotateInputEvent = {
60
77
  type: "rotate";
61
78
  } & RawUserRotateInputEventPayload;
62
79
  /**
63
- * @description The raw user input event map.
80
+ * Mapping of event names to their payload types.
64
81
  *
65
- * @category Event Parser
82
+ * @remarks
83
+ * This type enables type-safe event subscription:
84
+ * - Subscribe to specific events ("pan", "zoom", "rotate") to receive only those payloads
85
+ * - Subscribe to "all" to receive all events with discriminated type property
86
+ *
87
+ * @category Raw Input Publisher
66
88
  */
67
89
  export type RawUserInputEventMap = {
68
90
  "pan": RawUserPanInputEventPayload;
@@ -71,51 +93,125 @@ export type RawUserInputEventMap = {
71
93
  "all": RawUserInputEvent;
72
94
  };
73
95
  /**
74
- * @description The raw user input event.
75
- * Use type to discriminate between pan, zoom, and rotate events.
96
+ * Union type of all raw user input events.
97
+ *
98
+ * @remarks
99
+ * Use the `type` discriminator property to determine which event variant you have.
76
100
  *
77
- * @category Event Parser
101
+ * @category Raw Input Publisher
78
102
  */
79
103
  export type RawUserInputEvent = RawUserPanInputEvent | RawUserZoomInputEvent | RawUserRotateInputEvent;
80
104
  /**
81
- * @description The raw user input callback.
82
- * This is the function type of callbacks for raw user input events.
105
+ * Callback function type for raw user input events.
106
+ *
107
+ * @typeParam K - The event name key from RawUserInputEventMap
83
108
  *
84
- * @category Event Parser
109
+ * @category Raw Input Publisher
85
110
  */
86
111
  export type RawUserInputCallback<K extends keyof RawUserInputEventMap> = (event: RawUserInputEventMap[K]) => void;
112
+ /**
113
+ * Interface for publishing raw user input events to observers.
114
+ *
115
+ * @remarks
116
+ * This interface defines the contract for broadcasting user input events
117
+ * to external subscribers. Implementations provide the observable pattern
118
+ * for input event distribution.
119
+ *
120
+ * @category Raw Input Publisher
121
+ */
87
122
  export interface UserInputPublisher {
123
+ /** Notifies subscribers of a pan gesture */
88
124
  notifyPan(diff: Point): void;
125
+ /** Notifies subscribers of a zoom gesture */
89
126
  notifyZoom(deltaZoomAmount: number, anchorPoint: Point): void;
127
+ /** Notifies subscribers of a rotate gesture */
90
128
  notifyRotate(deltaRotation: number): void;
129
+ /** Subscribes to input events */
91
130
  on<K extends keyof RawUserInputEventMap>(eventName: K, callback: (event: RawUserInputEventMap[K]) => void): UnsubscribeToUserRawInput;
92
131
  }
93
132
  /**
94
- * @description The raw user input publisher.
95
- * Publishs raw user input events to the input flow control, and subscribers.
133
+ * Publisher for broadcasting raw user input events to observers.
134
+ *
135
+ * @remarks
136
+ * This class implements the observable pattern to distribute user input events
137
+ * to external subscribers. It operates in parallel to camera control - the
138
+ * orchestrator both sends events to this publisher AND controls the camera.
139
+ *
140
+ * **Architecture**:
141
+ * ```
142
+ * Orchestrator → Publisher → Observers (UI, analytics, etc.)
143
+ * ↓
144
+ * CameraMux → CameraRig
145
+ * ```
146
+ *
147
+ * **Event Streams**:
148
+ * - **Specific streams**: Subscribe to "pan", "zoom", or "rotate" for typed events
149
+ * - **Unified stream**: Subscribe to "all" for all events with type discriminator
150
+ *
151
+ * **Use Cases**:
152
+ * - Update UI elements based on user interactions
153
+ * - Log analytics about user gestures
154
+ * - Synchronize secondary views or previews
155
+ * - Implement custom gesture reactions independent of camera
156
+ *
157
+ * **Observable Implementation**:
158
+ * Uses AsyncObservable for asynchronous event delivery, preventing observers
159
+ * from blocking the input processing pipeline.
96
160
  *
97
- * @category Event Parser
161
+ * @category Raw Input Publisher
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * const publisher = new RawUserInputPublisher();
166
+ *
167
+ * // Subscribe to pan events
168
+ * const unsubscribe = publisher.on("pan", (event) => {
169
+ * console.log("User panned by:", event.diff);
170
+ * updateMinimap(event.diff);
171
+ * });
172
+ *
173
+ * // Subscribe to all events
174
+ * publisher.on("all", (event) => {
175
+ * switch (event.type) {
176
+ * case "pan":
177
+ * analytics.log("pan", event.diff);
178
+ * break;
179
+ * case "zoom":
180
+ * analytics.log("zoom", event.deltaZoomAmount, event.anchorPoint);
181
+ * break;
182
+ * case "rotate":
183
+ * analytics.log("rotate", event.deltaRotation);
184
+ * break;
185
+ * }
186
+ * });
187
+ *
188
+ * // Later, unsubscribe
189
+ * unsubscribe();
190
+ * ```
98
191
  */
99
192
  export declare class RawUserInputPublisher implements UserInputPublisher {
100
193
  private pan;
101
194
  private zoom;
102
195
  private rotate;
103
196
  private all;
104
- private _cameraMux;
105
- constructor(cameraMux: CameraMux);
197
+ constructor();
106
198
  notifyPan(diff: Point): void;
107
199
  notifyZoom(deltaZoomAmount: number, anchorPoint: Point): void;
108
200
  notifyRotate(deltaRotation: number): void;
109
201
  on<K extends keyof RawUserInputEventMap>(eventName: K, callback: (event: RawUserInputEventMap[K]) => void): UnsubscribeToUserRawInput;
110
- get cameraMux(): CameraMux;
111
- set cameraMux(cameraMux: CameraMux);
112
202
  }
113
203
  /**
114
- * @description Creates a default raw user input publisher.
204
+ * Creates a default raw user input publisher.
205
+ *
206
+ * @returns A new RawUserInputPublisher instance
207
+ *
208
+ * @remarks
209
+ * Factory function for creating a standard publisher. Useful for dependency injection
210
+ * and testing scenarios where you want to swap implementations.
115
211
  *
116
- * @category Event Parser
212
+ * @category Raw Input Publisher
117
213
  */
118
- export declare function createDefaultRawUserInputPublisher(camera: ObservableBoardCamera): RawUserInputPublisher;
214
+ export declare function createDefaultRawUserInputPublisher(): RawUserInputPublisher;
119
215
  export declare class RawUserInputPublisherWithWebWorkerRelay implements UserInputPublisher {
120
216
  private pan;
121
217
  private zoom;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ue-too/board",
3
3
  "type": "module",
4
- "version": "0.9.5",
4
+ "version": "0.11.0",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./index.d.ts",
@@ -14,8 +14,8 @@
14
14
  "types": "./index.d.ts",
15
15
  "module": "./index.js",
16
16
  "dependencies": {
17
- "@ue-too/being": "^0.9.5",
18
- "@ue-too/math": "^0.9.5"
17
+ "@ue-too/being": "^0.11.0",
18
+ "@ue-too/math": "^0.11.0"
19
19
  },
20
20
  "repository": {
21
21
  "type": "git",
@@ -1,5 +1,140 @@
1
1
  import { Observer, SubscriptionOptions } from "../utils/observable";
2
- export type CanvasUpdateObserver = (rect: DOMRect) => void;
2
+ /**
3
+ * Monitors and publishes position and dimension changes for SVG elements.
4
+ *
5
+ * @remarks
6
+ * This class tracks SVG element position and dimensions using multiple browser APIs
7
+ * to ensure comprehensive detection of all changes:
8
+ * - ResizeObserver: Detects size changes
9
+ * - IntersectionObserver: Detects visibility and position changes
10
+ * - MutationObserver: Detects attribute changes (width, height, style)
11
+ * - Window scroll/resize events: Detects changes from page layout
12
+ *
13
+ * The reported DOMRect excludes padding and borders to provide the actual
14
+ * content dimensions using {@link getTrueRect}.
15
+ *
16
+ * Position and dimension changes are published synchronously to all subscribers,
17
+ * ensuring immediate updates for coordinate transformations and rendering logic.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const svg = document.querySelector('svg');
22
+ * const publisher = new SvgPositionDimensionPublisher(svg);
23
+ *
24
+ * // Subscribe to position/dimension updates
25
+ * publisher.onPositionUpdate((rect) => {
26
+ * console.log(`SVG at (${rect.x}, ${rect.y}) with size ${rect.width}x${rect.height}`);
27
+ * });
28
+ *
29
+ * // Clean up when done
30
+ * publisher.dispose();
31
+ * ```
32
+ *
33
+ * @category Canvas Position
34
+ */
35
+ export declare class SvgPositionDimensionPublisher {
36
+ private lastRect?;
37
+ private resizeObserver;
38
+ private intersectionObserver;
39
+ private mutationObserver;
40
+ private scrollHandler?;
41
+ private resizeHandler?;
42
+ private _observers;
43
+ /**
44
+ * Creates a new SVG position/dimension publisher.
45
+ *
46
+ * @param canvas - Optional SVG element to immediately attach to
47
+ *
48
+ * @remarks
49
+ * If a canvas is provided, observers are immediately attached and monitoring begins.
50
+ * Otherwise, call {@link attach} later to begin monitoring.
51
+ */
52
+ constructor(canvas?: SVGSVGElement);
53
+ /**
54
+ * Cleans up all observers and event listeners.
55
+ *
56
+ * @remarks
57
+ * Disconnects all observers (ResizeObserver, IntersectionObserver, MutationObserver)
58
+ * and removes window event listeners (scroll, resize). Always call this method
59
+ * when the publisher is no longer needed to prevent memory leaks.
60
+ */
61
+ dispose(): void;
62
+ /**
63
+ * Attaches observers to an SVG element and begins monitoring.
64
+ *
65
+ * @param canvas - The SVG element to monitor
66
+ *
67
+ * @remarks
68
+ * Automatically calls {@link dispose} first to clean up any previous attachments.
69
+ * Sets up all observers and records the initial position/dimensions.
70
+ *
71
+ * The initial rect is calculated immediately and stored, but no notification
72
+ * is sent to observers for this initial state.
73
+ */
74
+ attach(canvas: SVGSVGElement): void;
75
+ private publishPositionUpdate;
76
+ /**
77
+ * Subscribes to position and dimension updates.
78
+ *
79
+ * @param observer - Callback function that receives the updated DOMRect
80
+ * @param options - Optional subscription options (e.g., AbortSignal for cleanup)
81
+ * @returns Unsubscribe function to remove this observer
82
+ *
83
+ * @remarks
84
+ * The observer is called synchronously whenever the SVG's position or dimensions change.
85
+ * The DOMRect parameter represents the actual content area (excluding padding and borders).
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * const unsubscribe = publisher.onPositionUpdate((rect) => {
90
+ * console.log(`Position: ${rect.x}, ${rect.y}`);
91
+ * console.log(`Size: ${rect.width}x${rect.height}`);
92
+ * });
93
+ *
94
+ * // Later, when done:
95
+ * unsubscribe();
96
+ * ```
97
+ */
98
+ onPositionUpdate(observer: Observer<[DOMRect]>, options?: SubscriptionOptions): () => void;
99
+ private attributeCallBack;
100
+ }
101
+ /**
102
+ * Monitors and publishes position and dimension changes for HTML Canvas elements.
103
+ *
104
+ * @remarks
105
+ * Similar to {@link SvgPositionDimensionPublisher} but specifically for HTMLCanvasElement.
106
+ * Automatically handles device pixel ratio adjustments to maintain crisp rendering
107
+ * at different screen densities.
108
+ *
109
+ * Key differences from SVG version:
110
+ * - Automatically adjusts canvas.width/height attributes based on devicePixelRatio
111
+ * - Synchronizes CSS dimensions (style.width/height) with canvas buffer size
112
+ * - Ensures canvas maintains proper resolution on high-DPI displays
113
+ *
114
+ * The class uses multiple browser APIs for comprehensive change detection:
115
+ * - ResizeObserver: Detects size changes
116
+ * - IntersectionObserver: Detects visibility and position changes
117
+ * - MutationObserver: Detects attribute changes and synchronizes dimensions
118
+ * - Window scroll/resize events: Detects changes from page layout
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * const canvas = document.querySelector('canvas');
123
+ * const publisher = new CanvasPositionDimensionPublisher(canvas);
124
+ *
125
+ * // Subscribe to updates
126
+ * publisher.onPositionUpdate((rect) => {
127
+ * // Canvas dimensions automatically adjusted for devicePixelRatio
128
+ * console.log(`Canvas at (${rect.x}, ${rect.y})`);
129
+ * console.log(`Display size: ${rect.width}x${rect.height}`);
130
+ * });
131
+ *
132
+ * publisher.dispose();
133
+ * ```
134
+ *
135
+ * @category Canvas Position
136
+ * @see {@link SvgPositionDimensionPublisher} for SVG elements
137
+ */
3
138
  export declare class CanvasPositionDimensionPublisher {
4
139
  private lastRect?;
5
140
  private resizeObserver;
@@ -8,13 +143,159 @@ export declare class CanvasPositionDimensionPublisher {
8
143
  private scrollHandler?;
9
144
  private resizeHandler?;
10
145
  private _observers;
146
+ /**
147
+ * Creates a new Canvas position/dimension publisher.
148
+ *
149
+ * @param canvas - Optional canvas element to immediately attach to
150
+ *
151
+ * @remarks
152
+ * If a canvas is provided, observers are immediately attached and monitoring begins.
153
+ * The canvas dimensions are automatically adjusted for devicePixelRatio.
154
+ */
11
155
  constructor(canvas?: HTMLCanvasElement);
156
+ /**
157
+ * Cleans up all observers and event listeners.
158
+ *
159
+ * @remarks
160
+ * Disconnects all observers and removes window event listeners.
161
+ * Always call this method when the publisher is no longer needed to prevent memory leaks.
162
+ */
12
163
  dispose(): void;
164
+ /**
165
+ * Attaches observers to a canvas element and begins monitoring.
166
+ *
167
+ * @param canvas - The canvas element to monitor
168
+ *
169
+ * @remarks
170
+ * Automatically calls {@link dispose} first to clean up any previous attachments.
171
+ * Sets up all observers, adjusts canvas dimensions for devicePixelRatio,
172
+ * and records the initial position/dimensions.
173
+ */
13
174
  attach(canvas: HTMLCanvasElement): void;
14
175
  private publishPositionUpdate;
176
+ /**
177
+ * Subscribes to position and dimension updates.
178
+ *
179
+ * @param observer - Callback function that receives the updated DOMRect
180
+ * @param options - Optional subscription options (e.g., AbortSignal for cleanup)
181
+ * @returns Unsubscribe function to remove this observer
182
+ *
183
+ * @remarks
184
+ * The observer is called synchronously whenever the canvas position or dimensions change.
185
+ * The DOMRect represents the actual content area (excluding padding and borders).
186
+ * Canvas buffer dimensions are automatically adjusted for devicePixelRatio.
187
+ */
15
188
  onPositionUpdate(observer: Observer<[DOMRect]>, options?: SubscriptionOptions): () => void;
189
+ /**
190
+ * Handles attribute mutations on the canvas element.
191
+ *
192
+ * @param mutationsList - List of mutations detected
193
+ * @param observer - The MutationObserver instance
194
+ *
195
+ * @remarks
196
+ * This callback synchronizes canvas buffer size with CSS dimensions:
197
+ * - When width/height attributes change: Updates CSS dimensions based on devicePixelRatio
198
+ * - When style changes: Updates buffer size to match CSS dimensions
199
+ *
200
+ * This ensures the canvas maintains proper resolution on all displays.
201
+ */
16
202
  private attributeCallBack;
17
203
  }
204
+ /**
205
+ * Calculates the actual content rectangle excluding padding and borders.
206
+ *
207
+ * @param rect - The element's bounding client rectangle
208
+ * @param computedStyle - The computed CSS styles for the element
209
+ * @returns DOMRect representing the content area only
210
+ *
211
+ * @remarks
212
+ * Browser's getBoundingClientRect() includes padding and borders, but for
213
+ * coordinate transformations we need the actual drawable content area.
214
+ *
215
+ * This function subtracts padding and border from all four sides to get
216
+ * the "true" content rectangle. This is essential for accurate coordinate
217
+ * conversions between window and canvas space.
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * const canvas = document.querySelector('canvas');
222
+ * const rect = canvas.getBoundingClientRect();
223
+ * const style = window.getComputedStyle(canvas);
224
+ * const contentRect = getTrueRect(rect, style);
225
+ *
226
+ * // contentRect.width is less than rect.width if padding/borders exist
227
+ * console.log(`Full size: ${rect.width}x${rect.height}`);
228
+ * console.log(`Content size: ${contentRect.width}x${contentRect.height}`);
229
+ * ```
230
+ *
231
+ * @category Canvas Position
232
+ */
18
233
  export declare function getTrueRect(rect: DOMRect, computedStyle: CSSStyleDeclaration): DOMRect;
234
+ /**
235
+ * Creates a proxy that automatically flips y-coordinates for canvas context methods.
236
+ *
237
+ * @param context - The canvas 2D rendering context to wrap
238
+ * @returns Proxied context that handles y-axis reversal automatically
239
+ *
240
+ * @remarks
241
+ * Standard HTML canvas uses a top-left origin with y-axis pointing down.
242
+ * This proxy inverts the y-axis to create a mathematical coordinate system
243
+ * with y-axis pointing up.
244
+ *
245
+ * The proxy intercepts drawing methods (fillRect, strokeRect, moveTo, lineTo, etc.)
246
+ * and automatically negates y-coordinates and height values. This allows you to
247
+ * work in mathematical coordinates while still rendering correctly.
248
+ *
249
+ * Special handling for complex methods:
250
+ * - drawImage with 9 args: Properly inverts source and destination rectangles
251
+ * - drawImage with 5 args: Adjusts for image height
252
+ * - All methods in {@link methodsToFlip}: Y-coordinates negated automatically
253
+ *
254
+ * @example
255
+ * ```typescript
256
+ * const canvas = document.querySelector('canvas');
257
+ * const ctx = canvas.getContext('2d');
258
+ * const flippedCtx = reverseYAxis(ctx);
259
+ *
260
+ * // Draw with mathematical coordinates (y-up)
261
+ * flippedCtx.fillRect(0, 0, 100, 100); // Square in first quadrant
262
+ * flippedCtx.moveTo(0, 0);
263
+ * flippedCtx.lineTo(50, 100); // Line going upward
264
+ * ```
265
+ *
266
+ * @category Canvas Position
267
+ * @see {@link methodsToFlip} for list of intercepted methods
268
+ * @see {@link invertYAxisForDrawImageWith9Args} for drawImage special handling
269
+ */
19
270
  export declare function reverseYAxis(context: CanvasRenderingContext2D): CanvasRenderingContext2D;
271
+ /**
272
+ * Inverts y-coordinates for the 9-argument variant of drawImage.
273
+ *
274
+ * @param args - The arguments array for drawImage
275
+ * @returns Modified arguments with inverted y-coordinates
276
+ *
277
+ * @remarks
278
+ * The 9-argument drawImage signature is:
279
+ * drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
280
+ *
281
+ * When inverting y-axis, we need to adjust:
282
+ * - sy (source y): Flip relative to image height
283
+ * - sHeight: Negate (height becomes negative in flipped space)
284
+ * - dy (destination y): Negate
285
+ * - dy offset: Subtract destination height
286
+ *
287
+ * This ensures images render correctly when the canvas y-axis is flipped.
288
+ *
289
+ * @example
290
+ * ```typescript
291
+ * // Original call (top-left origin):
292
+ * ctx.drawImage(img, 0, 0, 100, 100, 50, 50, 200, 200);
293
+ *
294
+ * // With flipped y-axis, this becomes:
295
+ * // sy = imageHeight - 0, sHeight = -100, dy = -50 - 200, dHeight = -200
296
+ * ```
297
+ *
298
+ * @category Canvas Position
299
+ * @see {@link reverseYAxis} for the main y-axis flipping proxy
300
+ */
20
301
  export declare function invertYAxisForDrawImageWith9Args(args: any[]): typeof args;
@@ -0,0 +1,79 @@
1
+ import { Point } from "@ue-too/math";
2
+ /**
3
+ * Converts a point from canvas space to viewport space.
4
+ *
5
+ * @param pointInCanvas - The point in canvas coordinates to convert
6
+ * @param viewportOriginInCanvasSpace - The viewport's origin position in canvas coordinates (default: {0, 0})
7
+ * @param viewportHasFlippedYAxis - Whether viewport uses inverted y-axis (default: false)
8
+ * @returns The point in viewport coordinates
9
+ *
10
+ * @remarks
11
+ * Canvas and viewport coordinate systems can differ in two ways:
12
+ * 1. Origin position: Viewport origin may not be at canvas top-left (0,0)
13
+ * 2. Y-axis direction: Viewport may use mathematical coordinates (y-up) vs canvas (y-down)
14
+ *
15
+ * The conversion process:
16
+ * 1. Translate: Subtract viewport origin from point (shifts coordinate system)
17
+ * 2. Flip Y (if needed): Negate y-coordinate for mathematical coordinate system
18
+ *
19
+ * Common use case: Converting mouse click positions (canvas space) to positions
20
+ * relative to a centered viewport that uses mathematical coordinates.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // Canvas with centered viewport using mathematical coordinates
25
+ * const canvasPoint = { x: 400, y: 300 }; // Click near center
26
+ * const viewportOrigin = { x: 400, y: 300 }; // Viewport centered in 800x600 canvas
27
+ *
28
+ * // Convert to viewport space with flipped y-axis
29
+ * const viewportPoint = convertFromCanvas2ViewPort(
30
+ * canvasPoint,
31
+ * viewportOrigin,
32
+ * true // viewport has y-up
33
+ * );
34
+ * // Result: { x: 0, y: 0 } (center of viewport)
35
+ * ```
36
+ *
37
+ * @category Coordinate Conversion
38
+ * @see {@link convertFromViewPort2Canvas} for inverse conversion
39
+ */
40
+ export declare function convertFromCanvas2ViewPort(pointInCanvas: Point, viewportOriginInCanvasSpace?: Point, viewportHasFlippedYAxis?: boolean): Point;
41
+ /**
42
+ * Converts a point from viewport space to canvas space.
43
+ *
44
+ * @param pointInViewPort - The point in viewport coordinates to convert
45
+ * @param viewportOriginInCanvasSpace - The viewport's origin position in canvas coordinates (default: {0, 0})
46
+ * @param viewportHasFlippedYAxis - Whether viewport uses inverted y-axis (default: false)
47
+ * @returns The point in canvas coordinates
48
+ *
49
+ * @remarks
50
+ * This is the inverse of {@link convertFromCanvas2ViewPort}. It transforms points
51
+ * from viewport-relative coordinates back to absolute canvas coordinates.
52
+ *
53
+ * The conversion process:
54
+ * 1. Flip Y (if needed): Negate y-coordinate to convert from mathematical to canvas system
55
+ * 2. Translate: Add viewport origin to convert from relative to absolute position
56
+ *
57
+ * This is essential for rendering viewport-space objects (like shapes drawn by user)
58
+ * onto the actual canvas element.
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * // Viewport space point (centered viewport with y-up)
63
+ * const viewportPoint = { x: 100, y: 50 }; // 100 right, 50 up from viewport center
64
+ * const viewportOrigin = { x: 400, y: 300 }; // Viewport centered in canvas
65
+ *
66
+ * // Convert to canvas coordinates
67
+ * const canvasPoint = convertFromViewPort2Canvas(
68
+ * viewportPoint,
69
+ * viewportOrigin,
70
+ * true // viewport has y-up
71
+ * );
72
+ * // Result: { x: 500, y: 250 }
73
+ * // (400 + 100 = 500 in x, 300 - 50 = 250 in y due to flip)
74
+ * ```
75
+ *
76
+ * @category Coordinate Conversion
77
+ * @see {@link convertFromCanvas2ViewPort} for inverse conversion
78
+ */
79
+ export declare function convertFromViewPort2Canvas(pointInViewPort: Point, viewportOriginInCanvasSpace?: Point, viewportHasFlippedYAxis?: boolean): Point;