@ue-too/board 0.9.4 → 0.10.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
package/camera/base.d.ts
CHANGED
|
@@ -5,15 +5,42 @@ import { RotationLimits } from './utils/rotation';
|
|
|
5
5
|
import { BoardCamera } from './interface';
|
|
6
6
|
import { TransformationMatrix } from './utils/matrix';
|
|
7
7
|
/**
|
|
8
|
+
* Base camera implementation providing core functionality for an infinite canvas system.
|
|
9
|
+
* This is the fundamental building block for camera management in the board package.
|
|
8
10
|
*
|
|
9
|
-
* @
|
|
11
|
+
* @remarks
|
|
12
|
+
* BaseCamera is non-observable and does not emit events when state changes.
|
|
13
|
+
* For event-driven camera updates, use {@link DefaultBoardCamera} instead.
|
|
10
14
|
*
|
|
11
|
-
*
|
|
15
|
+
* The camera supports:
|
|
16
|
+
* - Position, rotation, and zoom transformations
|
|
17
|
+
* - Configurable boundaries for position, zoom, and rotation
|
|
18
|
+
* - Coordinate conversion between viewport and world space
|
|
19
|
+
* - Transformation matrix caching for performance
|
|
20
|
+
* - High-DPI display support via devicePixelRatio
|
|
12
21
|
*
|
|
13
|
-
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* // Create a camera for a 1920x1080 viewport
|
|
25
|
+
* const camera = new BaseCamera(1920, 1080, { x: 0, y: 0 }, 0, 1.0);
|
|
26
|
+
*
|
|
27
|
+
* // Set boundaries to constrain camera movement
|
|
28
|
+
* camera.setHorizontalBoundaries(-5000, 5000);
|
|
29
|
+
* camera.setVerticalBoundaries(-5000, 5000);
|
|
30
|
+
*
|
|
31
|
+
* // Update camera state
|
|
32
|
+
* camera.setPosition({ x: 100, y: 200 });
|
|
33
|
+
* camera.setZoomLevel(2.0);
|
|
34
|
+
* camera.setRotation(Math.PI / 6);
|
|
35
|
+
*
|
|
36
|
+
* // Get transformation matrix for rendering
|
|
37
|
+
* const transform = camera.getTransform(window.devicePixelRatio, true);
|
|
38
|
+
* ctx.setTransform(transform.a, transform.b, transform.c, transform.d, transform.e, transform.f);
|
|
39
|
+
* ```
|
|
14
40
|
*
|
|
15
|
-
* This class is not observable (you can not register a callback for camera state changes). If you need to observe the camera state, use the {@link DefaultBoardCamera} class instead.
|
|
16
41
|
* @category Camera
|
|
42
|
+
* @see {@link DefaultBoardCamera} for observable camera with event support
|
|
43
|
+
* @see {@link CameraRig} for high-level camera control with input handling
|
|
17
44
|
*/
|
|
18
45
|
export default class BaseCamera implements BoardCamera {
|
|
19
46
|
private _position;
|
|
@@ -26,97 +53,223 @@ export default class BaseCamera implements BoardCamera {
|
|
|
26
53
|
private _zoomBoundaries?;
|
|
27
54
|
private _rotationBoundaries?;
|
|
28
55
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* @param
|
|
32
|
-
* @param
|
|
33
|
-
* @param
|
|
34
|
-
* @param
|
|
35
|
-
* @param
|
|
36
|
-
* @param
|
|
56
|
+
* Creates a new BaseCamera instance with specified viewport size and optional constraints.
|
|
57
|
+
*
|
|
58
|
+
* @param viewPortWidth - Width of the viewport in CSS pixels (default: 1000)
|
|
59
|
+
* @param viewPortHeight - Height of the viewport in CSS pixels (default: 1000)
|
|
60
|
+
* @param position - Initial camera position in world coordinates (default: {x: 0, y: 0})
|
|
61
|
+
* @param rotation - Initial rotation in radians (default: 0)
|
|
62
|
+
* @param zoomLevel - Initial zoom level, where 1.0 = 100% (default: 1.0)
|
|
63
|
+
* @param boundaries - Position constraints in world space (default: ±10000 on both axes)
|
|
64
|
+
* @param zoomLevelBoundaries - Zoom constraints (default: 0.1 to 10)
|
|
65
|
+
* @param rotationBoundaries - Optional rotation constraints (default: undefined, unrestricted)
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* // Basic camera with defaults
|
|
70
|
+
* const camera = new BaseCamera();
|
|
71
|
+
*
|
|
72
|
+
* // Camera with custom viewport and position
|
|
73
|
+
* const camera2 = new BaseCamera(
|
|
74
|
+
* 1920, 1080,
|
|
75
|
+
* { x: 500, y: 300 },
|
|
76
|
+
* 0,
|
|
77
|
+
* 1.5
|
|
78
|
+
* );
|
|
79
|
+
*
|
|
80
|
+
* // Camera with all constraints
|
|
81
|
+
* const camera3 = new BaseCamera(
|
|
82
|
+
* 1920, 1080,
|
|
83
|
+
* { x: 0, y: 0 },
|
|
84
|
+
* 0,
|
|
85
|
+
* 1.0,
|
|
86
|
+
* { min: { x: -2000, y: -2000 }, max: { x: 2000, y: 2000 } },
|
|
87
|
+
* { min: 0.5, max: 5 },
|
|
88
|
+
* { start: 0, end: Math.PI / 2 }
|
|
89
|
+
* );
|
|
90
|
+
* ```
|
|
37
91
|
*/
|
|
38
92
|
constructor(viewPortWidth?: number, viewPortHeight?: number, position?: Point, rotation?: number, zoomLevel?: number, boundaries?: Boundaries, zoomLevelBoundaries?: ZoomLevelLimits, rotationBoundaries?: RotationLimits | undefined);
|
|
39
93
|
/**
|
|
40
|
-
*
|
|
94
|
+
* Gets the current position boundaries that constrain camera movement in world coordinates.
|
|
41
95
|
*
|
|
42
|
-
* @
|
|
96
|
+
* @returns The boundaries object or undefined if no boundaries are set
|
|
43
97
|
*/
|
|
44
98
|
get boundaries(): Boundaries | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* Sets position boundaries to constrain camera movement in world coordinates.
|
|
101
|
+
*
|
|
102
|
+
* @param boundaries - Boundary constraints or undefined to remove all constraints
|
|
103
|
+
*/
|
|
45
104
|
set boundaries(boundaries: Boundaries | undefined);
|
|
46
105
|
/**
|
|
47
|
-
*
|
|
106
|
+
* Gets the viewport width in CSS pixels.
|
|
48
107
|
*
|
|
49
|
-
* @
|
|
108
|
+
* @returns Current viewport width
|
|
50
109
|
*/
|
|
51
110
|
get viewPortWidth(): number;
|
|
111
|
+
/**
|
|
112
|
+
* Sets the viewport width in CSS pixels.
|
|
113
|
+
* Updates invalidate the cached transformation matrix.
|
|
114
|
+
*
|
|
115
|
+
* @param width - New viewport width in CSS pixels
|
|
116
|
+
*/
|
|
52
117
|
set viewPortWidth(width: number);
|
|
53
118
|
/**
|
|
54
|
-
*
|
|
119
|
+
* Gets the viewport height in CSS pixels.
|
|
55
120
|
*
|
|
56
|
-
* @
|
|
121
|
+
* @returns Current viewport height
|
|
57
122
|
*/
|
|
58
123
|
get viewPortHeight(): number;
|
|
124
|
+
/**
|
|
125
|
+
* Sets the viewport height in CSS pixels.
|
|
126
|
+
* Updates invalidate the cached transformation matrix.
|
|
127
|
+
*
|
|
128
|
+
* @param height - New viewport height in CSS pixels
|
|
129
|
+
*/
|
|
59
130
|
set viewPortHeight(height: number);
|
|
60
131
|
/**
|
|
61
|
-
*
|
|
132
|
+
* Gets the current camera position in world coordinates.
|
|
62
133
|
*
|
|
63
|
-
* @
|
|
134
|
+
* @returns A copy of the current position (center of viewport in world space)
|
|
64
135
|
*/
|
|
65
136
|
get position(): Point;
|
|
66
137
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* @
|
|
138
|
+
* Sets the camera position with boundary validation and floating-point jitter prevention.
|
|
139
|
+
*
|
|
140
|
+
* @param destination - Target position in world coordinates
|
|
141
|
+
* @returns True if position was updated, false if rejected by boundaries or negligible change
|
|
142
|
+
*
|
|
143
|
+
* @remarks
|
|
144
|
+
* Position updates are rejected if:
|
|
145
|
+
* - The destination is outside the configured boundaries
|
|
146
|
+
* - The change magnitude is less than 10E-10
|
|
147
|
+
* - The change magnitude is less than 1/zoomLevel (prevents sub-pixel jitter)
|
|
70
148
|
*
|
|
71
|
-
* @
|
|
72
|
-
*
|
|
73
|
-
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* camera.setHorizontalBoundaries(-1000, 1000);
|
|
152
|
+
* camera.setVerticalBoundaries(-1000, 1000);
|
|
153
|
+
*
|
|
154
|
+
* camera.setPosition({ x: 500, y: 500 }); // returns true
|
|
155
|
+
* camera.setPosition({ x: 2000, y: 0 }); // returns false (out of bounds)
|
|
156
|
+
* ```
|
|
74
157
|
*/
|
|
75
158
|
setPosition(destination: Point): boolean;
|
|
76
159
|
/**
|
|
77
|
-
*
|
|
160
|
+
* Gets the current zoom level.
|
|
78
161
|
*
|
|
79
|
-
* @
|
|
162
|
+
* @returns Current zoom level (1.0 = 100%, 2.0 = 200%, etc.)
|
|
80
163
|
*/
|
|
81
164
|
get zoomLevel(): number;
|
|
82
165
|
/**
|
|
83
|
-
*
|
|
166
|
+
* Gets the current zoom level constraints.
|
|
84
167
|
*
|
|
85
|
-
* @
|
|
168
|
+
* @returns Zoom boundaries object or undefined if unconstrained
|
|
86
169
|
*/
|
|
87
170
|
get zoomBoundaries(): ZoomLevelLimits | undefined;
|
|
88
171
|
/**
|
|
89
|
-
*
|
|
172
|
+
* Sets zoom level constraints with automatic min/max swapping if needed.
|
|
173
|
+
*
|
|
174
|
+
* @param zoomBoundaries - Zoom constraints or undefined to remove constraints
|
|
90
175
|
*
|
|
91
|
-
* @
|
|
176
|
+
* @remarks
|
|
177
|
+
* If min > max, the values are automatically swapped.
|
|
92
178
|
*/
|
|
93
179
|
set zoomBoundaries(zoomBoundaries: ZoomLevelLimits | undefined);
|
|
180
|
+
/**
|
|
181
|
+
* Sets the maximum allowed zoom level.
|
|
182
|
+
*
|
|
183
|
+
* @param maxZoomLevel - New maximum zoom level
|
|
184
|
+
* @returns True if successfully set, false if conflicts with existing min or current zoom
|
|
185
|
+
*
|
|
186
|
+
* @remarks
|
|
187
|
+
* Returns false if:
|
|
188
|
+
* - The new max is less than the current minimum boundary
|
|
189
|
+
* - The current zoom level exceeds the new maximum
|
|
190
|
+
*/
|
|
94
191
|
setMaxZoomLevel(maxZoomLevel: number): boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Sets the minimum allowed zoom level.
|
|
194
|
+
*
|
|
195
|
+
* @param minZoomLevel - New minimum zoom level
|
|
196
|
+
* @returns True if successfully set, false if conflicts with existing max
|
|
197
|
+
*
|
|
198
|
+
* @remarks
|
|
199
|
+
* If the current zoom level is below the new minimum, the camera automatically
|
|
200
|
+
* zooms in to match the minimum. Returns false if new min exceeds existing max boundary.
|
|
201
|
+
*/
|
|
95
202
|
setMinZoomLevel(minZoomLevel: number): boolean;
|
|
96
203
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* @
|
|
204
|
+
* Sets the camera zoom level with boundary validation.
|
|
205
|
+
*
|
|
206
|
+
* @param zoomLevel - Target zoom level (1.0 = 100%, 2.0 = 200%, etc.)
|
|
207
|
+
* @returns True if zoom was updated, false if outside boundaries or already at limit
|
|
208
|
+
*
|
|
209
|
+
* @remarks
|
|
210
|
+
* Returns false if:
|
|
211
|
+
* - Zoom level is outside configured boundaries
|
|
212
|
+
* - Already at maximum and trying to zoom beyond it
|
|
213
|
+
* - Already at minimum and trying to zoom below it
|
|
100
214
|
*
|
|
101
|
-
* @
|
|
102
|
-
*
|
|
103
|
-
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```typescript
|
|
217
|
+
* camera.setZoomLevel(2.0); // 200% zoom
|
|
218
|
+
* camera.setZoomLevel(0.5); // 50% zoom
|
|
219
|
+
* ```
|
|
104
220
|
*/
|
|
105
221
|
setZoomLevel(zoomLevel: number): boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Gets the current camera rotation in radians.
|
|
224
|
+
*
|
|
225
|
+
* @returns Current rotation angle (0 to 2π)
|
|
226
|
+
*/
|
|
106
227
|
get rotation(): number;
|
|
228
|
+
/**
|
|
229
|
+
* Gets the current rotation constraints.
|
|
230
|
+
*
|
|
231
|
+
* @returns Rotation boundaries or undefined if unconstrained
|
|
232
|
+
*/
|
|
107
233
|
get rotationBoundaries(): RotationLimits | undefined;
|
|
234
|
+
/**
|
|
235
|
+
* Sets rotation constraints with automatic start/end swapping if needed.
|
|
236
|
+
*
|
|
237
|
+
* @param rotationBoundaries - Rotation limits or undefined to remove constraints
|
|
238
|
+
*
|
|
239
|
+
* @remarks
|
|
240
|
+
* If start > end, the values are automatically swapped.
|
|
241
|
+
*/
|
|
108
242
|
set rotationBoundaries(rotationBoundaries: RotationLimits | undefined);
|
|
109
243
|
/**
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
* 2. Translation (move the origin of the context to the center of the canvas)
|
|
113
|
-
* 3. Rotation (rotate the context negatively the rotation of the camera)
|
|
114
|
-
* 4. Zoom (scale the context using the zoom level of the camera)
|
|
115
|
-
* 5. Translation (move the origin of the context to the position of the camera in the context coordinate system)
|
|
244
|
+
* Computes the complete transformation matrix from world space to canvas pixel space.
|
|
245
|
+
* Includes caching for performance optimization.
|
|
116
246
|
*
|
|
117
|
-
* @param devicePixelRatio
|
|
118
|
-
* @param alignCoorindate
|
|
119
|
-
* @returns
|
|
247
|
+
* @param devicePixelRatio - Device pixel ratio (typically window.devicePixelRatio)
|
|
248
|
+
* @param alignCoorindate - If true, uses standard y-up coordinate system. If false, inverts y-axis
|
|
249
|
+
* @returns Transformation matrix object {a, b, c, d, e, f} with optional cached flag
|
|
250
|
+
*
|
|
251
|
+
* @remarks
|
|
252
|
+
* Transformation order applied:
|
|
253
|
+
* 1. Scale by devicePixelRatio
|
|
254
|
+
* 2. Translate to viewport center
|
|
255
|
+
* 3. Rotate (negated if alignCoorindate is true)
|
|
256
|
+
* 4. Scale by zoom level
|
|
257
|
+
* 5. Translate by camera position
|
|
258
|
+
*
|
|
259
|
+
* The result is cached based on all parameters. Subsequent calls with identical parameters
|
|
260
|
+
* return the cached matrix with `cached: true` flag.
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```typescript
|
|
264
|
+
* const ctx = canvas.getContext('2d');
|
|
265
|
+
* const transform = camera.getTransform(window.devicePixelRatio, true);
|
|
266
|
+
* ctx.setTransform(transform.a, transform.b, transform.c, transform.d, transform.e, transform.f);
|
|
267
|
+
*
|
|
268
|
+
* // Now drawing at world coordinates (100, 200) appears correctly on canvas
|
|
269
|
+
* ctx.fillRect(100, 200, 50, 50);
|
|
270
|
+
* ```
|
|
271
|
+
*
|
|
272
|
+
* @see {@link getTRS} for decomposed transformation components
|
|
120
273
|
*/
|
|
121
274
|
getTransform(devicePixelRatio: number, alignCoorindate: boolean): {
|
|
122
275
|
cached: boolean;
|
|
@@ -127,6 +280,17 @@ export default class BaseCamera implements BoardCamera {
|
|
|
127
280
|
e: number;
|
|
128
281
|
f: number;
|
|
129
282
|
};
|
|
283
|
+
/**
|
|
284
|
+
* Decomposes the transformation matrix into Translation, Rotation, and Scale components.
|
|
285
|
+
*
|
|
286
|
+
* @param devicePixelRatio - Device pixel ratio for high-DPI displays
|
|
287
|
+
* @param alignCoorindate - If true, uses standard y-up coordinate system. If false, inverts y-axis
|
|
288
|
+
* @returns Object containing separate scale, rotation, and translation values
|
|
289
|
+
*
|
|
290
|
+
* @remarks
|
|
291
|
+
* This is useful when you need individual transformation components rather than
|
|
292
|
+
* the combined matrix. Internally calls {@link getTransform} and decomposes the result.
|
|
293
|
+
*/
|
|
130
294
|
getTRS(devicePixelRatio: number, alignCoorindate: boolean): {
|
|
131
295
|
translation: {
|
|
132
296
|
x: number;
|
|
@@ -139,53 +303,160 @@ export default class BaseCamera implements BoardCamera {
|
|
|
139
303
|
};
|
|
140
304
|
};
|
|
141
305
|
/**
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
306
|
+
* Sets camera state by decomposing a transformation matrix.
|
|
307
|
+
* Inverse operation of {@link getTransform}.
|
|
308
|
+
*
|
|
309
|
+
* @param transformationMatrix - 2D transformation matrix to decompose
|
|
146
310
|
*
|
|
147
|
-
* @
|
|
311
|
+
* @remarks
|
|
312
|
+
* The matrix is decomposed assuming the same transformation order as {@link getTransform}:
|
|
313
|
+
* Scale(devicePixelRatio) → Translation(viewport center) → Rotation → Zoom → Translation(position)
|
|
148
314
|
*
|
|
149
|
-
*
|
|
315
|
+
* Extracted position, zoom, and rotation values are still validated against boundaries.
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```typescript
|
|
319
|
+
* // Apply a transformation matrix from an external source
|
|
320
|
+
* const matrix = { a: 2, b: 0, c: 0, d: 2, e: 100, f: 100 };
|
|
321
|
+
* camera.setUsingTransformationMatrix(matrix);
|
|
322
|
+
* ```
|
|
150
323
|
*/
|
|
151
324
|
setUsingTransformationMatrix(transformationMatrix: TransformationMatrix): void;
|
|
325
|
+
/**
|
|
326
|
+
* Sets the camera rotation with boundary validation and normalization.
|
|
327
|
+
*
|
|
328
|
+
* @param rotation - Target rotation in radians
|
|
329
|
+
* @returns True if rotation was updated, false if outside boundaries or already at limit
|
|
330
|
+
*
|
|
331
|
+
* @remarks
|
|
332
|
+
* Rotation is automatically normalized to 0-2π range. Returns false if:
|
|
333
|
+
* - Rotation is outside configured boundaries
|
|
334
|
+
* - Already at maximum boundary and trying to rotate beyond it
|
|
335
|
+
* - Already at minimum boundary and trying to rotate below it
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* ```typescript
|
|
339
|
+
* camera.setRotation(Math.PI / 4); // 45 degrees
|
|
340
|
+
* camera.setRotation(Math.PI); // 180 degrees
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
152
343
|
setRotation(rotation: number): boolean;
|
|
153
344
|
/**
|
|
154
|
-
*
|
|
155
|
-
*
|
|
345
|
+
* Gets the camera origin in window coordinates.
|
|
346
|
+
*
|
|
347
|
+
* @deprecated This method is deprecated and will be removed in a future version.
|
|
348
|
+
* Currently just returns the input unchanged.
|
|
156
349
|
*
|
|
157
|
-
* @
|
|
350
|
+
* @param centerInWindow - Center point in window coordinates
|
|
351
|
+
* @returns The same point (camera origin equals window center)
|
|
158
352
|
*/
|
|
159
353
|
getCameraOriginInWindow(centerInWindow: Point): Point;
|
|
160
354
|
/**
|
|
161
|
-
*
|
|
355
|
+
* Converts a point from viewport coordinates to world coordinates.
|
|
356
|
+
*
|
|
357
|
+
* @param point - Point in viewport space (relative to viewport center, in CSS pixels)
|
|
358
|
+
* @returns Corresponding point in world coordinates
|
|
162
359
|
*
|
|
163
|
-
* @
|
|
164
|
-
*
|
|
360
|
+
* @remarks
|
|
361
|
+
* This accounts for camera position, zoom, and rotation. Useful for converting
|
|
362
|
+
* mouse/touch input to world space.
|
|
165
363
|
*
|
|
166
|
-
* @
|
|
364
|
+
* @example
|
|
365
|
+
* ```typescript
|
|
366
|
+
* // Convert mouse click to world position
|
|
367
|
+
* const rect = canvas.getBoundingClientRect();
|
|
368
|
+
* const viewportPoint = {
|
|
369
|
+
* x: event.clientX - rect.left - rect.width / 2,
|
|
370
|
+
* y: event.clientY - rect.top - rect.height / 2
|
|
371
|
+
* };
|
|
372
|
+
* const worldPoint = camera.convertFromViewPort2WorldSpace(viewportPoint);
|
|
373
|
+
* ```
|
|
167
374
|
*/
|
|
168
375
|
convertFromViewPort2WorldSpace(point: Point): Point;
|
|
169
376
|
/**
|
|
170
|
-
*
|
|
377
|
+
* Converts a point from world coordinates to viewport coordinates.
|
|
171
378
|
*
|
|
172
|
-
* @param point
|
|
173
|
-
* @returns
|
|
379
|
+
* @param point - Point in world coordinates
|
|
380
|
+
* @returns Corresponding point in viewport space (relative to viewport center, in CSS pixels)
|
|
174
381
|
*
|
|
175
|
-
* @
|
|
382
|
+
* @remarks
|
|
383
|
+
* This accounts for camera position, zoom, and rotation. Useful for positioning
|
|
384
|
+
* UI elements at world object locations.
|
|
385
|
+
*
|
|
386
|
+
* @example
|
|
387
|
+
* ```typescript
|
|
388
|
+
* // Position a DOM element at a world object's location
|
|
389
|
+
* const viewportPos = camera.convertFromWorld2ViewPort(objectWorldPos);
|
|
390
|
+
* element.style.left = `${viewportPos.x + canvas.width / 2}px`;
|
|
391
|
+
* element.style.top = `${viewportPos.y + canvas.height / 2}px`;
|
|
392
|
+
* ```
|
|
176
393
|
*/
|
|
177
394
|
convertFromWorld2ViewPort(point: Point): Point;
|
|
178
395
|
/**
|
|
179
|
-
*
|
|
396
|
+
* Converts a point from world coordinates to viewport coordinates.
|
|
397
|
+
* Alternative implementation of {@link convertFromWorld2ViewPort}.
|
|
180
398
|
*
|
|
181
|
-
* @param point
|
|
182
|
-
* @returns
|
|
399
|
+
* @param point - Point in world coordinates
|
|
400
|
+
* @returns Corresponding point in viewport space (relative to viewport center, in CSS pixels)
|
|
183
401
|
*
|
|
184
|
-
* @
|
|
402
|
+
* @remarks
|
|
403
|
+
* This method provides an alternative calculation approach. In most cases,
|
|
404
|
+
* prefer using {@link convertFromWorld2ViewPort} for consistency.
|
|
185
405
|
*/
|
|
186
406
|
invertFromWorldSpace2ViewPort(point: Point): Point;
|
|
407
|
+
/**
|
|
408
|
+
* Sets horizontal (x-axis) position boundaries for camera movement.
|
|
409
|
+
*
|
|
410
|
+
* @param min - Minimum x coordinate in world space
|
|
411
|
+
* @param max - Maximum x coordinate in world space
|
|
412
|
+
*
|
|
413
|
+
* @remarks
|
|
414
|
+
* If min > max, the values are automatically swapped. The current camera position
|
|
415
|
+
* is not automatically clamped when boundaries are set.
|
|
416
|
+
*
|
|
417
|
+
* @example
|
|
418
|
+
* ```typescript
|
|
419
|
+
* camera.setHorizontalBoundaries(-1000, 1000);
|
|
420
|
+
* // Camera can now only move between x: -1000 and x: 1000
|
|
421
|
+
* ```
|
|
422
|
+
*/
|
|
187
423
|
setHorizontalBoundaries(min: number, max: number): void;
|
|
424
|
+
/**
|
|
425
|
+
* Sets vertical (y-axis) position boundaries for camera movement.
|
|
426
|
+
*
|
|
427
|
+
* @param min - Minimum y coordinate in world space
|
|
428
|
+
* @param max - Maximum y coordinate in world space
|
|
429
|
+
*
|
|
430
|
+
* @remarks
|
|
431
|
+
* If min > max, the values are automatically swapped. The current camera position
|
|
432
|
+
* is not automatically clamped when boundaries are set.
|
|
433
|
+
*
|
|
434
|
+
* @example
|
|
435
|
+
* ```typescript
|
|
436
|
+
* camera.setVerticalBoundaries(-500, 500);
|
|
437
|
+
* // Camera can now only move between y: -500 and y: 500
|
|
438
|
+
* ```
|
|
439
|
+
*/
|
|
188
440
|
setVerticalBoundaries(min: number, max: number): void;
|
|
441
|
+
/**
|
|
442
|
+
* Calculates the four corners of the viewport in world space, accounting for rotation.
|
|
443
|
+
*
|
|
444
|
+
* @param alignCoordinate - If true, uses standard y-up coordinate system. If false, inverts y-axis (default: true)
|
|
445
|
+
* @returns Object containing the four corner points organized as top/bottom and left/right
|
|
446
|
+
*
|
|
447
|
+
* @remarks
|
|
448
|
+
* Returns the actual rotated viewport corners. This is more precise than {@link viewPortAABB}
|
|
449
|
+
* which returns the axis-aligned bounding box. Use this when you need the exact viewport bounds.
|
|
450
|
+
*
|
|
451
|
+
* @example
|
|
452
|
+
* ```typescript
|
|
453
|
+
* const corners = camera.viewPortInWorldSpace();
|
|
454
|
+
* console.log(corners.top.left); // Top-left corner in world coords
|
|
455
|
+
* console.log(corners.top.right); // Top-right corner
|
|
456
|
+
* console.log(corners.bottom.left); // Bottom-left corner
|
|
457
|
+
* console.log(corners.bottom.right);// Bottom-right corner
|
|
458
|
+
* ```
|
|
459
|
+
*/
|
|
189
460
|
viewPortInWorldSpace(alignCoordinate?: boolean): {
|
|
190
461
|
top: {
|
|
191
462
|
left: Point;
|
|
@@ -196,6 +467,31 @@ export default class BaseCamera implements BoardCamera {
|
|
|
196
467
|
right: Point;
|
|
197
468
|
};
|
|
198
469
|
};
|
|
470
|
+
/**
|
|
471
|
+
* Calculates the axis-aligned bounding box (AABB) of the viewport in world space.
|
|
472
|
+
*
|
|
473
|
+
* @param alignCoordinate - If true, uses standard y-up coordinate system. If false, inverts y-axis
|
|
474
|
+
* @returns Object with min and max points defining the AABB
|
|
475
|
+
*
|
|
476
|
+
* @remarks
|
|
477
|
+
* This returns the smallest axis-aligned rectangle that contains the entire viewport.
|
|
478
|
+
* When the camera is rotated, this AABB will be larger than the actual viewport.
|
|
479
|
+
* For exact viewport bounds, use {@link viewPortInWorldSpace}.
|
|
480
|
+
*
|
|
481
|
+
* Useful for:
|
|
482
|
+
* - Frustum culling (checking if objects are visible)
|
|
483
|
+
* - Broad-phase collision detection
|
|
484
|
+
* - Determining which tiles/chunks to load
|
|
485
|
+
*
|
|
486
|
+
* @example
|
|
487
|
+
* ```typescript
|
|
488
|
+
* const aabb = camera.viewPortAABB();
|
|
489
|
+
* const isVisible = (
|
|
490
|
+
* object.x >= aabb.min.x && object.x <= aabb.max.x &&
|
|
491
|
+
* object.y >= aabb.min.y && object.y <= aabb.max.y
|
|
492
|
+
* );
|
|
493
|
+
* ```
|
|
494
|
+
*/
|
|
199
495
|
viewPortAABB(alignCoordinate?: boolean): {
|
|
200
496
|
min: Point;
|
|
201
497
|
max: Point;
|
|
@@ -1,13 +1,118 @@
|
|
|
1
1
|
import { CameraMux } from "./camera-mux";
|
|
2
|
+
/**
|
|
3
|
+
* Automatic camera panning triggered by cursor proximity to viewport edges.
|
|
4
|
+
* Commonly used in strategy games, map editors, and design tools.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* This class implements edge-scrolling behavior where the camera automatically
|
|
8
|
+
* pans when the cursor approaches the viewport edges. The panning speed is
|
|
9
|
+
* constant and direction-based (no acceleration).
|
|
10
|
+
*
|
|
11
|
+
* The camera moves in viewport space, meaning the speed is consistent regardless
|
|
12
|
+
* of zoom level. The actual world-space movement will vary with zoom.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const cameraMux = new CameraMux(camera);
|
|
17
|
+
* const edgeScroll = new EdgeAutoCameraInput(cameraMux);
|
|
18
|
+
*
|
|
19
|
+
* // Track mouse position relative to viewport edges
|
|
20
|
+
* canvas.addEventListener('mousemove', (e) => {
|
|
21
|
+
* const rect = canvas.getBoundingClientRect();
|
|
22
|
+
* const edgeMargin = 50; // pixels from edge
|
|
23
|
+
*
|
|
24
|
+
* let horizontal: 'left' | 'right' | 'none' = 'none';
|
|
25
|
+
* let vertical: 'up' | 'down' | 'none' = 'none';
|
|
26
|
+
*
|
|
27
|
+
* if (e.clientX - rect.left < edgeMargin) horizontal = 'left';
|
|
28
|
+
* if (rect.right - e.clientX < edgeMargin) horizontal = 'right';
|
|
29
|
+
* if (e.clientY - rect.top < edgeMargin) vertical = 'up';
|
|
30
|
+
* if (rect.bottom - e.clientY < edgeMargin) vertical = 'down';
|
|
31
|
+
*
|
|
32
|
+
* edgeScroll.setDirection(horizontal, vertical);
|
|
33
|
+
* edgeScroll.toggleOn();
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // Stop scrolling when mouse leaves
|
|
37
|
+
* canvas.addEventListener('mouseleave', () => {
|
|
38
|
+
* edgeScroll.toggleOff();
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* // Update in render loop
|
|
42
|
+
* function render(deltaTime: number) {
|
|
43
|
+
* edgeScroll.update(deltaTime / 1000); // convert ms to seconds
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @category Camera
|
|
48
|
+
* @see {@link CameraMux} for the camera input multiplexer this feeds into
|
|
49
|
+
*/
|
|
2
50
|
export declare class EdgeAutoCameraInput {
|
|
3
51
|
private _cameraMux;
|
|
4
52
|
private _state;
|
|
5
53
|
private _speed;
|
|
6
54
|
private _horizontalDirection;
|
|
7
55
|
private _verticalDirection;
|
|
56
|
+
/**
|
|
57
|
+
* Creates a new edge auto-scroll input controller.
|
|
58
|
+
*
|
|
59
|
+
* @param cameraMux - The camera multiplexer to send pan inputs to
|
|
60
|
+
*/
|
|
8
61
|
constructor(cameraMux: CameraMux);
|
|
62
|
+
/**
|
|
63
|
+
* Disables edge scrolling.
|
|
64
|
+
* The camera will stop panning even if direction is set.
|
|
65
|
+
*/
|
|
9
66
|
toggleOff(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Enables edge scrolling.
|
|
69
|
+
* The camera will pan according to the current direction setting.
|
|
70
|
+
*/
|
|
10
71
|
toggleOn(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Sets the scrolling direction based on cursor position relative to edges.
|
|
74
|
+
*
|
|
75
|
+
* @param horizontalDirection - Horizontal scroll direction ('left', 'right', or 'none')
|
|
76
|
+
* @param verticalDirection - Vertical scroll direction ('up', 'down', or 'none')
|
|
77
|
+
*
|
|
78
|
+
* @remarks
|
|
79
|
+
* Directions can be combined for diagonal scrolling.
|
|
80
|
+
* Set both to 'none' to stop scrolling without disabling via {@link toggleOff}.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* edgeScroll.setDirection('left', 'none'); // Scroll left only
|
|
85
|
+
* edgeScroll.setDirection('right', 'up'); // Scroll diagonally up-right
|
|
86
|
+
* edgeScroll.setDirection('none', 'none'); // Stop scrolling
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
11
89
|
setDirection(horizontalDirection: 'left' | 'right' | 'none', verticalDirection: 'up' | 'down' | 'none'): void;
|
|
90
|
+
/**
|
|
91
|
+
* Updates the camera position based on elapsed time and current direction.
|
|
92
|
+
* Call this in your render loop or update tick.
|
|
93
|
+
*
|
|
94
|
+
* @param deltaTime - Time elapsed since last update in seconds
|
|
95
|
+
*
|
|
96
|
+
* @remarks
|
|
97
|
+
* The camera pans at a constant speed of 100 pixels/second in viewport space.
|
|
98
|
+
* This is independent of zoom level - world-space movement varies with zoom.
|
|
99
|
+
*
|
|
100
|
+
* If the state is 'idle', this method does nothing.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* // In animation frame callback
|
|
105
|
+
* let lastTime = performance.now();
|
|
106
|
+
*
|
|
107
|
+
* function animate(currentTime: number) {
|
|
108
|
+
* const deltaTime = (currentTime - lastTime) / 1000; // Convert to seconds
|
|
109
|
+
* lastTime = currentTime;
|
|
110
|
+
*
|
|
111
|
+
* edgeScroll.update(deltaTime);
|
|
112
|
+
*
|
|
113
|
+
* requestAnimationFrame(animate);
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
12
117
|
update(deltaTime: number): void;
|
|
13
118
|
}
|