@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.
- package/README.md +66 -2
- package/boardify/index.d.ts +280 -9
- package/camera/base.d.ts +364 -68
- package/camera/camera-edge-auto-input.d.ts +105 -0
- package/camera/camera-mux/animation-and-lock/animation-and-lock.d.ts +316 -14
- package/camera/camera-mux/animation-and-lock/index.d.ts +27 -0
- package/camera/camera-mux/animation-and-lock/pan-control-state-machine.d.ts +143 -60
- package/camera/camera-mux/animation-and-lock/rotation-control-state-machine.d.ts +143 -55
- package/camera/camera-mux/animation-and-lock/zoom-control-state-machine.d.ts +205 -58
- package/camera/camera-mux/index.d.ts +26 -0
- package/camera/camera-mux/interface.d.ts +161 -5
- package/camera/camera-mux/relay.d.ts +79 -16
- package/camera/camera-rig/camera-rig.d.ts +536 -94
- package/camera/camera-rig/index.d.ts +26 -1
- package/camera/camera-rig/pan-handler.d.ts +508 -48
- package/camera/camera-rig/rotation-handler.d.ts +353 -31
- package/camera/camera-rig/zoom-handler.d.ts +369 -32
- package/camera/default-camera.d.ts +173 -26
- package/camera/index.d.ts +20 -0
- package/camera/interface.d.ts +202 -2
- package/camera/update-publisher.d.ts +128 -38
- package/camera/utils/coordinate-conversion.d.ts +323 -26
- package/camera/utils/index.d.ts +22 -0
- package/camera/utils/matrix.d.ts +217 -14
- package/camera/utils/position.d.ts +249 -11
- package/camera/utils/rotation.d.ts +139 -9
- package/camera/utils/zoom.d.ts +72 -4
- package/index.d.ts +37 -0
- package/index.js +2 -4796
- package/index.js.map +39 -38
- package/input-interpretation/index.d.ts +29 -0
- package/input-interpretation/input-orchestrator.d.ts +197 -0
- package/input-interpretation/input-state-machine/index.d.ts +18 -0
- package/input-interpretation/input-state-machine/kmt-input-context.d.ts +191 -38
- package/input-interpretation/input-state-machine/kmt-input-state-machine.d.ts +201 -85
- package/input-interpretation/input-state-machine/touch-input-context.d.ts +76 -10
- package/input-interpretation/input-state-machine/touch-input-state-machine.d.ts +138 -17
- package/input-interpretation/raw-input-parser/index.d.ts +19 -0
- package/input-interpretation/raw-input-parser/vanilla-kmt-event-parser.d.ts +107 -21
- package/input-interpretation/raw-input-parser/vanilla-touch-event-parser.d.ts +71 -8
- package/input-interpretation/raw-input-publisher/index.d.ts +18 -0
- package/input-interpretation/raw-input-publisher/raw-input-publisher.d.ts +133 -37
- package/package.json +3 -3
- package/utils/canvas-position-dimension.d.ts +282 -1
- package/utils/coordinate-conversions/canvas-viewport.d.ts +79 -0
- package/utils/coordinate-conversions/viewport-world.d.ts +101 -0
- package/utils/coordinate-conversions/window-canvas.d.ts +90 -0
- package/utils/coorindate-conversion.d.ts +91 -0
- package/utils/drawing.d.ts +151 -3
- package/utils/index.d.ts +21 -0
- package/utils/observable.d.ts +179 -0
- package/utils/ruler.d.ts +36 -0
- package/utils/zoomlevel-adjustment.d.ts +144 -8
- package/camera/camera-rig/update-batcher/index.d.ts +0 -3
- package/camera/camera-rig/update-batcher/position-update-batcher.d.ts +0 -58
- package/camera/camera-rig/update-batcher/rotation-update-batcher.d.ts +0 -54
- package/camera/camera-rig/update-batcher/zoom-udpate-batcher.d.ts +0 -60
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input interpretation system module exports.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* This module handles all user input processing for the board package, converting raw DOM events
|
|
6
|
+
* into camera operations through a pipeline of parsers, state machines, and orchestration.
|
|
7
|
+
*
|
|
8
|
+
* ## Architecture
|
|
9
|
+
*
|
|
10
|
+
* The input system follows this flow:
|
|
11
|
+
* 1. **Raw Input Parsers**: Listen to DOM events (mouse, keyboard, touch)
|
|
12
|
+
* 2. **Input State Machines**: Interpret event sequences (e.g., drag vs click, pinch vs pan)
|
|
13
|
+
* 3. **Input Orchestrator**: Translates gestures into camera operations
|
|
14
|
+
* 4. **Raw Input Publisher**: Publishes input events for application-level handling
|
|
15
|
+
*
|
|
16
|
+
* ## Key Components
|
|
17
|
+
*
|
|
18
|
+
* - **Parsers**: {@link VanillaKMTEventParser}, {@link VanillaTouchEventParser} for DOM event handling
|
|
19
|
+
* - **State Machines**: {@link createKmtInputStateMachine}, {@link createTouchInputStateMachine} for gesture recognition
|
|
20
|
+
* - **Orchestrator**: {@link InputOrchestrator} for coordinating camera operations
|
|
21
|
+
* - **Publisher**: {@link RawUserInputPublisher} for input event subscriptions
|
|
22
|
+
*
|
|
23
|
+
* @see {@link InputOrchestrator} for camera control coordination
|
|
24
|
+
* @see {@link VanillaKMTEventParser} for keyboard/mouse/trackpad input
|
|
25
|
+
* @see {@link VanillaTouchEventParser} for touch input
|
|
26
|
+
*
|
|
27
|
+
* @module
|
|
28
|
+
*/
|
|
1
29
|
export * from "./input-state-machine";
|
|
2
30
|
export * from "./raw-input-publisher";
|
|
3
31
|
export * from "./raw-input-parser";
|
|
32
|
+
export * from "./input-orchestrator";
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { KmtOutputEvent } from "./input-state-machine/kmt-input-state-machine";
|
|
2
|
+
import { TouchOutputEvent } from "./input-state-machine/touch-input-state-machine";
|
|
3
|
+
import { UserInputPublisher } from "./raw-input-publisher/raw-input-publisher";
|
|
4
|
+
import { CameraMux } from "../camera/camera-mux";
|
|
5
|
+
import { CameraRig } from "../camera/camera-rig";
|
|
6
|
+
/**
|
|
7
|
+
* Union type of all output events from state machines.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* This type represents the unified output from both KMT (Keyboard/Mouse/Trackpad) and Touch state machines.
|
|
11
|
+
* By unifying these outputs, the orchestrator can handle events from different input modalities uniformly.
|
|
12
|
+
*
|
|
13
|
+
* @category Input Interpretation
|
|
14
|
+
*/
|
|
15
|
+
export type OutputEvent = KmtOutputEvent | TouchOutputEvent;
|
|
16
|
+
/**
|
|
17
|
+
* Central orchestrator that coordinates input interpretation and camera control for the infinite canvas.
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* The InputOrchestrator serves as the mediator between input state machines and camera control systems.
|
|
21
|
+
* It implements a permission-based architecture where:
|
|
22
|
+
*
|
|
23
|
+
* 1. **Event Flow**: State machines produce high-level gesture events (pan, zoom, rotate)
|
|
24
|
+
* 2. **Permission Check**: Events are sent to CameraMux for permission validation
|
|
25
|
+
* 3. **Execution**: If allowed, gestures are executed on CameraRig
|
|
26
|
+
* 4. **Broadcasting**: Raw events are simultaneously broadcast to observers via UserInputPublisher
|
|
27
|
+
*
|
|
28
|
+
* **Architecture Pattern**:
|
|
29
|
+
* ```
|
|
30
|
+
* State Machines → Orchestrator → CameraMux (permission) → CameraRig (execution)
|
|
31
|
+
* ↓
|
|
32
|
+
* UserInputPublisher (observers)
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* This design decouples state machines from camera control, allowing state machines to focus solely
|
|
36
|
+
* on gesture recognition while the orchestrator handles the complexities of camera coordination,
|
|
37
|
+
* permission management, and event distribution.
|
|
38
|
+
*
|
|
39
|
+
* **Key Benefits**:
|
|
40
|
+
* - Single point of control for all camera operations
|
|
41
|
+
* - State machines remain unaware of camera implementation
|
|
42
|
+
* - Parallel path for observers to react to raw input events
|
|
43
|
+
* - Consistent handling of KMT and Touch input modalities
|
|
44
|
+
*
|
|
45
|
+
* @category Input Interpretation
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* // Create the orchestrator
|
|
50
|
+
* const cameraMux = new CameraMux();
|
|
51
|
+
* const cameraRig = new CameraRig(camera, viewport);
|
|
52
|
+
* const publisher = new RawUserInputPublisher();
|
|
53
|
+
* const orchestrator = new InputOrchestrator(cameraMux, cameraRig, publisher);
|
|
54
|
+
*
|
|
55
|
+
* // State machines send their output to the orchestrator
|
|
56
|
+
* const kmtStateMachine = createKmtInputStateMachine(kmtContext);
|
|
57
|
+
* const result = kmtStateMachine.happens("leftPointerMove", {x: 100, y: 200});
|
|
58
|
+
* orchestrator.processInputEventOutput(result.output);
|
|
59
|
+
*
|
|
60
|
+
* // Observers can subscribe to raw input events
|
|
61
|
+
* publisher.on("pan", (event) => {
|
|
62
|
+
* console.log("Pan gesture detected:", event.diff);
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare class InputOrchestrator {
|
|
67
|
+
private _cameraMux;
|
|
68
|
+
private _cameraRig;
|
|
69
|
+
private _publisher?;
|
|
70
|
+
/**
|
|
71
|
+
* Creates a new InputOrchestrator instance.
|
|
72
|
+
*
|
|
73
|
+
* @param cameraMux - The camera multiplexer that validates and controls camera operation permissions
|
|
74
|
+
* @param cameraRig - The camera rig that executes camera transformations
|
|
75
|
+
* @param publisher - Optional publisher for broadcasting raw input events to observers
|
|
76
|
+
*
|
|
77
|
+
* @remarks
|
|
78
|
+
* The publisher parameter is optional to support scenarios where event broadcasting is not needed.
|
|
79
|
+
* When provided, all input events are broadcast in parallel to camera control execution.
|
|
80
|
+
*/
|
|
81
|
+
constructor(cameraMux: CameraMux, cameraRig: CameraRig, publisher?: UserInputPublisher);
|
|
82
|
+
/**
|
|
83
|
+
* Processes output events from state machines and routes them to camera control and observers.
|
|
84
|
+
*
|
|
85
|
+
* @param output - The output from a state machine, can be a single event, array of events, or any value
|
|
86
|
+
*
|
|
87
|
+
* @remarks
|
|
88
|
+
* This method serves as the main entry point for state machine outputs. It:
|
|
89
|
+
* 1. Validates whether the output is a valid OutputEvent
|
|
90
|
+
* 2. Handles both single events and arrays of events
|
|
91
|
+
* 3. Routes each valid event through the camera control pipeline
|
|
92
|
+
* 4. Broadcasts events to observers via the publisher
|
|
93
|
+
*
|
|
94
|
+
* Called by event parsers after the state machine processes an input and produces output.
|
|
95
|
+
* The method uses type guards to ensure type safety when handling dynamic output types.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const result = stateMachine.happens("scroll", {deltaX: 0, deltaY: 10, x: 100, y: 200});
|
|
100
|
+
* orchestrator.processInputEventOutput(result.output);
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
processInputEventOutput(output: any): void;
|
|
104
|
+
/**
|
|
105
|
+
* Type guard to check if an output value is a valid OutputEvent.
|
|
106
|
+
*
|
|
107
|
+
* @param output - The value to check
|
|
108
|
+
* @returns True if the output is a valid OutputEvent with a type property
|
|
109
|
+
*
|
|
110
|
+
* @remarks
|
|
111
|
+
* This type guard ensures type safety when processing state machine outputs.
|
|
112
|
+
* It checks for the presence of a 'type' property which is common to all OutputEvent variants.
|
|
113
|
+
*/
|
|
114
|
+
private isOutputEvent;
|
|
115
|
+
/**
|
|
116
|
+
* Handles individual output events from state machines by routing to camera control and observers.
|
|
117
|
+
*
|
|
118
|
+
* @param event - The output event from a state machine (pan, zoom, rotate, cursor, or none)
|
|
119
|
+
*
|
|
120
|
+
* @remarks
|
|
121
|
+
* This method implements a dual-path architecture:
|
|
122
|
+
*
|
|
123
|
+
* **Parallel Path 1 - Observer Notification**:
|
|
124
|
+
* - Immediately broadcasts the event to all subscribers via UserInputPublisher
|
|
125
|
+
* - This allows external systems to react to user input in real-time
|
|
126
|
+
* - Independent of camera permission/execution
|
|
127
|
+
*
|
|
128
|
+
* **Parallel Path 2 - Camera Control**:
|
|
129
|
+
* - Requests permission from CameraMux for the operation
|
|
130
|
+
* - CameraMux may modify the event (e.g., clamp values, deny operation)
|
|
131
|
+
* - If permitted, executes the transformation on CameraRig
|
|
132
|
+
*
|
|
133
|
+
* Event types:
|
|
134
|
+
* - **pan**: Translates the camera viewport
|
|
135
|
+
* - **zoom**: Scales the camera around an anchor point
|
|
136
|
+
* - **rotate**: Rotates the camera view
|
|
137
|
+
* - **cursor**: Changes cursor appearance (handled by state machine)
|
|
138
|
+
* - **none**: No operation needed
|
|
139
|
+
*/
|
|
140
|
+
private handleStateMachineOutput;
|
|
141
|
+
/**
|
|
142
|
+
* Processes pan output from CameraMux and executes the pan operation if permitted.
|
|
143
|
+
*
|
|
144
|
+
* @param output - The pan output from CameraMux containing permission and potentially modified delta
|
|
145
|
+
*
|
|
146
|
+
* @remarks
|
|
147
|
+
* CameraMux may deny the operation (allowPassThrough = false) or modify the delta value
|
|
148
|
+
* to enforce constraints like viewport bounds or animation states.
|
|
149
|
+
* Only when permission is granted does the pan execute on CameraRig.
|
|
150
|
+
*/
|
|
151
|
+
private processPanMuxOutput;
|
|
152
|
+
/**
|
|
153
|
+
* Processes zoom output from CameraMux and executes the zoom operation if permitted.
|
|
154
|
+
*
|
|
155
|
+
* @param output - The zoom output from CameraMux containing permission and potentially modified parameters
|
|
156
|
+
*
|
|
157
|
+
* @remarks
|
|
158
|
+
* CameraMux may deny the operation or modify zoom parameters to enforce constraints
|
|
159
|
+
* like minimum/maximum zoom levels or animation states. The anchor point determines
|
|
160
|
+
* the center of the zoom transformation in viewport coordinates.
|
|
161
|
+
*/
|
|
162
|
+
private processZoomMuxOutput;
|
|
163
|
+
/**
|
|
164
|
+
* Processes rotation output from CameraMux and executes the rotation operation if permitted.
|
|
165
|
+
*
|
|
166
|
+
* @param output - The rotation output from CameraMux containing permission and potentially modified delta
|
|
167
|
+
*
|
|
168
|
+
* @remarks
|
|
169
|
+
* CameraMux may deny the operation or modify the rotation delta to enforce constraints
|
|
170
|
+
* like rotation limits or animation states.
|
|
171
|
+
*/
|
|
172
|
+
private processRotateMuxOutput;
|
|
173
|
+
/**
|
|
174
|
+
* Gets the UserInputPublisher for direct access to event subscription.
|
|
175
|
+
*
|
|
176
|
+
* @returns The publisher instance, or undefined if not configured
|
|
177
|
+
*
|
|
178
|
+
* @remarks
|
|
179
|
+
* Allows external code to subscribe to raw input events without going through the orchestrator.
|
|
180
|
+
*/
|
|
181
|
+
get publisher(): UserInputPublisher | undefined;
|
|
182
|
+
/**
|
|
183
|
+
* Gets the CameraMux instance for direct access to permission control.
|
|
184
|
+
*
|
|
185
|
+
* @returns The camera multiplexer instance
|
|
186
|
+
*/
|
|
187
|
+
get cameraMux(): CameraMux;
|
|
188
|
+
/**
|
|
189
|
+
* Sets a new CameraMux instance.
|
|
190
|
+
*
|
|
191
|
+
* @param cameraMux - The new camera multiplexer to use for permission control
|
|
192
|
+
*
|
|
193
|
+
* @remarks
|
|
194
|
+
* Allows dynamic reconfiguration of camera permission logic at runtime.
|
|
195
|
+
*/
|
|
196
|
+
set cameraMux(cameraMux: CameraMux);
|
|
197
|
+
}
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input state machine module exports.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* This module provides state machines for interpreting raw input events into high-level gestures.
|
|
6
|
+
* Separate state machines handle keyboard/mouse/trackpad (KMT) and touch input.
|
|
7
|
+
*
|
|
8
|
+
* ## Components
|
|
9
|
+
*
|
|
10
|
+
* - **KMT State Machine**: {@link createKmtInputStateMachine} for keyboard/mouse/trackpad gestures
|
|
11
|
+
* - **Touch State Machine**: {@link createTouchInputStateMachine} for touch gestures (pan, pinch, rotate)
|
|
12
|
+
* - **Input Contexts**: {@link ObservableInputTracker}, {@link TouchInputTracker} for tracking input state
|
|
13
|
+
*
|
|
14
|
+
* @see {@link createKmtInputStateMachine} for KMT gesture recognition
|
|
15
|
+
* @see {@link createTouchInputStateMachine} for touch gesture recognition
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
1
19
|
export * from "./kmt-input-context";
|
|
2
20
|
export * from "./touch-input-context";
|
|
3
21
|
export * from "./touch-input-state-machine";
|
|
@@ -1,36 +1,86 @@
|
|
|
1
1
|
import { Point } from "@ue-too/math";
|
|
2
2
|
import { BaseContext } from "@ue-too/being";
|
|
3
|
-
import { UserInputPublisher } from "../raw-input-publisher";
|
|
4
3
|
import { CanvasPositionDimensionPublisher, Observable, Observer, SubscriptionOptions } from "../../utils";
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Cursor styles used to provide visual feedback for different input states.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* These cursor styles indicate the current interaction mode to users:
|
|
9
|
+
* - **GRAB**: Indicates the canvas is ready to be panned (spacebar pressed, no drag yet)
|
|
10
|
+
* - **GRABBING**: Indicates active panning is in progress
|
|
11
|
+
* - **DEFAULT**: Normal cursor state when no special interaction is active
|
|
12
|
+
*
|
|
13
|
+
* @category Input State Machine
|
|
14
|
+
*/
|
|
6
15
|
export declare enum CursorStyle {
|
|
7
16
|
GRAB = "grab",
|
|
8
17
|
DEFAULT = "default",
|
|
9
18
|
GRABBING = "grabbing"
|
|
10
19
|
}
|
|
11
20
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
21
|
+
* Canvas dimension and position information.
|
|
22
|
+
*
|
|
23
|
+
* @property width - The canvas width in CSS pixels
|
|
24
|
+
* @property height - The canvas height in CSS pixels
|
|
25
|
+
* @property position - The top-left position of the canvas in window coordinates
|
|
26
|
+
*
|
|
27
|
+
* @category Input State Machine
|
|
28
|
+
*/
|
|
29
|
+
export type CanvasDimensions = {
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
position: Point;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Abstraction interface for canvas element access and manipulation.
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
* This interface provides a decoupled way to access canvas properties without direct DOM access.
|
|
39
|
+
* Multiple implementations exist to support different use cases:
|
|
40
|
+
* - **CanvasProxy**: Full implementation for HTML canvas elements with dimension tracking
|
|
41
|
+
* - **SvgProxy**: Implementation for SVG elements
|
|
42
|
+
* - **DummyCanvas**: No-op implementation for web worker contexts
|
|
43
|
+
* - **WorkerRelayCanvas**: Relays canvas dimension updates to web workers
|
|
44
|
+
* - **CanvasCacheInWebWorker**: Caches canvas dimensions within a web worker
|
|
45
|
+
*
|
|
46
|
+
* The abstraction enables:
|
|
47
|
+
* - Coordinate system transformations (window → canvas → viewport)
|
|
48
|
+
* - Canvas dimension tracking without repeated DOM queries
|
|
49
|
+
* - Cursor style management
|
|
50
|
+
* - Support for both canvas and SVG rendering contexts
|
|
51
|
+
*
|
|
52
|
+
* @category Input State Machine
|
|
14
53
|
*/
|
|
15
54
|
export interface Canvas {
|
|
55
|
+
/** The canvas width in CSS pixels */
|
|
16
56
|
width: number;
|
|
57
|
+
/** The canvas height in CSS pixels */
|
|
17
58
|
height: number;
|
|
59
|
+
/** The top-left position of the canvas in window coordinates */
|
|
18
60
|
position: Point;
|
|
61
|
+
/** Sets the CSS cursor style for visual feedback */
|
|
19
62
|
setCursor: (style: CursorStyle) => void;
|
|
63
|
+
/** Combined dimensions and position information */
|
|
20
64
|
dimensions: CanvasDimensions;
|
|
65
|
+
/** Whether the canvas is currently detached from the DOM */
|
|
21
66
|
detached: boolean;
|
|
67
|
+
/** Cleanup method to dispose of resources and event listeners */
|
|
22
68
|
tearDown: () => void;
|
|
23
69
|
}
|
|
24
|
-
export type CanvasDimensions = {
|
|
25
|
-
width: number;
|
|
26
|
-
height: number;
|
|
27
|
-
position: Point;
|
|
28
|
-
};
|
|
29
70
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
71
|
+
* No-op implementation of Canvas interface for web worker relay contexts.
|
|
72
|
+
*
|
|
73
|
+
* @remarks
|
|
74
|
+
* This class is used when an input state machine is configured to relay events to a web worker
|
|
75
|
+
* rather than perform actual canvas operations. The state machine requires a Canvas in its context,
|
|
76
|
+
* but in the relay scenario, no actual canvas operations are needed - events are simply forwarded
|
|
77
|
+
* to the worker thread.
|
|
78
|
+
*
|
|
79
|
+
* All properties return default/empty values and all methods are no-ops.
|
|
80
|
+
*
|
|
81
|
+
* @category Input State Machine
|
|
82
|
+
*
|
|
83
|
+
* @see {@link DummyKmtInputContext}
|
|
34
84
|
*/
|
|
35
85
|
export declare class DummyCanvas implements Canvas {
|
|
36
86
|
width: number;
|
|
@@ -100,6 +150,40 @@ export declare class CanvasProxy implements Canvas, Observable<[CanvasDimensions
|
|
|
100
150
|
attach(canvas: HTMLCanvasElement): void;
|
|
101
151
|
logCanvasTrueSize(): void;
|
|
102
152
|
}
|
|
153
|
+
export declare class SvgProxy implements Canvas, Observable<[CanvasDimensions]> {
|
|
154
|
+
private _width;
|
|
155
|
+
private _height;
|
|
156
|
+
private _position;
|
|
157
|
+
private _svgPositionDimensionPublisher;
|
|
158
|
+
private _svg;
|
|
159
|
+
private _internalSizeUpdateObservable;
|
|
160
|
+
constructor(svg?: SVGSVGElement);
|
|
161
|
+
subscribe(observer: Observer<[CanvasDimensions]>, options?: SubscriptionOptions): () => void;
|
|
162
|
+
notify(...data: [CanvasDimensions]): void;
|
|
163
|
+
get detached(): boolean;
|
|
164
|
+
get dimensions(): {
|
|
165
|
+
width: number;
|
|
166
|
+
height: number;
|
|
167
|
+
position: Point;
|
|
168
|
+
};
|
|
169
|
+
get width(): number;
|
|
170
|
+
/**
|
|
171
|
+
* set the width of the canvas
|
|
172
|
+
* the width is synonymous with the canvas style width not the canvas width
|
|
173
|
+
*/
|
|
174
|
+
setWidth(width: number): void;
|
|
175
|
+
/**
|
|
176
|
+
* set the height of the canvas
|
|
177
|
+
* the height is synonymous with the canvas style height not the canvas height
|
|
178
|
+
*/
|
|
179
|
+
setHeight(height: number): void;
|
|
180
|
+
get height(): number;
|
|
181
|
+
get position(): Point;
|
|
182
|
+
setCursor(style: "grab" | "default" | "grabbing"): void;
|
|
183
|
+
tearDown(): void;
|
|
184
|
+
attach(svg: SVGSVGElement): void;
|
|
185
|
+
logCanvasTrueSize(): void;
|
|
186
|
+
}
|
|
103
187
|
/**
|
|
104
188
|
* @description A proxy for the canvas that is used to communicate with the web worker.
|
|
105
189
|
* The primary purpose of this class is to cache the canvas dimensions and position in the DOM to reduce the calling of the getBoundingClientRect method.
|
|
@@ -127,27 +211,66 @@ export declare class WorkerRelayCanvas implements Canvas {
|
|
|
127
211
|
setCursor(style: "grab" | "default" | "grabbing"): void;
|
|
128
212
|
}
|
|
129
213
|
/**
|
|
130
|
-
*
|
|
214
|
+
* Context interface for the Keyboard/Mouse/Trackpad (KMT) input state machine.
|
|
215
|
+
*
|
|
216
|
+
* @remarks
|
|
217
|
+
* This context provides the state and behavior needed by the KMT state machine to:
|
|
218
|
+
* 1. Track cursor positions for calculating pan deltas
|
|
219
|
+
* 2. Distinguish between mouse and trackpad input modalities
|
|
220
|
+
* 3. Access canvas dimensions for coordinate transformations
|
|
221
|
+
* 4. Manage coordinate system alignment (inverted Y-axis handling)
|
|
222
|
+
*
|
|
223
|
+
* **Input Modality Detection**:
|
|
224
|
+
* The context uses a scoring system (`kmtTrackpadTrackScore`) to differentiate between
|
|
225
|
+
* mouse and trackpad input, which have different zoom behaviors:
|
|
226
|
+
* - Mouse: Ctrl+Scroll = zoom, Scroll = pan
|
|
227
|
+
* - Trackpad: Scroll = zoom (no Ctrl needed), Two-finger gesture = pan
|
|
228
|
+
*
|
|
229
|
+
* **Coordinate System**:
|
|
230
|
+
* The `alignCoordinateSystem` flag determines Y-axis orientation:
|
|
231
|
+
* - `true`: Standard screen coordinates (Y increases downward)
|
|
232
|
+
* - `false`: Inverted coordinates (Y increases upward)
|
|
233
|
+
*
|
|
234
|
+
* This interface extends BaseContext from the @ue-too/being state machine library,
|
|
235
|
+
* inheriting setup() and cleanup() lifecycle methods.
|
|
131
236
|
*
|
|
132
237
|
* @category Input State Machine
|
|
133
238
|
*/
|
|
134
239
|
export interface KmtInputContext extends BaseContext {
|
|
240
|
+
/** Whether to use standard screen coordinate system (vs inverted Y-axis) */
|
|
135
241
|
alignCoordinateSystem: boolean;
|
|
242
|
+
/** Canvas accessor for dimensions and cursor control */
|
|
136
243
|
canvas: Canvas;
|
|
137
|
-
|
|
138
|
-
notifyOnZoom: (zoomAmount: number, anchorPoint: Point) => void;
|
|
139
|
-
notifyOnRotate: (deltaRotation: number) => void;
|
|
244
|
+
/** Sets the initial cursor position when starting a pan gesture */
|
|
140
245
|
setInitialCursorPosition: (position: Point) => void;
|
|
246
|
+
/** Cancels the current action and resets cursor position */
|
|
141
247
|
cancelCurrentAction: () => void;
|
|
248
|
+
/** The cursor position when a pan gesture started */
|
|
142
249
|
initialCursorPosition: Point;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
250
|
+
/** Score tracking input modality: >0 for mouse, <0 for trackpad, 0 for undetermined */
|
|
251
|
+
kmtTrackpadTrackScore: number;
|
|
252
|
+
/** Decreases the score toward trackpad */
|
|
253
|
+
subtractKmtTrackpadTrackScore: () => void;
|
|
254
|
+
/** Increases the score toward mouse */
|
|
255
|
+
addKmtTrackpadTrackScore: () => void;
|
|
256
|
+
/** Sets the determined input modality */
|
|
257
|
+
setMode: (mode: 'kmt' | 'trackpad' | 'TBD') => void;
|
|
258
|
+
/** The current input modality: 'kmt' (mouse), 'trackpad', or 'TBD' (to be determined) */
|
|
259
|
+
mode: 'kmt' | 'trackpad' | 'TBD';
|
|
146
260
|
}
|
|
147
261
|
/**
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
262
|
+
* No-op implementation of KmtInputContext for web worker relay scenarios.
|
|
263
|
+
*
|
|
264
|
+
* @remarks
|
|
265
|
+
* Used when the input state machine is configured to relay events to a web worker
|
|
266
|
+
* rather than process them locally. The state machine requires a context, but in
|
|
267
|
+
* the relay scenario, no actual state tracking is needed - events are simply forwarded.
|
|
268
|
+
*
|
|
269
|
+
* All methods are no-ops and all properties return default values.
|
|
270
|
+
*
|
|
271
|
+
* @category Input State Machine
|
|
272
|
+
*
|
|
273
|
+
* @see {@link DummyCanvas}
|
|
151
274
|
*/
|
|
152
275
|
export declare class DummyKmtInputContext implements KmtInputContext {
|
|
153
276
|
alignCoordinateSystem: boolean;
|
|
@@ -157,40 +280,70 @@ export declare class DummyKmtInputContext implements KmtInputContext {
|
|
|
157
280
|
toggleOnEdgeAutoCameraInput: () => void;
|
|
158
281
|
toggleOffEdgeAutoCameraInput: () => void;
|
|
159
282
|
setCursorPosition: (position: Point) => void;
|
|
160
|
-
notifyOnPan(delta: Point): void;
|
|
161
|
-
notifyOnZoom(zoomAmount: number, anchorPoint: Point): void;
|
|
162
|
-
notifyOnRotate(deltaRotation: number): void;
|
|
163
283
|
setInitialCursorPosition(position: Point): void;
|
|
164
284
|
cleanup(): void;
|
|
165
285
|
setup(): void;
|
|
286
|
+
get kmtTrackpadTrackScore(): number;
|
|
287
|
+
subtractKmtTrackpadTrackScore(): void;
|
|
288
|
+
addKmtTrackpadTrackScore(): void;
|
|
289
|
+
setMode(mode: 'kmt' | 'trackpad' | 'TBD'): void;
|
|
290
|
+
get mode(): 'kmt' | 'trackpad' | 'TBD';
|
|
166
291
|
cancelCurrentAction(): void;
|
|
167
292
|
}
|
|
168
293
|
/**
|
|
169
|
-
*
|
|
170
|
-
*
|
|
294
|
+
* Production implementation of KmtInputContext that tracks input state for the state machine.
|
|
295
|
+
*
|
|
296
|
+
* @remarks
|
|
297
|
+
* This class provides the concrete implementation of the KMT input context, maintaining
|
|
298
|
+
* all state required by the state machine to recognize and track gestures:
|
|
299
|
+
*
|
|
300
|
+
* **State Tracking**:
|
|
301
|
+
* - Initial cursor position for calculating pan deltas
|
|
302
|
+
* - Input modality score to distinguish mouse vs trackpad
|
|
303
|
+
* - Determined input mode (kmt/trackpad/TBD)
|
|
304
|
+
* - Coordinate system alignment preference
|
|
305
|
+
*
|
|
306
|
+
* **Input Modality Detection**:
|
|
307
|
+
* The `kmtTrackpadTrackScore` accumulates evidence about the input device:
|
|
308
|
+
* - Positive values indicate mouse behavior (middle-click, no horizontal scroll)
|
|
309
|
+
* - Negative values indicate trackpad behavior (horizontal scroll, two-finger gestures)
|
|
310
|
+
* - Score is used to determine zoom behavior (Ctrl+Scroll for mouse vs Scroll for trackpad)
|
|
311
|
+
*
|
|
312
|
+
* **Design Pattern**:
|
|
313
|
+
* This class follows the Context pattern from the @ue-too/being state machine library,
|
|
314
|
+
* providing stateful data and operations that states can access and modify during transitions.
|
|
171
315
|
*
|
|
172
316
|
* @category Input State Machine
|
|
317
|
+
*
|
|
318
|
+
* @example
|
|
319
|
+
* ```typescript
|
|
320
|
+
* const canvasProxy = new CanvasProxy(canvasElement);
|
|
321
|
+
* const context = new ObservableInputTracker(canvasProxy);
|
|
322
|
+
* const stateMachine = createKmtInputStateMachine(context);
|
|
323
|
+
*
|
|
324
|
+
* // Context tracks state as the state machine processes events
|
|
325
|
+
* stateMachine.happens("leftPointerDown", {x: 100, y: 200});
|
|
326
|
+
* console.log(context.initialCursorPosition); // {x: 100, y: 200}
|
|
327
|
+
* ```
|
|
173
328
|
*/
|
|
174
329
|
export declare class ObservableInputTracker implements KmtInputContext {
|
|
175
330
|
private _alignCoordinateSystem;
|
|
176
331
|
private _canvasOperator;
|
|
177
|
-
private _inputPublisher;
|
|
178
332
|
private _initialCursorPosition;
|
|
179
|
-
private
|
|
180
|
-
private
|
|
181
|
-
constructor(canvasOperator: Canvas
|
|
333
|
+
private _kmtTrackpadTrackScore;
|
|
334
|
+
private _mode;
|
|
335
|
+
constructor(canvasOperator: Canvas);
|
|
336
|
+
get mode(): 'kmt' | 'trackpad' | 'TBD';
|
|
337
|
+
setMode(mode: 'kmt' | 'trackpad' | 'TBD'): void;
|
|
338
|
+
get kmtTrackpadTrackScore(): number;
|
|
339
|
+
subtractKmtTrackpadTrackScore(): void;
|
|
340
|
+
addKmtTrackpadTrackScore(): void;
|
|
182
341
|
get alignCoordinateSystem(): boolean;
|
|
183
342
|
get canvas(): Canvas;
|
|
184
343
|
get initialCursorPosition(): Point;
|
|
185
344
|
set alignCoordinateSystem(value: boolean);
|
|
186
|
-
notifyOnPan(delta: Point): void;
|
|
187
|
-
notifyOnZoom(zoomAmount: number, anchorPoint: Point): void;
|
|
188
|
-
notifyOnRotate(deltaRotation: number): void;
|
|
189
345
|
cancelCurrentAction(): void;
|
|
190
346
|
setInitialCursorPosition(position: Point): void;
|
|
191
|
-
toggleOnEdgeAutoCameraInput(): void;
|
|
192
|
-
toggleOffEdgeAutoCameraInput(): void;
|
|
193
|
-
setCursorPosition(position: Point): void;
|
|
194
347
|
cleanup(): void;
|
|
195
348
|
setup(): void;
|
|
196
349
|
}
|