@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/utils/matrix.d.ts
CHANGED
|
@@ -1,10 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* 2D affine transformation matrix in standard CSS/Canvas format.
|
|
3
|
+
*
|
|
4
|
+
* Represents a 3x3 matrix in homogeneous coordinates, stored in the compact 6-parameter form:
|
|
4
5
|
* ```
|
|
5
|
-
* | a
|
|
6
|
-
* | b
|
|
7
|
-
* | 0
|
|
6
|
+
* | a c e |
|
|
7
|
+
* | b d f |
|
|
8
|
+
* | 0 0 1 |
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* @property a - Horizontal scaling / rotation component (m11)
|
|
12
|
+
* @property b - Vertical skewing / rotation component (m12)
|
|
13
|
+
* @property c - Horizontal skewing / rotation component (m21)
|
|
14
|
+
* @property d - Vertical scaling / rotation component (m22)
|
|
15
|
+
* @property e - Horizontal translation (tx)
|
|
16
|
+
* @property f - Vertical translation (ty)
|
|
17
|
+
*
|
|
18
|
+
* @remarks
|
|
19
|
+
* This format is compatible with:
|
|
20
|
+
* - Canvas 2D context: `ctx.setTransform(a, b, c, d, e, f)`
|
|
21
|
+
* - CSS transforms: `matrix(a, b, c, d, e, f)`
|
|
22
|
+
* - SVG transforms: `matrix(a b c d e f)`
|
|
23
|
+
*
|
|
24
|
+
* Common transformation types:
|
|
25
|
+
* - **Translation**: `{a: 1, b: 0, c: 0, d: 1, e: tx, f: ty}`
|
|
26
|
+
* - **Scaling**: `{a: sx, b: 0, c: 0, d: sy, e: 0, f: 0}`
|
|
27
|
+
* - **Rotation**: `{a: cos(θ), b: sin(θ), c: -sin(θ), d: cos(θ), e: 0, f: 0}`
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* // Identity matrix (no transformation)
|
|
32
|
+
* const identity: TransformationMatrix = {
|
|
33
|
+
* a: 1, b: 0, c: 0, d: 1, e: 0, f: 0
|
|
34
|
+
* };
|
|
35
|
+
*
|
|
36
|
+
* // Translation by (100, 50)
|
|
37
|
+
* const translate: TransformationMatrix = {
|
|
38
|
+
* a: 1, b: 0, c: 0, d: 1, e: 100, f: 50
|
|
39
|
+
* };
|
|
40
|
+
*
|
|
41
|
+
* // 2x scale
|
|
42
|
+
* const scale: TransformationMatrix = {
|
|
43
|
+
* a: 2, b: 0, c: 0, d: 2, e: 0, f: 0
|
|
44
|
+
* };
|
|
45
|
+
*
|
|
46
|
+
* // 45° rotation
|
|
47
|
+
* const rotate: TransformationMatrix = {
|
|
48
|
+
* a: 0.707, b: 0.707, c: -0.707, d: 0.707, e: 0, f: 0
|
|
49
|
+
* };
|
|
8
50
|
* ```
|
|
9
51
|
*
|
|
10
52
|
* @category Camera
|
|
@@ -18,16 +60,51 @@ export type TransformationMatrix = {
|
|
|
18
60
|
f: number;
|
|
19
61
|
};
|
|
20
62
|
/**
|
|
21
|
-
* Decomposes a camera transformation matrix back to camera parameters
|
|
63
|
+
* Decomposes a camera transformation matrix back to camera parameters.
|
|
64
|
+
* Inverse operation of {@link createCameraMatrix}.
|
|
22
65
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
66
|
+
* @param transformMatrix - The combined transformation matrix to decompose
|
|
67
|
+
* @param devicePixelRatio - Device pixel ratio used when creating the matrix
|
|
68
|
+
* @param canvasWidth - Canvas width in CSS pixels
|
|
69
|
+
* @param canvasHeight - Canvas height in CSS pixels
|
|
70
|
+
* @returns Camera parameters: position, zoom, and rotation
|
|
71
|
+
*
|
|
72
|
+
* @remarks
|
|
73
|
+
* This function reverses the transformation chain applied by {@link createCameraMatrix}:
|
|
74
|
+
* 1. Scale by devicePixelRatio
|
|
25
75
|
* 2. Translate to canvas center
|
|
26
76
|
* 3. Rotate by -camera.rotation
|
|
27
77
|
* 4. Scale by zoom level
|
|
28
78
|
* 5. Translate by -camera.position
|
|
29
79
|
*
|
|
30
|
-
* Final matrix: M =
|
|
80
|
+
* Final matrix: M = Scale(DPR) * Translate(center) * Rotate * Scale(zoom) * Translate(-position)
|
|
81
|
+
*
|
|
82
|
+
* The decomposition extracts:
|
|
83
|
+
* - **Rotation**: From the orientation of the transformation (atan2)
|
|
84
|
+
* - **Zoom**: From the total scale after removing devicePixelRatio
|
|
85
|
+
* - **Position**: By reversing the translation chain
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* // Create and then decompose a matrix
|
|
90
|
+
* const matrix = createCameraMatrix(
|
|
91
|
+
* { x: 100, y: 200 },
|
|
92
|
+
* 2.0,
|
|
93
|
+
* Math.PI / 4,
|
|
94
|
+
* window.devicePixelRatio,
|
|
95
|
+
* 1920, 1080
|
|
96
|
+
* );
|
|
97
|
+
*
|
|
98
|
+
* const params = decomposeCameraMatrix(
|
|
99
|
+
* matrix,
|
|
100
|
+
* window.devicePixelRatio,
|
|
101
|
+
* 1920, 1080
|
|
102
|
+
* );
|
|
103
|
+
* // params ≈ { position: {x: 100, y: 200}, zoom: 2.0, rotation: π/4 }
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @category Camera
|
|
107
|
+
* @see {@link createCameraMatrix} for the inverse operation
|
|
31
108
|
*/
|
|
32
109
|
export declare function decomposeCameraMatrix(transformMatrix: TransformationMatrix, devicePixelRatio: number, canvasWidth: number, canvasHeight: number): {
|
|
33
110
|
position: {
|
|
@@ -37,6 +114,55 @@ export declare function decomposeCameraMatrix(transformMatrix: TransformationMat
|
|
|
37
114
|
zoom: number;
|
|
38
115
|
rotation: number;
|
|
39
116
|
};
|
|
117
|
+
/**
|
|
118
|
+
* Creates a camera transformation matrix from camera parameters.
|
|
119
|
+
* This matrix transforms world coordinates to canvas pixel coordinates.
|
|
120
|
+
*
|
|
121
|
+
* @param cameraPos - Camera position in world coordinates
|
|
122
|
+
* @param zoom - Zoom level (1.0 = 100%, 2.0 = 200%, etc.)
|
|
123
|
+
* @param rotation - Camera rotation in radians
|
|
124
|
+
* @param devicePixelRatio - Device pixel ratio (typically window.devicePixelRatio)
|
|
125
|
+
* @param canvasWidth - Canvas width in CSS pixels (not canvas.width!)
|
|
126
|
+
* @param canvasHeight - Canvas height in CSS pixels (not canvas.height!)
|
|
127
|
+
* @returns Transformation matrix for world→canvas conversion
|
|
128
|
+
*
|
|
129
|
+
* @remarks
|
|
130
|
+
* **Important**: canvasWidth and canvasHeight are CSS pixel dimensions,
|
|
131
|
+
* not the internal canvas buffer size (canvas.width/canvas.height).
|
|
132
|
+
* Use element.clientWidth/clientHeight or the CSS dimensions.
|
|
133
|
+
*
|
|
134
|
+
* Transformation order:
|
|
135
|
+
* 1. Scale by devicePixelRatio (for high-DPI displays)
|
|
136
|
+
* 2. Translate to canvas center
|
|
137
|
+
* 3. Rotate by -camera.rotation (negated for correct direction)
|
|
138
|
+
* 4. Scale by zoom
|
|
139
|
+
* 5. Translate by -camera.position (world offset)
|
|
140
|
+
*
|
|
141
|
+
* The resulting matrix can be applied to a canvas context:
|
|
142
|
+
* ```typescript
|
|
143
|
+
* const {a, b, c, d, e, f} = createCameraMatrix(...);
|
|
144
|
+
* ctx.setTransform(a, b, c, d, e, f);
|
|
145
|
+
* // Now draw at world coordinates
|
|
146
|
+
* ```
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* const matrix = createCameraMatrix(
|
|
151
|
+
* { x: 100, y: 200 }, // camera position
|
|
152
|
+
* 2.0, // 2x zoom
|
|
153
|
+
* Math.PI / 6, // 30° rotation
|
|
154
|
+
* window.devicePixelRatio,
|
|
155
|
+
* canvas.clientWidth, // CSS width, not canvas.width!
|
|
156
|
+
* canvas.clientHeight
|
|
157
|
+
* );
|
|
158
|
+
*
|
|
159
|
+
* ctx.setTransform(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);
|
|
160
|
+
* ctx.fillRect(100, 200, 50, 50); // Draws at world coordinates (100, 200)
|
|
161
|
+
* ```
|
|
162
|
+
*
|
|
163
|
+
* @category Camera
|
|
164
|
+
* @see {@link decomposeCameraMatrix} for extracting camera parameters from a matrix
|
|
165
|
+
*/
|
|
40
166
|
export declare function createCameraMatrix(cameraPos: {
|
|
41
167
|
x: number;
|
|
42
168
|
y: number;
|
|
@@ -48,6 +174,55 @@ export declare function createCameraMatrix(cameraPos: {
|
|
|
48
174
|
e: number;
|
|
49
175
|
f: number;
|
|
50
176
|
};
|
|
177
|
+
/**
|
|
178
|
+
* Multiplies two 2D transformation matrices.
|
|
179
|
+
* Order matters: M = m1 × m2 applies m2 first, then m1.
|
|
180
|
+
*
|
|
181
|
+
* @param m1 - First transformation matrix (applied second)
|
|
182
|
+
* @param m2 - Second transformation matrix (applied first)
|
|
183
|
+
* @returns Combined transformation matrix
|
|
184
|
+
*
|
|
185
|
+
* @remarks
|
|
186
|
+
* Matrix multiplication is not commutative: m1 × m2 ≠ m2 × m1
|
|
187
|
+
*
|
|
188
|
+
* The result applies transformations in right-to-left order:
|
|
189
|
+
* - Result = m1 × m2
|
|
190
|
+
* - Applying result to point P: (m1 × m2) × P = m1 × (m2 × P)
|
|
191
|
+
* - m2 is applied first, then m1
|
|
192
|
+
*
|
|
193
|
+
* Common use: Building composite transformations
|
|
194
|
+
* ```typescript
|
|
195
|
+
* // Translate then rotate (rotate happens first!)
|
|
196
|
+
* const translate = { a: 1, b: 0, c: 0, d: 1, e: 100, f: 0 };
|
|
197
|
+
* const rotate = { a: 0, b: 1, c: -1, d: 0, e: 0, f: 0 }; // 90° ccw
|
|
198
|
+
* const combined = multiplyMatrix(translate, rotate);
|
|
199
|
+
* // Points are rotated, then translated
|
|
200
|
+
* ```
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```typescript
|
|
204
|
+
* // Combine scale and translation
|
|
205
|
+
* const scale2x: TransformationMatrix = {
|
|
206
|
+
* a: 2, b: 0, c: 0, d: 2, e: 0, f: 0
|
|
207
|
+
* };
|
|
208
|
+
* const translate: TransformationMatrix = {
|
|
209
|
+
* a: 1, b: 0, c: 0, d: 1, e: 100, f: 50
|
|
210
|
+
* };
|
|
211
|
+
*
|
|
212
|
+
* // Scale then translate
|
|
213
|
+
* const combined = multiplyMatrix(translate, scale2x);
|
|
214
|
+
* // Points are scaled by 2, then translated by (100, 50)
|
|
215
|
+
*
|
|
216
|
+
* // Chain multiple transformations
|
|
217
|
+
* const m = multiplyMatrix(
|
|
218
|
+
* multiplyMatrix(translate, rotate),
|
|
219
|
+
* scale
|
|
220
|
+
* );
|
|
221
|
+
* // Equivalent to: scale → rotate → translate
|
|
222
|
+
* ```
|
|
223
|
+
*
|
|
224
|
+
* @category Matrix
|
|
225
|
+
*/
|
|
51
226
|
export declare function multiplyMatrix(m1: TransformationMatrix, m2: TransformationMatrix): {
|
|
52
227
|
a: number;
|
|
53
228
|
b: number;
|
|
@@ -76,14 +251,42 @@ export declare function decomposeTRS(matrix: TransformationMatrix): {
|
|
|
76
251
|
};
|
|
77
252
|
};
|
|
78
253
|
/**
|
|
79
|
-
* Creates a transformation matrix from
|
|
254
|
+
* Creates a transformation matrix from Translation, Rotation, and Scale components.
|
|
255
|
+
* Inverse of {@link decomposeTRS}.
|
|
80
256
|
*
|
|
81
|
-
* @param translation - Translation vector
|
|
82
|
-
* @param rotation - Rotation in radians
|
|
83
|
-
* @param scale - Scale vector
|
|
84
|
-
* @returns Transformation matrix
|
|
257
|
+
* @param translation - Translation vector (tx, ty)
|
|
258
|
+
* @param rotation - Rotation angle in radians (counter-clockwise)
|
|
259
|
+
* @param scale - Scale vector (sx, sy)
|
|
260
|
+
* @returns Transformation matrix combining TRS
|
|
261
|
+
*
|
|
262
|
+
* @remarks
|
|
263
|
+
* Transformation order: Scale → Rotate → Translate
|
|
264
|
+
*
|
|
265
|
+
* The resulting matrix is in standard form compatible with Canvas/CSS/SVG.
|
|
266
|
+
* Applying this matrix transforms points as:
|
|
267
|
+
* 1. Scale by (sx, sy)
|
|
268
|
+
* 2. Rotate by θ radians
|
|
269
|
+
* 3. Translate by (tx, ty)
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ```typescript
|
|
273
|
+
* // Create a transform that scales 2x, rotates 45°, then moves to (100, 50)
|
|
274
|
+
* const matrix = createTRSMatrix(
|
|
275
|
+
* { x: 100, y: 50 }, // translation
|
|
276
|
+
* Math.PI / 4, // 45° rotation
|
|
277
|
+
* { x: 2, y: 2 } // 2x scale
|
|
278
|
+
* );
|
|
279
|
+
*
|
|
280
|
+
* ctx.setTransform(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);
|
|
281
|
+
* // Now drawing happens with scale→rotate→translate applied
|
|
282
|
+
*
|
|
283
|
+
* // Round-trip test
|
|
284
|
+
* const decomposed = decomposeTRS(matrix);
|
|
285
|
+
* // decomposed ≈ { translation: {x:100, y:50}, rotation: π/4, scale: {x:2, y:2} }
|
|
286
|
+
* ```
|
|
85
287
|
*
|
|
86
288
|
* @category Matrix
|
|
289
|
+
* @see {@link decomposeTRS} for extracting TRS from a matrix
|
|
87
290
|
*/
|
|
88
291
|
export declare function createTRSMatrix(translation: {
|
|
89
292
|
x: number;
|
|
@@ -1,7 +1,41 @@
|
|
|
1
1
|
import { Point } from "@ue-too/math";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Position boundaries for camera movement in world space.
|
|
4
|
+
* Allows optional constraints on x and y axes independently.
|
|
5
|
+
*
|
|
6
|
+
* @property min - Minimum position constraints (both x and y are optional)
|
|
7
|
+
* @property max - Maximum position constraints (both x and y are optional)
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* All coordinates are in world space. Each axis (x, y) can be:
|
|
11
|
+
* - Fully constrained: both min and max defined
|
|
12
|
+
* - Partially constrained: only min or max defined
|
|
13
|
+
* - Unconstrained: neither min nor max defined
|
|
14
|
+
*
|
|
15
|
+
* This allows for flexible boundary configurations like:
|
|
16
|
+
* - Horizontal-only boundaries (x constrained, y free)
|
|
17
|
+
* - Vertical-only boundaries (y constrained, x free)
|
|
18
|
+
* - One-sided boundaries (e.g., minimum x but no maximum)
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* // Fully constrained rectangular boundary
|
|
23
|
+
* const rect: Boundaries = {
|
|
24
|
+
* min: { x: -1000, y: -1000 },
|
|
25
|
+
* max: { x: 1000, y: 1000 }
|
|
26
|
+
* };
|
|
27
|
+
*
|
|
28
|
+
* // Horizontal constraints only
|
|
29
|
+
* const horizontal: Boundaries = {
|
|
30
|
+
* min: { x: -500 },
|
|
31
|
+
* max: { x: 500 }
|
|
32
|
+
* };
|
|
33
|
+
*
|
|
34
|
+
* // One-sided constraint (can't go below y=0)
|
|
35
|
+
* const floor: Boundaries = {
|
|
36
|
+
* min: { y: 0 }
|
|
37
|
+
* };
|
|
38
|
+
* ```
|
|
5
39
|
*
|
|
6
40
|
* @category Camera
|
|
7
41
|
*/
|
|
@@ -16,56 +50,260 @@ export type Boundaries = {
|
|
|
16
50
|
};
|
|
17
51
|
};
|
|
18
52
|
/**
|
|
19
|
-
*
|
|
53
|
+
* Checks if a point is within the specified boundaries.
|
|
54
|
+
*
|
|
55
|
+
* @param point - Point to check in world coordinates
|
|
56
|
+
* @param boundaries - Optional boundary constraints
|
|
57
|
+
* @returns True if point is within boundaries or no boundaries specified, false otherwise
|
|
58
|
+
*
|
|
59
|
+
* @remarks
|
|
60
|
+
* Returns true if:
|
|
61
|
+
* - No boundaries are defined (undefined)
|
|
62
|
+
* - Point satisfies all defined constraints
|
|
63
|
+
*
|
|
64
|
+
* Each axis is checked independently. A missing constraint on an axis means
|
|
65
|
+
* that axis is unbounded.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* const bounds: Boundaries = {
|
|
70
|
+
* min: { x: -100, y: -50 },
|
|
71
|
+
* max: { x: 100, y: 50 }
|
|
72
|
+
* };
|
|
73
|
+
*
|
|
74
|
+
* withinBoundaries({ x: 0, y: 0 }, bounds); // true (inside)
|
|
75
|
+
* withinBoundaries({ x: 150, y: 0 }, bounds); // false (x too large)
|
|
76
|
+
* withinBoundaries({ x: 0, y: -100 }, bounds); // false (y too small)
|
|
77
|
+
* withinBoundaries({ x: 100, y: 50 }, bounds); // true (on boundary)
|
|
78
|
+
* withinBoundaries({ x: 0, y: 0 }, undefined); // true (no bounds)
|
|
79
|
+
* ```
|
|
20
80
|
*
|
|
21
81
|
* @category Camera
|
|
22
82
|
*/
|
|
23
83
|
export declare function withinBoundaries(point: Point, boundaries: Boundaries | undefined): boolean;
|
|
24
84
|
/**
|
|
25
|
-
*
|
|
85
|
+
* Validates that boundaries are logically consistent.
|
|
86
|
+
*
|
|
87
|
+
* @param boundaries - The boundaries to validate
|
|
88
|
+
* @returns True if boundaries are valid or undefined, false if min >= max on any axis
|
|
89
|
+
*
|
|
90
|
+
* @remarks
|
|
91
|
+
* Returns false if:
|
|
92
|
+
* - On any axis, both min and max are defined AND min >= max
|
|
93
|
+
*
|
|
94
|
+
* Returns true if:
|
|
95
|
+
* - Boundaries are undefined
|
|
96
|
+
* - Only min or max is defined on an axis
|
|
97
|
+
* - Both are defined and min < max on all axes
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* isValidBoundaries({ min: { x: 0, y: 0 }, max: { x: 100, y: 100 } }); // true
|
|
102
|
+
* isValidBoundaries({ min: { x: 100 }, max: { x: 0 } }); // false (min > max)
|
|
103
|
+
* isValidBoundaries({ min: { x: 50, y: 50 }, max: { x: 50, y: 60 } }); // false (x min == max)
|
|
104
|
+
* isValidBoundaries({ min: { x: 0 } }); // true (partial)
|
|
105
|
+
* isValidBoundaries(undefined); // true
|
|
106
|
+
* ```
|
|
26
107
|
*
|
|
27
108
|
* @category Camera
|
|
28
109
|
*/
|
|
29
110
|
export declare function isValidBoundaries(boundaries: Boundaries | undefined): boolean;
|
|
30
111
|
/**
|
|
31
|
-
*
|
|
112
|
+
* Checks if boundaries have all four constraints (min/max for both x and y) defined.
|
|
113
|
+
*
|
|
114
|
+
* @param boundaries - The boundaries to check
|
|
115
|
+
* @returns True if all four constraints are defined, false otherwise
|
|
116
|
+
*
|
|
117
|
+
* @remarks
|
|
118
|
+
* Returns true only if boundaries define a complete rectangular region:
|
|
119
|
+
* - min.x, min.y, max.x, and max.y are all defined
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* boundariesFullyDefined({
|
|
124
|
+
* min: { x: 0, y: 0 },
|
|
125
|
+
* max: { x: 100, y: 100 }
|
|
126
|
+
* }); // true
|
|
127
|
+
*
|
|
128
|
+
* boundariesFullyDefined({
|
|
129
|
+
* min: { x: 0, y: 0 },
|
|
130
|
+
* max: { x: 100 } // missing max.y
|
|
131
|
+
* }); // false
|
|
132
|
+
*
|
|
133
|
+
* boundariesFullyDefined({ min: { x: 0 } }); // false
|
|
134
|
+
* boundariesFullyDefined(undefined); // false
|
|
135
|
+
* ```
|
|
32
136
|
*
|
|
33
137
|
* @category Camera
|
|
34
138
|
*/
|
|
35
139
|
export declare function boundariesFullyDefined(boundaries: Boundaries | undefined): boolean;
|
|
36
140
|
/**
|
|
37
|
-
*
|
|
141
|
+
* Clamps a point to stay within specified boundaries.
|
|
142
|
+
*
|
|
143
|
+
* @param point - Point to clamp in world coordinates
|
|
144
|
+
* @param boundaries - Optional boundary constraints
|
|
145
|
+
* @returns Clamped point, or original if already within bounds or no boundaries
|
|
146
|
+
*
|
|
147
|
+
* @remarks
|
|
148
|
+
* Each axis is clamped independently:
|
|
149
|
+
* - If a min constraint exists on an axis, ensures point >= min
|
|
150
|
+
* - If a max constraint exists on an axis, ensures point <= max
|
|
151
|
+
* - If no constraint exists on an axis, that axis is unchanged
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```typescript
|
|
155
|
+
* const bounds: Boundaries = {
|
|
156
|
+
* min: { x: -100, y: -50 },
|
|
157
|
+
* max: { x: 100, y: 50 }
|
|
158
|
+
* };
|
|
159
|
+
*
|
|
160
|
+
* clampPoint({ x: 0, y: 0 }, bounds); // { x: 0, y: 0 } (inside)
|
|
161
|
+
* clampPoint({ x: 150, y: 0 }, bounds); // { x: 100, y: 0 } (clamped x)
|
|
162
|
+
* clampPoint({ x: 0, y: -100 }, bounds); // { x: 0, y: -50 } (clamped y)
|
|
163
|
+
* clampPoint({ x: 200, y: -200 }, bounds); // { x: 100, y: -50 } (both clamped)
|
|
164
|
+
* clampPoint({ x: 0, y: 0 }, undefined); // { x: 0, y: 0 } (no bounds)
|
|
165
|
+
* ```
|
|
38
166
|
*
|
|
39
167
|
* @category Camera
|
|
40
168
|
*/
|
|
41
169
|
export declare function clampPoint(point: Point, boundaries: Boundaries | undefined): Point;
|
|
42
170
|
/**
|
|
43
|
-
*
|
|
171
|
+
* Calculates the width (x-axis span) of the boundaries.
|
|
172
|
+
*
|
|
173
|
+
* @param boundaries - The boundaries to measure
|
|
174
|
+
* @returns Width in world units, or undefined if x boundaries are not fully defined
|
|
175
|
+
*
|
|
176
|
+
* @remarks
|
|
177
|
+
* Returns undefined if boundaries don't have both min.x and max.x defined.
|
|
178
|
+
* Result is always non-negative for valid boundaries (max.x - min.x).
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```typescript
|
|
182
|
+
* translationWidthOf({
|
|
183
|
+
* min: { x: -100, y: -50 },
|
|
184
|
+
* max: { x: 100, y: 50 }
|
|
185
|
+
* }); // 200
|
|
186
|
+
*
|
|
187
|
+
* translationWidthOf({ min: { x: 0 } }); // undefined (no max.x)
|
|
188
|
+
* translationWidthOf(undefined); // undefined
|
|
189
|
+
* ```
|
|
44
190
|
*
|
|
45
191
|
* @category Camera
|
|
46
192
|
*/
|
|
47
193
|
export declare function translationWidthOf(boundaries: Boundaries | undefined): number | undefined;
|
|
48
194
|
/**
|
|
49
|
-
*
|
|
195
|
+
* Calculates half the width (x-axis half-span) of the boundaries.
|
|
196
|
+
*
|
|
197
|
+
* @param boundaries - The boundaries to measure
|
|
198
|
+
* @returns Half-width in world units, or undefined if x boundaries are not fully defined
|
|
199
|
+
*
|
|
200
|
+
* @remarks
|
|
201
|
+
* Useful for calculating radius or offset from center for x-axis.
|
|
202
|
+
* Equivalent to `translationWidthOf(boundaries) / 2`.
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* halfTranslationWidthOf({
|
|
207
|
+
* min: { x: -100, y: -50 },
|
|
208
|
+
* max: { x: 100, y: 50 }
|
|
209
|
+
* }); // 100
|
|
210
|
+
* ```
|
|
50
211
|
*
|
|
51
212
|
* @category Camera
|
|
52
213
|
*/
|
|
53
214
|
export declare function halfTranslationWidthOf(boundaries: Boundaries | undefined): number | undefined;
|
|
54
215
|
/**
|
|
55
|
-
*
|
|
216
|
+
* Calculates the height (y-axis span) of the boundaries.
|
|
217
|
+
*
|
|
218
|
+
* @param boundaries - The boundaries to measure
|
|
219
|
+
* @returns Height in world units, or undefined if y boundaries are not fully defined
|
|
220
|
+
*
|
|
221
|
+
* @remarks
|
|
222
|
+
* Returns undefined if boundaries don't have both min.y and max.y defined.
|
|
223
|
+
* Result is always non-negative for valid boundaries (max.y - min.y).
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```typescript
|
|
227
|
+
* translationHeightOf({
|
|
228
|
+
* min: { x: -100, y: -50 },
|
|
229
|
+
* max: { x: 100, y: 50 }
|
|
230
|
+
* }); // 100
|
|
231
|
+
*
|
|
232
|
+
* translationHeightOf({ min: { y: 0 } }); // undefined (no max.y)
|
|
233
|
+
* translationHeightOf(undefined); // undefined
|
|
234
|
+
* ```
|
|
56
235
|
*
|
|
57
236
|
* @category Camera
|
|
58
237
|
*/
|
|
59
238
|
export declare function translationHeightOf(boundaries: Boundaries | undefined): number | undefined;
|
|
60
239
|
/**
|
|
61
|
-
*
|
|
240
|
+
* Calculates half the height (y-axis half-span) of the boundaries.
|
|
241
|
+
*
|
|
242
|
+
* @param boundaries - The boundaries to measure
|
|
243
|
+
* @returns Half-height in world units, or undefined if y boundaries are not fully defined
|
|
244
|
+
*
|
|
245
|
+
* @remarks
|
|
246
|
+
* Useful for calculating radius or offset from center for y-axis.
|
|
247
|
+
* Equivalent to `translationHeightOf(boundaries) / 2`.
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```typescript
|
|
251
|
+
* halfTranslationHeightOf({
|
|
252
|
+
* min: { x: -100, y: -50 },
|
|
253
|
+
* max: { x: 100, y: 50 }
|
|
254
|
+
* }); // 50
|
|
255
|
+
* ```
|
|
62
256
|
*
|
|
63
257
|
* @category Camera
|
|
64
258
|
*/
|
|
65
259
|
export declare function halfTranslationHeightOf(boundaries: Boundaries | undefined): number | undefined;
|
|
66
260
|
/**
|
|
67
|
-
*
|
|
261
|
+
* Clamps camera position to ensure the entire viewport stays within boundaries.
|
|
262
|
+
* More restrictive than {@link clampPoint} as it considers viewport size and rotation.
|
|
263
|
+
*
|
|
264
|
+
* @param point - Proposed camera position in world coordinates
|
|
265
|
+
* @param viewPortWidth - Width of the viewport in CSS pixels
|
|
266
|
+
* @param viewPortHeight - Height of the viewport in CSS pixels
|
|
267
|
+
* @param boundaries - Optional boundary constraints in world space
|
|
268
|
+
* @param cameraZoomLevel - Current camera zoom level
|
|
269
|
+
* @param cameraRotation - Current camera rotation in radians
|
|
270
|
+
* @returns Adjusted camera position that keeps entire viewport within boundaries
|
|
271
|
+
*
|
|
272
|
+
* @remarks
|
|
273
|
+
* This function ensures no part of the viewport extends outside the boundaries.
|
|
274
|
+
* It accounts for:
|
|
275
|
+
* - Viewport dimensions (width/height)
|
|
276
|
+
* - Camera rotation (viewport corners rotate around camera center)
|
|
277
|
+
* - Zoom level (affects world-space size of viewport)
|
|
278
|
+
*
|
|
279
|
+
* The algorithm:
|
|
280
|
+
* 1. Calculates all four viewport corners in world space
|
|
281
|
+
* 2. Clamps each corner to boundaries
|
|
282
|
+
* 3. Finds the maximum displacement needed across all corners
|
|
283
|
+
* 4. Adjusts camera position by that displacement
|
|
284
|
+
*
|
|
285
|
+
* Use this for "edge-stop" behavior where viewport cannot scroll past boundaries.
|
|
286
|
+
* For "center-stop" behavior, use {@link clampPoint} instead.
|
|
287
|
+
*
|
|
288
|
+
* @example
|
|
289
|
+
* ```typescript
|
|
290
|
+
* const bounds: Boundaries = {
|
|
291
|
+
* min: { x: 0, y: 0 },
|
|
292
|
+
* max: { x: 1000, y: 1000 }
|
|
293
|
+
* };
|
|
294
|
+
*
|
|
295
|
+
* // Camera at center of bounds, viewport extends outside
|
|
296
|
+
* const adjusted = clampPointEntireViewPort(
|
|
297
|
+
* { x: 100, y: 100 }, // camera position
|
|
298
|
+
* 800, 600, // viewport size
|
|
299
|
+
* bounds,
|
|
300
|
+
* 1.0, // zoom
|
|
301
|
+
* 0 // rotation
|
|
302
|
+
* );
|
|
303
|
+
* // Returns position that prevents viewport from exceeding bounds
|
|
304
|
+
* ```
|
|
68
305
|
*
|
|
69
306
|
* @category Camera
|
|
307
|
+
* @see {@link clampPoint} for clamping camera center only
|
|
70
308
|
*/
|
|
71
309
|
export declare function clampPointEntireViewPort(point: Point, viewPortWidth: number, viewPortHeight: number, boundaries: Boundaries | undefined, cameraZoomLevel: number, cameraRotation: number): Point;
|