@semio/utils 0.0.0 → 0.1.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/dist/index.d.mts +482 -69
- package/dist/index.d.ts +482 -69
- package/dist/index.js +573 -131
- package/dist/index.mjs +535 -126
- package/package.json +18 -9
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
+
import { Context, ComponentType, ReactNode } from 'react';
|
|
2
3
|
import * as zustand from 'zustand';
|
|
4
|
+
import { OrthographicCamera, PerspectiveCamera } from 'three';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Logs a message to the console.
|
|
6
8
|
*
|
|
7
9
|
* @param value - The message to be logged
|
|
8
|
-
*
|
|
9
|
-
* @remarks
|
|
10
|
-
* This function temporarily disables ESLint console warnings for testing purposes.
|
|
11
10
|
*/
|
|
12
11
|
declare function log(value: string): void;
|
|
13
12
|
|
|
@@ -56,38 +55,56 @@ declare function getId(lookup: string): string;
|
|
|
56
55
|
* Time representation in milliseconds.
|
|
57
56
|
*/
|
|
58
57
|
type RawTime = number;
|
|
58
|
+
declare enum PlayerDirection {
|
|
59
|
+
Reverse = "reverse",
|
|
60
|
+
Forward = "forward"
|
|
61
|
+
}
|
|
59
62
|
/**
|
|
60
63
|
* A timer implementation for managing animation playback.
|
|
61
64
|
*
|
|
62
|
-
* The timer operates
|
|
65
|
+
* The timer operates in milliseconds, where:
|
|
63
66
|
* - 0 represents the start of the animation
|
|
64
|
-
* -
|
|
67
|
+
* - duration (in ms) represents the end of the animation
|
|
68
|
+
*
|
|
69
|
+
* Fields prefixed with `_` (e.g. `_previousTime`, `_currentDirection`,
|
|
70
|
+
* `_bounced`, `_enteredBounds`) are internal bookkeeping for the
|
|
71
|
+
* `updated()` tick function and should not be read by external
|
|
72
|
+
* consumers. They're on the public type because immutable spread-and-
|
|
73
|
+
* return pattern means every `withX` helper must roundtrip them.
|
|
65
74
|
*
|
|
66
75
|
* @property running - Whether the timer is actively running
|
|
67
|
-
* @property _previousTime -
|
|
68
|
-
* @property _currentTime -
|
|
69
|
-
* @property stamp - Current
|
|
70
|
-
* @property
|
|
71
|
-
* @property
|
|
72
|
-
* @property
|
|
73
|
-
* @property
|
|
74
|
-
* @property
|
|
76
|
+
* @property _previousTime - INTERNAL. Last update time in ms.
|
|
77
|
+
* @property _currentTime - INTERNAL. Current update time in ms.
|
|
78
|
+
* @property stamp - Current time position in milliseconds
|
|
79
|
+
* @property speed - Playback speed multiplier (always positive)
|
|
80
|
+
* @property direction - Initial playback direction (PlayerDirection.Forward or PlayerDirection.Reverse)
|
|
81
|
+
* @property _currentDirection - INTERNAL. Actual movement direction during bouncing.
|
|
82
|
+
* @property _bounced - INTERNAL. Whether the player has already bounced this run.
|
|
83
|
+
* @property _enteredBounds - INTERNAL. Whether the player has crossed into bounds at least once.
|
|
84
|
+
* @property bounds - Constrains playback to a [start, end] range in milliseconds
|
|
85
|
+
* @property bounce - Whether to reverse direction when reaching bounds
|
|
86
|
+
* @property looping - Whether to continue playing after reaching bounds
|
|
87
|
+
* @property duration - Total animation duration in milliseconds (used for playback stepping)
|
|
75
88
|
*/
|
|
76
89
|
interface Player {
|
|
77
90
|
running: boolean;
|
|
78
91
|
_previousTime: RawTime;
|
|
79
92
|
_currentTime: RawTime;
|
|
80
93
|
stamp: number;
|
|
81
|
-
|
|
94
|
+
speed: number;
|
|
95
|
+
direction: PlayerDirection;
|
|
96
|
+
_currentDirection: PlayerDirection;
|
|
97
|
+
_bounced: boolean;
|
|
98
|
+
_enteredBounds: boolean;
|
|
82
99
|
bounds: [number, number];
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
bounce: boolean;
|
|
101
|
+
looping: boolean;
|
|
85
102
|
duration: number;
|
|
86
103
|
}
|
|
87
104
|
/**
|
|
88
105
|
* Creates a copy of the provided timer, but updated with the new timestamp.
|
|
89
106
|
* @param timer - the timer to be updated
|
|
90
|
-
* @param stamp - the new timestamp in
|
|
107
|
+
* @param stamp - the new timestamp in milliseconds
|
|
91
108
|
* @returns the updated timer
|
|
92
109
|
*/
|
|
93
110
|
declare function reset(player: Player, stamp?: number): Player;
|
|
@@ -102,38 +119,34 @@ declare function now(): RawTime;
|
|
|
102
119
|
* @param timer - the timer to be updated
|
|
103
120
|
* @returns the updated timer
|
|
104
121
|
*/
|
|
105
|
-
declare function
|
|
122
|
+
declare function updated(player: Player, coldStart: boolean): Player;
|
|
106
123
|
/**
|
|
107
124
|
* Sets the bounds for the player.
|
|
108
125
|
* @param player - the player to be updated
|
|
109
|
-
* @param bounds - the new bounds in
|
|
126
|
+
* @param bounds - the new bounds in milliseconds [start, end]
|
|
110
127
|
* @returns the updated player
|
|
111
128
|
*/
|
|
112
|
-
declare function
|
|
129
|
+
declare function withBounds(player: Player, bounds: [number, number]): Player;
|
|
113
130
|
/**
|
|
114
|
-
*
|
|
115
|
-
* @param player - the player to be updated
|
|
116
|
-
* @param viewport - the new viewport in the range [0, 1]
|
|
117
|
-
* @returns the updated player
|
|
118
|
-
*/
|
|
119
|
-
declare function setViewport(player: Player, viewport: [number, number]): Player;
|
|
120
|
-
/**
|
|
121
|
-
* Creates a copy of the provided timer, but updated with a timescale based on the speed provided.
|
|
131
|
+
* Creates a copy of the provided timer, but updated with speed and direction.
|
|
122
132
|
* @param timer - the timer to be updated
|
|
123
|
-
* @param speed - the speed of playback desired (defaults to
|
|
133
|
+
* @param speed - the speed of playback desired (defaults to current speed)
|
|
134
|
+
* @param direction - the direction of playback desired (defaults to current direction)
|
|
124
135
|
* @returns the updated timer
|
|
125
136
|
*/
|
|
126
|
-
declare function play(player: Player, speed?: number): Player;
|
|
137
|
+
declare function play(player: Player, speed?: number, direction?: PlayerDirection.Forward | PlayerDirection.Reverse): Player;
|
|
127
138
|
/**
|
|
128
|
-
* Creates a copy of the provided timer, but
|
|
139
|
+
* Creates a copy of the provided timer, but paused
|
|
129
140
|
* @param timer - the timer to be updated
|
|
130
141
|
* @returns the updated timer
|
|
131
142
|
*/
|
|
132
143
|
declare function pause(player: Player): Player;
|
|
133
144
|
/**
|
|
134
|
-
* Returns the provided player,
|
|
145
|
+
* Returns the provided player, reset to the given stamp.
|
|
146
|
+
* Pure stamp-set; viewport-follow is handled separately by the
|
|
147
|
+
* viewport-follow subscription.
|
|
135
148
|
* @param player - the player to be updated
|
|
136
|
-
* @param stamp - the new stamp
|
|
149
|
+
* @param stamp - the new stamp
|
|
137
150
|
* @returns the updated player
|
|
138
151
|
*/
|
|
139
152
|
declare function seek(player: Player, stamp: number): Player;
|
|
@@ -143,21 +156,55 @@ declare function seek(player: Player, stamp: number): Player;
|
|
|
143
156
|
* @param duration - the new duration
|
|
144
157
|
* @returns the updated player
|
|
145
158
|
*/
|
|
146
|
-
declare function
|
|
159
|
+
declare function withDuration(player: Player, duration: number): Player;
|
|
147
160
|
/**
|
|
148
161
|
* Creates a new Player instance with default values.
|
|
149
162
|
*
|
|
150
163
|
* @returns A new Player instance initialized with:
|
|
151
164
|
* - Not running
|
|
152
165
|
* - Current timestamp
|
|
153
|
-
* - Zero stamp position
|
|
154
|
-
* -
|
|
155
|
-
* -
|
|
156
|
-
* -
|
|
157
|
-
* -
|
|
158
|
-
* -
|
|
166
|
+
* - Zero stamp position (0ms)
|
|
167
|
+
* - Normal speed (1x)
|
|
168
|
+
* - Forward direction
|
|
169
|
+
* - Default bounds [0, 5000] ms
|
|
170
|
+
* - Looping enabled, bounce disabled
|
|
171
|
+
* - 5000ms duration
|
|
159
172
|
*/
|
|
160
173
|
declare function newPlayer(): Player;
|
|
174
|
+
/**
|
|
175
|
+
* Sets the playback speed without affecting direction.
|
|
176
|
+
* @param player - the player to be updated
|
|
177
|
+
* @param speed - the new speed (must be positive)
|
|
178
|
+
* @returns the updated player
|
|
179
|
+
*/
|
|
180
|
+
declare function withSpeed(player: Player, speed: number): Player;
|
|
181
|
+
/**
|
|
182
|
+
* Sets the playback direction without affecting speed.
|
|
183
|
+
* @param player - the player to be updated
|
|
184
|
+
* @param direction - the new direction
|
|
185
|
+
* @returns the updated player
|
|
186
|
+
*/
|
|
187
|
+
declare function withDirection(player: Player, direction: PlayerDirection.Forward | PlayerDirection.Reverse): Player;
|
|
188
|
+
/**
|
|
189
|
+
* Reverses the current playback direction.
|
|
190
|
+
* @param player - the player to be updated
|
|
191
|
+
* @returns the updated player
|
|
192
|
+
*/
|
|
193
|
+
declare function reversed(player: Player): Player;
|
|
194
|
+
/**
|
|
195
|
+
* Sets the bounce behavior for the player.
|
|
196
|
+
* @param player - the player to be updated
|
|
197
|
+
* @param bounce - whether to bounce at boundaries
|
|
198
|
+
* @returns the updated player
|
|
199
|
+
*/
|
|
200
|
+
declare function withBounce(player: Player, bounce: boolean): Player;
|
|
201
|
+
/**
|
|
202
|
+
* Sets the looping behavior for the player.
|
|
203
|
+
* @param player - the player to be updated
|
|
204
|
+
* @param looping - whether to loop at boundaries
|
|
205
|
+
* @returns the updated player
|
|
206
|
+
*/
|
|
207
|
+
declare function withLooping(player: Player, looping: boolean): Player;
|
|
161
208
|
|
|
162
209
|
/**
|
|
163
210
|
* Core data structure for player state
|
|
@@ -172,12 +219,16 @@ interface PlayerData {
|
|
|
172
219
|
interface PlayerActions {
|
|
173
220
|
/** Updates the total duration of the animation */
|
|
174
221
|
updateDuration: (duration: number) => void;
|
|
175
|
-
/** Updates the playback speed
|
|
176
|
-
|
|
222
|
+
/** Updates the playback speed */
|
|
223
|
+
updateSpeed: (speed: number) => void;
|
|
224
|
+
/** Updates the playback direction */
|
|
225
|
+
updateDirection: (direction: PlayerDirection) => void;
|
|
226
|
+
/** Reverses the current playback direction */
|
|
227
|
+
reverseDirection: () => void;
|
|
177
228
|
/** Resets the player to initial state or specified time */
|
|
178
229
|
resetPlayer: (time?: number) => void;
|
|
179
230
|
/** Plays the animation */
|
|
180
|
-
playPlayer: (speed?: number) => void;
|
|
231
|
+
playPlayer: (speed?: number, direction?: PlayerDirection) => void;
|
|
181
232
|
/** Pauses the animation */
|
|
182
233
|
pausePlayer: () => void;
|
|
183
234
|
/** Updates the timer */
|
|
@@ -186,28 +237,27 @@ interface PlayerActions {
|
|
|
186
237
|
updatePlayerBounds: (start: number, end: number) => void;
|
|
187
238
|
/** Updates one bound of the player */
|
|
188
239
|
updatePlayerBound: (bound: "start" | "end", time?: number) => void;
|
|
189
|
-
/**
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
|
|
193
|
-
/** Updates one bound of the player viewport */
|
|
194
|
-
updatePlayerViewportBound: (bound: "start" | "end", time: number) => void;
|
|
240
|
+
/** Update the player bounce setting */
|
|
241
|
+
updateBounce: (bounce: boolean) => void;
|
|
242
|
+
/** Update the player looping setting */
|
|
243
|
+
updateLooping: (looping: boolean) => void;
|
|
195
244
|
}
|
|
196
|
-
type PlayerStoreSetter = (partial: (PlayerData & PlayerActions) | Partial<PlayerData & PlayerActions> | ((state: PlayerData & PlayerActions) => (PlayerData & PlayerActions) | Partial<PlayerData & PlayerActions>), replace?: false
|
|
245
|
+
type PlayerStoreSetter = (partial: (PlayerData & PlayerActions) | Partial<PlayerData & PlayerActions> | ((state: PlayerData & PlayerActions) => (PlayerData & PlayerActions) | Partial<PlayerData & PlayerActions>), replace?: false) => void;
|
|
197
246
|
type PlayerStoreGetter = () => PlayerData & PlayerActions;
|
|
198
247
|
declare const PlayerSlice: (set: PlayerStoreSetter) => {
|
|
199
248
|
player: Player;
|
|
200
249
|
updateDuration: (duration: number) => void;
|
|
201
|
-
|
|
250
|
+
updateSpeed: (speed: number) => void;
|
|
251
|
+
updateDirection: (direction: PlayerDirection) => void;
|
|
252
|
+
reverseDirection: () => void;
|
|
202
253
|
resetPlayer: (time?: number) => void;
|
|
203
|
-
playPlayer: (speed?: number) => void;
|
|
254
|
+
playPlayer: (speed?: number, direction?: PlayerDirection) => void;
|
|
204
255
|
pausePlayer: () => void;
|
|
205
256
|
updatePlayer: (coldStart?: boolean) => void;
|
|
206
257
|
updatePlayerBounds: (start: number, end: number) => void;
|
|
207
258
|
updatePlayerBound: (bound: "start" | "end", time?: number) => void;
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
updatePlayerViewportBound: (bound: "start" | "end", time: number) => void;
|
|
259
|
+
updateBounce: (bounce: boolean) => void;
|
|
260
|
+
updateLooping: (looping: boolean) => void;
|
|
211
261
|
};
|
|
212
262
|
declare const usePlayerStore: zustand.UseBoundStore<Omit<zustand.StoreApi<PlayerData & PlayerActions>, "subscribe"> & {
|
|
213
263
|
subscribe: {
|
|
@@ -242,9 +292,9 @@ interface RawVector2 {
|
|
|
242
292
|
y: number;
|
|
243
293
|
}
|
|
244
294
|
interface RawEuler {
|
|
245
|
-
|
|
295
|
+
r: number;
|
|
296
|
+
p: number;
|
|
246
297
|
y: number;
|
|
247
|
-
z: number;
|
|
248
298
|
}
|
|
249
299
|
interface RawRGB {
|
|
250
300
|
r: number;
|
|
@@ -264,7 +314,33 @@ interface AnimatablePubInfo {
|
|
|
264
314
|
output: string;
|
|
265
315
|
color?: string;
|
|
266
316
|
}
|
|
267
|
-
|
|
317
|
+
declare enum AnimatableGroupType {
|
|
318
|
+
Vector2 = "vector2",
|
|
319
|
+
Vector3 = "vector3",
|
|
320
|
+
Euler = "euler",
|
|
321
|
+
RGB = "rgb",
|
|
322
|
+
HSL = "hsl",
|
|
323
|
+
Group = "group",
|
|
324
|
+
/** Entity-level group (spans all instances for one entity/namespace). */
|
|
325
|
+
Entity = "entity",
|
|
326
|
+
/** Instance-level group (one animation instance within an entity). */
|
|
327
|
+
Instance = "instance"
|
|
328
|
+
}
|
|
329
|
+
interface AnimatableGroupInfo {
|
|
330
|
+
/** Stable group UUID used to associate related simple animatables. */
|
|
331
|
+
id: string;
|
|
332
|
+
/** Composite group type for editor grouping semantics. */
|
|
333
|
+
type: AnimatableGroupType;
|
|
334
|
+
/** Optional axis label (x/y/z or r/p/y) for disambiguation. */
|
|
335
|
+
axis?: string;
|
|
336
|
+
/** Optional ordering hint within the group. */
|
|
337
|
+
order?: number;
|
|
338
|
+
}
|
|
339
|
+
type AnimatableValue = AnimatableBoolean | AnimatableNumber | AnimatableString;
|
|
340
|
+
/**
|
|
341
|
+
* @deprecated Complex animatables should be flattened into scalar values.
|
|
342
|
+
*/
|
|
343
|
+
type DeprecatedComplexAnimatableValue = AnimatableVector3 | AnimatableVector2 | AnimatableEuler | AnimatableColor;
|
|
268
344
|
/**
|
|
269
345
|
* A specification for an animated numerical value
|
|
270
346
|
*
|
|
@@ -284,6 +360,7 @@ interface AnimatableBoolean {
|
|
|
284
360
|
frequency?: number;
|
|
285
361
|
};
|
|
286
362
|
pub?: AnimatablePubInfo;
|
|
363
|
+
group?: AnimatableGroupInfo;
|
|
287
364
|
}
|
|
288
365
|
/**
|
|
289
366
|
* A specification for an animated numerical value
|
|
@@ -307,6 +384,7 @@ interface AnimatableNumber {
|
|
|
307
384
|
velocity?: number;
|
|
308
385
|
};
|
|
309
386
|
pub?: AnimatablePubInfo;
|
|
387
|
+
group?: AnimatableGroupInfo;
|
|
310
388
|
}
|
|
311
389
|
/**
|
|
312
390
|
* A specification for an animated string value
|
|
@@ -327,6 +405,7 @@ interface AnimatableString {
|
|
|
327
405
|
length?: number;
|
|
328
406
|
};
|
|
329
407
|
pub?: AnimatablePubInfo;
|
|
408
|
+
group?: AnimatableGroupInfo;
|
|
330
409
|
}
|
|
331
410
|
/**
|
|
332
411
|
* A specification for an animated 3-vector value
|
|
@@ -425,6 +504,15 @@ declare function instanceOfRawEuler(object: any): object is RawEuler;
|
|
|
425
504
|
declare function instanceOfRawColor(object: any): object is RawColor;
|
|
426
505
|
declare function instanceOfRawRGB(object: any): object is RawRGB;
|
|
427
506
|
declare function instanceOfRawHSL(object: any): object is RawHSL;
|
|
507
|
+
/**
|
|
508
|
+
* Logs a console warning when a feature callback receives a value of an unexpected type.
|
|
509
|
+
* Use this in `useFeatures` callbacks to surface data-flow issues early.
|
|
510
|
+
*
|
|
511
|
+
* @param feature - The feature key (e.g. "translation.x", "jointValue").
|
|
512
|
+
* @param expected - Human-readable description of the expected type(s) (e.g. "number", "number | string").
|
|
513
|
+
* @param value - The actual value received.
|
|
514
|
+
*/
|
|
515
|
+
declare function warnUnexpectedFeatureValue(feature: string, expected: string, value: unknown): void;
|
|
428
516
|
declare function isRawObject(value: any): boolean;
|
|
429
517
|
|
|
430
518
|
/**
|
|
@@ -506,14 +594,13 @@ declare function getHexagonPath(x: number, y: number, size: number, height: numb
|
|
|
506
594
|
declare function getDegenerateHexagonPath(x: number, y: number, size: number, height: number): string;
|
|
507
595
|
|
|
508
596
|
/**
|
|
509
|
-
*
|
|
510
|
-
* and returns the closest frame as a percentage of the whole animation's duration.
|
|
597
|
+
* Snaps a timestamp in milliseconds to the nearest frame boundary.
|
|
511
598
|
*
|
|
512
|
-
* @param
|
|
513
|
-
* @param
|
|
514
|
-
* @returns The
|
|
599
|
+
* @param stampMs - The timestamp in milliseconds.
|
|
600
|
+
* @param framerate - The framerate (frames per second).
|
|
601
|
+
* @returns The timestamp snapped to the nearest frame boundary in milliseconds.
|
|
515
602
|
*/
|
|
516
|
-
declare function closestFrame(
|
|
603
|
+
declare function closestFrame(stampMs: number, framerate: number): number;
|
|
517
604
|
|
|
518
605
|
/**
|
|
519
606
|
* Converts an angle from radians to degrees.
|
|
@@ -604,6 +691,44 @@ declare function altColor(color: string, factor: number): string;
|
|
|
604
691
|
declare function hexToRgbArray(color: string): [number, number, number];
|
|
605
692
|
declare function rawRGBToHex({ r, g, b }: RawRGB): string;
|
|
606
693
|
declare function rawHSLToHex({ h, s, l }: RawHSL): string;
|
|
694
|
+
declare function randomHexString(constrainLuminosity?: number, constrainSaturation?: number): string;
|
|
695
|
+
/**
|
|
696
|
+
* Compute normalized chroma (0..1) from an RGB tuple.
|
|
697
|
+
* - 0 means perfectly gray
|
|
698
|
+
* - 1 means maximum colorfulness
|
|
699
|
+
*/
|
|
700
|
+
declare function rgbChroma([r, g, b]: [number, number, number]): number;
|
|
701
|
+
/**
|
|
702
|
+
* Compute lightness (0..1) from an RGB tuple using (max+min)/2.
|
|
703
|
+
* - 0 is black
|
|
704
|
+
* - 1 is white
|
|
705
|
+
*/
|
|
706
|
+
declare function rgbLightness([r, g, b]: [number, number, number]): number;
|
|
707
|
+
/**
|
|
708
|
+
* Compute chroma from any CSS color string.
|
|
709
|
+
*/
|
|
710
|
+
declare function colorChroma(color: string): number;
|
|
711
|
+
/**
|
|
712
|
+
* Compute lightness from any CSS color string.
|
|
713
|
+
*/
|
|
714
|
+
declare function colorLightness(color: string): number;
|
|
715
|
+
interface BlendHeuristicOptions {
|
|
716
|
+
chromaCutoff?: number;
|
|
717
|
+
minLightness?: number;
|
|
718
|
+
maxLightness?: number;
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Decide whether mix-blend-difference is likely to improve contrast for a given color.
|
|
722
|
+
* Disables blending for near-neutral, mid-lightness colors (e.g., #737373),
|
|
723
|
+
* where difference blending tends to reduce contrast.
|
|
724
|
+
*
|
|
725
|
+
* Returns false for undefined/unparseable colors as a safe default.
|
|
726
|
+
*/
|
|
727
|
+
declare function shouldUseBlendForLabelColor(color?: string | null, opts?: BlendHeuristicOptions): boolean;
|
|
728
|
+
/**
|
|
729
|
+
* Convenience helper to detect a near-neutral, mid-lightness color.
|
|
730
|
+
*/
|
|
731
|
+
declare function isNearNeutralMid(color: string, opts?: BlendHeuristicOptions): boolean;
|
|
607
732
|
|
|
608
733
|
/**
|
|
609
734
|
* Creates a memoized selector function that only updates when the selected value
|
|
@@ -780,6 +905,71 @@ declare function rotationMatrixToAngle(R: number[][]): number;
|
|
|
780
905
|
* ```
|
|
781
906
|
*/
|
|
782
907
|
declare function angularDistance(euler1: [number, number, number], euler2: [number, number, number]): number;
|
|
908
|
+
/**
|
|
909
|
+
* Converts Euler angles (ZYX order) to a quaternion.
|
|
910
|
+
*
|
|
911
|
+
* @param euler - Array of three numbers representing rotation angles in radians [z, y, x]
|
|
912
|
+
* @returns A quaternion as [w, x, y, z]
|
|
913
|
+
*/
|
|
914
|
+
declare function eulerToQuaternion(euler: [number, number, number]): [number, number, number, number];
|
|
915
|
+
/**
|
|
916
|
+
* Converts a quaternion to Euler angles (ZYX order).
|
|
917
|
+
*
|
|
918
|
+
* @param q - A quaternion as [w, x, y, z]
|
|
919
|
+
* @returns Euler angles as [z, y, x] in radians
|
|
920
|
+
*/
|
|
921
|
+
declare function quaternionToEuler(q: [number, number, number, number]): [number, number, number];
|
|
922
|
+
/**
|
|
923
|
+
* Multiplies two quaternions.
|
|
924
|
+
*
|
|
925
|
+
* @param q1 - First quaternion as [w, x, y, z]
|
|
926
|
+
* @param q2 - Second quaternion as [w, x, y, z]
|
|
927
|
+
* @returns The product quaternion as [w, x, y, z]
|
|
928
|
+
*/
|
|
929
|
+
declare function quaternionMultiply(q1: [number, number, number, number], q2: [number, number, number, number]): [number, number, number, number];
|
|
930
|
+
/**
|
|
931
|
+
* Calculates the conjugate of a quaternion (inverse for unit quaternions).
|
|
932
|
+
*
|
|
933
|
+
* @param q - A quaternion as [w, x, y, z]
|
|
934
|
+
* @returns The conjugate quaternion as [w, -x, -y, -z]
|
|
935
|
+
*/
|
|
936
|
+
declare function quaternionConjugate(q: [number, number, number, number]): [number, number, number, number];
|
|
937
|
+
/**
|
|
938
|
+
* Performs spherical linear interpolation between two quaternions.
|
|
939
|
+
*
|
|
940
|
+
* @param q1 - First quaternion as [w, x, y, z]
|
|
941
|
+
* @param q2 - Second quaternion as [w, x, y, z]
|
|
942
|
+
* @param t - Interpolation factor. Values between 0-1 interpolate, outside this range extrapolate.
|
|
943
|
+
* t=0 returns q1, t=1 returns q2, t<0 extrapolates backwards, t>1 extrapolates forwards.
|
|
944
|
+
* @returns The interpolated/extrapolated quaternion as [w, x, y, z]
|
|
945
|
+
*/
|
|
946
|
+
declare function quaternionSlerp(q1: [number, number, number, number], q2: [number, number, number, number], t: number): [number, number, number, number];
|
|
947
|
+
/**
|
|
948
|
+
* Performs spherical linear interpolation between two Euler angles.
|
|
949
|
+
*
|
|
950
|
+
* @param euler1 - First Euler angle [z, y, x] in radians
|
|
951
|
+
* @param euler2 - Second Euler angle [z, y, x] in radians
|
|
952
|
+
* @param t - Interpolation factor. Values between 0-1 interpolate, outside this range extrapolate.
|
|
953
|
+
* t=0 returns euler1, t=1 returns euler2, t<0 extrapolates backwards, t>1 extrapolates forwards.
|
|
954
|
+
* @returns The interpolated/extrapolated Euler angle [z, y, x] in radians
|
|
955
|
+
*
|
|
956
|
+
* @example
|
|
957
|
+
* ```typescript
|
|
958
|
+
* const from = [0, 0, 0];
|
|
959
|
+
* const to = [Math.PI, Math.PI/2, 0];
|
|
960
|
+
* const halfway = eulerSlerp(from, to, 0.5); // 50% interpolation
|
|
961
|
+
* const extrapolated = eulerSlerp(from, to, 1.5); // 150% - extrapolates beyond 'to'
|
|
962
|
+
* const backwards = eulerSlerp(from, to, -0.5); // Extrapolates backwards from 'from'
|
|
963
|
+
* ```
|
|
964
|
+
*/
|
|
965
|
+
declare function eulerSlerp(euler1: [number, number, number], euler2: [number, number, number], t: number): [number, number, number];
|
|
966
|
+
/**
|
|
967
|
+
* Calculates the euler angle that represents the rotation matrix from one euler angle to another.
|
|
968
|
+
* @param euler1 - The first euler angle [z, y, x] in radians (source orientation)
|
|
969
|
+
* @param euler2 - The second euler angle [z, y, x] in radians (destination orientation)
|
|
970
|
+
* @return The euler angle representing the rotation from euler1 to euler2 [z, y, x] in radians
|
|
971
|
+
*/
|
|
972
|
+
declare function eulerRotationBetween(euler1: [number, number, number], euler2: [number, number, number]): [number, number, number];
|
|
783
973
|
|
|
784
974
|
/**
|
|
785
975
|
* Merges overlapping segments in an array of intervals.
|
|
@@ -1001,20 +1191,243 @@ declare function composeProgressiveResult<T extends {
|
|
|
1001
1191
|
*/
|
|
1002
1192
|
declare const EMAIL: RegExp;
|
|
1003
1193
|
|
|
1194
|
+
/**
|
|
1195
|
+
* Filter function type for map comparison
|
|
1196
|
+
*/
|
|
1197
|
+
type MapFilterFn<K, V> = (key: K, value: V) => boolean;
|
|
1198
|
+
/**
|
|
1199
|
+
* Options for map deep equality comparison
|
|
1200
|
+
*/
|
|
1201
|
+
interface MapDeepEqualOptions<K, V> {
|
|
1202
|
+
/** Filter function to determine which entries to compare */
|
|
1203
|
+
filter?: MapFilterFn<K, V>;
|
|
1204
|
+
}
|
|
1004
1205
|
/**
|
|
1005
1206
|
* Compares two maps for deep equality by checking all key/value pairs.
|
|
1207
|
+
* Optionally filters which entries to consider in the comparison.
|
|
1006
1208
|
*
|
|
1007
1209
|
* @param map1 - The first map to compare.
|
|
1008
1210
|
* @param map2 - The second map to compare.
|
|
1009
|
-
* @
|
|
1211
|
+
* @param options - Optional configuration for the comparison
|
|
1212
|
+
* @returns True if both maps have the same entries (after filtering); false otherwise.
|
|
1010
1213
|
*
|
|
1011
1214
|
* @example
|
|
1012
1215
|
* ```typescript
|
|
1013
|
-
* const mapA = new Map([["key1", { a: 1 }]]);
|
|
1014
|
-
* const mapB = new Map([["key1", { a: 1 }]]);
|
|
1216
|
+
* const mapA = new Map([["key1", { a: 1 }], ["key2", { b: 2 }]]);
|
|
1217
|
+
* const mapB = new Map([["key1", { a: 1 }], ["key2", { b: 2 }]]);
|
|
1015
1218
|
* console.log(isMapDeepEqual(mapA, mapB)); // true
|
|
1219
|
+
*
|
|
1220
|
+
* // With filter - only compare entries where key starts with "key1"
|
|
1221
|
+
* const mapC = new Map([["key1", { a: 1 }], ["key2", { b: 3 }]]);
|
|
1222
|
+
* const mapD = new Map([["key1", { a: 1 }], ["key2", { b: 2 }]]);
|
|
1223
|
+
* console.log(isMapDeepEqual(mapC, mapD, {
|
|
1224
|
+
* filter: (key) => key.toString().startsWith("key1")
|
|
1225
|
+
* })); // true (only key1 is compared)
|
|
1226
|
+
*
|
|
1227
|
+
* // Filter by value properties
|
|
1228
|
+
* const mapE = new Map([["a", { priority: 1, data: "x" }], ["b", { priority: 2, data: "y" }]]);
|
|
1229
|
+
* const mapF = new Map([["a", { priority: 1, data: "z" }], ["b", { priority: 2, data: "y" }]]);
|
|
1230
|
+
* console.log(isMapDeepEqual(mapE, mapF, {
|
|
1231
|
+
* filter: (key, value) => value.priority === 2
|
|
1232
|
+
* })); // true (only compares entries with priority: 2)
|
|
1016
1233
|
* ```
|
|
1017
1234
|
*/
|
|
1018
|
-
declare function isMapDeepEqual<K, V>(map1: Map<K, V>, map2: Map<K, V>): boolean;
|
|
1235
|
+
declare function isMapDeepEqual<K, V>(map1: Map<K, V>, map2: Map<K, V>, options?: MapDeepEqualOptions<K, V>): boolean;
|
|
1236
|
+
|
|
1237
|
+
declare function storedEulerXYZtoRPY(robotData: any): any;
|
|
1238
|
+
|
|
1239
|
+
/**
|
|
1240
|
+
* Configuration for a context provider
|
|
1241
|
+
*/
|
|
1242
|
+
interface ContextConfig<T> {
|
|
1243
|
+
/** The React context */
|
|
1244
|
+
context: Context<T | null>;
|
|
1245
|
+
/** Default store/value to provide when context is missing */
|
|
1246
|
+
defaultValue: T;
|
|
1247
|
+
/** Name for error messages */
|
|
1248
|
+
name: string;
|
|
1249
|
+
}
|
|
1250
|
+
/**
|
|
1251
|
+
* Props for components that can optionally provide their own context
|
|
1252
|
+
*/
|
|
1253
|
+
interface OptionalContextProps {
|
|
1254
|
+
/** Whether to skip providing context (assume parent provides it) */
|
|
1255
|
+
skipContext?: boolean;
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* Creates a hook that requires context to be present
|
|
1259
|
+
*/
|
|
1260
|
+
declare function createContextHook<T>(context: Context<T | null>, name: string): () => T;
|
|
1261
|
+
/**
|
|
1262
|
+
* Creates a component that provides context if not already present
|
|
1263
|
+
*/
|
|
1264
|
+
declare function withOptionalContext<P extends object>(CoreComponent: ComponentType<P>, contextConfig: ContextConfig<any>): ComponentType<P & OptionalContextProps>;
|
|
1265
|
+
/**
|
|
1266
|
+
* Composes multiple context providers into a single component
|
|
1267
|
+
*/
|
|
1268
|
+
declare function composeContexts(contexts: {
|
|
1269
|
+
Provider: ComponentType<{
|
|
1270
|
+
children: ReactNode;
|
|
1271
|
+
}>;
|
|
1272
|
+
condition?: () => boolean;
|
|
1273
|
+
}[]): ComponentType<{
|
|
1274
|
+
children: ReactNode;
|
|
1275
|
+
}>;
|
|
1276
|
+
/**
|
|
1277
|
+
* Creates a provider component for a context
|
|
1278
|
+
*/
|
|
1279
|
+
declare function createContextProvider<T>(context: Context<T | null>, defaultValue: T): ComponentType<{
|
|
1280
|
+
children: ReactNode;
|
|
1281
|
+
value?: T;
|
|
1282
|
+
}>;
|
|
1283
|
+
/**
|
|
1284
|
+
* Utility type for extracting context value type
|
|
1285
|
+
*/
|
|
1286
|
+
type ContextValue<T> = T extends Context<infer U> ? U : never;
|
|
1287
|
+
/**
|
|
1288
|
+
* Configuration for creating a complete context solution
|
|
1289
|
+
*/
|
|
1290
|
+
interface ContextSolutionConfig<T> {
|
|
1291
|
+
/** The React context */
|
|
1292
|
+
context: Context<T | null>;
|
|
1293
|
+
/** Default store/value */
|
|
1294
|
+
defaultValue: T;
|
|
1295
|
+
/** Name for debugging and errors */
|
|
1296
|
+
name: string;
|
|
1297
|
+
}
|
|
1298
|
+
/**
|
|
1299
|
+
* Creates a complete context solution with consistent patterns
|
|
1300
|
+
*/
|
|
1301
|
+
declare function createContextSolution<T>(config: ContextSolutionConfig<T>): {
|
|
1302
|
+
useContext: () => T;
|
|
1303
|
+
Provider: ComponentType<{
|
|
1304
|
+
children: ReactNode;
|
|
1305
|
+
value?: T | undefined;
|
|
1306
|
+
}>;
|
|
1307
|
+
withOptional: <P extends object>(Component: ComponentType<P>) => ComponentType<P & OptionalContextProps>;
|
|
1308
|
+
context: Context<T | null>;
|
|
1309
|
+
};
|
|
1310
|
+
/**
|
|
1311
|
+
* Standard interface for components that might need tooltip context
|
|
1312
|
+
*/
|
|
1313
|
+
interface WithTooltipContextProps {
|
|
1314
|
+
/** Skip providing tooltip context (assume parent provides) */
|
|
1315
|
+
skipTooltipContext?: boolean;
|
|
1316
|
+
}
|
|
1317
|
+
/**
|
|
1318
|
+
* Utility for checking if context exists without throwing
|
|
1319
|
+
*/
|
|
1320
|
+
declare function useOptionalContext<T>(context: Context<T | null>): T | null;
|
|
1321
|
+
/**
|
|
1322
|
+
* Creates a context checker function
|
|
1323
|
+
*/
|
|
1324
|
+
declare function createContextChecker<T>(context: Context<T | null>): () => boolean;
|
|
1325
|
+
|
|
1326
|
+
interface ValuesData {
|
|
1327
|
+
values: Map<string, RawValue | undefined>;
|
|
1328
|
+
velocities: Map<string, RawValue | undefined>;
|
|
1329
|
+
}
|
|
1330
|
+
interface ValuesActions {
|
|
1331
|
+
updateValues: (values: Map<string, RawValue | undefined>) => void;
|
|
1332
|
+
updateVelocities: (velocities: Map<string, RawValue | undefined>) => void;
|
|
1333
|
+
setTrackValue: (trackKey: string, value: RawValue) => void;
|
|
1334
|
+
/** Replace both maps at once (used by derived orchestrator). */
|
|
1335
|
+
replaceAll: (values: Map<string, RawValue | undefined>, velocities: Map<string, RawValue | undefined>) => void;
|
|
1336
|
+
}
|
|
1337
|
+
type ValuesStore = ValuesData & ValuesActions;
|
|
1338
|
+
/**
|
|
1339
|
+
* Merge `updates` into `base`, returning a new Map.
|
|
1340
|
+
* Keys mapped to `undefined` in `updates` are deleted from the result.
|
|
1341
|
+
*/
|
|
1342
|
+
declare function mergeValueMaps(base: Map<string, RawValue | undefined>, updates: Map<string, RawValue | undefined>): Map<string, RawValue | undefined>;
|
|
1343
|
+
/**
|
|
1344
|
+
* Standalone Zustand store for high-frequency transient values and velocities.
|
|
1345
|
+
*
|
|
1346
|
+
* **Single source of truth for runtime animatable values.** Scene rendering,
|
|
1347
|
+
* animation editor controls, and device commanders all read from this store.
|
|
1348
|
+
* The studio/animation/scene stores own *structure* (animatables, tracks,
|
|
1349
|
+
* world, namespaces); this store owns *current numeric state*.
|
|
1350
|
+
*
|
|
1351
|
+
* ## Why a separate store
|
|
1352
|
+
* During playback the derived orchestrator writes new interpolated values at
|
|
1353
|
+
* ~40 Hz. A dedicated store with `subscribeWithSelector` means only the
|
|
1354
|
+
* consumers that need per-tick updates re-evaluate; subscribers of the other
|
|
1355
|
+
* stores aren't woken on every tick. `mergeValueMaps` additionally returns
|
|
1356
|
+
* the same Map reference when no values changed, so redundant writes don't
|
|
1357
|
+
* fan out to subscribers.
|
|
1358
|
+
*
|
|
1359
|
+
* ## Key formats
|
|
1360
|
+
* Two key formats coexist in the maps:
|
|
1361
|
+
* - **trackKey** (`namespaceId/instanceId/trackId`) — written by the derived
|
|
1362
|
+
* orchestrator during playback. Only meaningful to the animation system.
|
|
1363
|
+
* - **dotKey** (`namespaceId.animatableId`) — used by scene rendering hooks
|
|
1364
|
+
* and device command subscriptions.
|
|
1365
|
+
*
|
|
1366
|
+
* The values-bridge subscription (in `apps/studio`) converts trackKey entries
|
|
1367
|
+
* into dotKey entries during playback so downstream consumers don't need to
|
|
1368
|
+
* know about the animation layer.
|
|
1369
|
+
*
|
|
1370
|
+
* ## Readers
|
|
1371
|
+
* - `useFeatures`, `useAnimatableSubscription` (`@semio/scene`, `@semio/vizij`)
|
|
1372
|
+
* — scene rendering hooks subscribe to dotKey entries.
|
|
1373
|
+
* - `AnimatableControl`, `AnimatableEditor` (`@semio/animation`) — animation
|
|
1374
|
+
* editor controls subscribe to trackKey or dotKey entries.
|
|
1375
|
+
* - `device-subscriptions.ts` (studio) — outbound device commands and
|
|
1376
|
+
* trajectories read dotKey entries.
|
|
1377
|
+
*
|
|
1378
|
+
* ## Writers
|
|
1379
|
+
* - `setValueDirectAction` (studio) — direct user edits.
|
|
1380
|
+
* - `device-subscriptions.ts` `onData` handler (studio) — incoming device
|
|
1381
|
+
* feedback writes feedback-namespace dotKeys.
|
|
1382
|
+
* - `namespace-subscription.ts` (studio) — writes root-transform dotKeys for
|
|
1383
|
+
* target/feedback/sim instances when entity config changes.
|
|
1384
|
+
* - `init-derived-orchestrator.ts` (`@semio/animation`) — writes trackKey
|
|
1385
|
+
* values during playback.
|
|
1386
|
+
* - `values-bridge-subscription.ts` (studio) — writes converted trackKey →
|
|
1387
|
+
* dotKey entries.
|
|
1388
|
+
*
|
|
1389
|
+
* ## Gizmo writes (override seam)
|
|
1390
|
+
* Scene primitives that write values back (e.g. joint gizmos) go through
|
|
1391
|
+
* `SceneValueWriterContext` from `@semio/scene` — they call
|
|
1392
|
+
* `useSceneValueWriter().setValue(id, namespace, value)` rather than touching
|
|
1393
|
+
* this store directly. The default writer hits `updateValues` here. Studio
|
|
1394
|
+
* overrides the writer to route through its animation-aware `setValueAction`,
|
|
1395
|
+
* which produces a keypoint update or a direct write depending on the entity's
|
|
1396
|
+
* controlMode and selected animation instance. See `packages/scene/README.md`.
|
|
1397
|
+
*
|
|
1398
|
+
* ## Lifecycle
|
|
1399
|
+
* On project load, studio's `loadFromFullContext` calls `replaceAll(new Map(),
|
|
1400
|
+
* new Map())` before applying the new project, so post-load subscribers
|
|
1401
|
+
* (`namespace-subscription`, derived orchestrator) repopulate from a clean
|
|
1402
|
+
* slate. Outside of load the store accumulates dotKey entries as namespaces
|
|
1403
|
+
* and animatables are added; entries for removed animatables can become stale
|
|
1404
|
+
* until cleared.
|
|
1405
|
+
*/
|
|
1406
|
+
declare const useValuesStore: zustand.UseBoundStore<Omit<zustand.StoreApi<ValuesStore>, "subscribe"> & {
|
|
1407
|
+
subscribe: {
|
|
1408
|
+
(listener: (selectedState: ValuesStore, previousSelectedState: ValuesStore) => void): () => void;
|
|
1409
|
+
<U>(selector: (state: ValuesStore) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
|
|
1410
|
+
equalityFn?: ((a: U, b: U) => boolean) | undefined;
|
|
1411
|
+
fireImmediately?: boolean;
|
|
1412
|
+
} | undefined): () => void;
|
|
1413
|
+
};
|
|
1414
|
+
}>;
|
|
1415
|
+
|
|
1416
|
+
/**
|
|
1417
|
+
* Type guard for Three.js OrthographicCamera.
|
|
1418
|
+
*
|
|
1419
|
+
* Accepts a broad parameter type to work with both Three.js Camera and
|
|
1420
|
+
* R3F's Camera union (which may resolve from a different @types/three
|
|
1421
|
+
* declaration in monorepo setups).
|
|
1422
|
+
*/
|
|
1423
|
+
declare function isOrthographicCamera(camera: object): camera is OrthographicCamera;
|
|
1424
|
+
/**
|
|
1425
|
+
* Type guard for Three.js PerspectiveCamera.
|
|
1426
|
+
*
|
|
1427
|
+
* Accepts a broad parameter type to work with both Three.js Camera and
|
|
1428
|
+
* R3F's Camera union (which may resolve from a different @types/three
|
|
1429
|
+
* declaration in monorepo setups).
|
|
1430
|
+
*/
|
|
1431
|
+
declare function isPerspectiveCamera(camera: object): camera is PerspectiveCamera;
|
|
1019
1432
|
|
|
1020
|
-
export { type AnimatableBoolean, type AnimatableColor, type AnimatableEuler, type AnimatableNumber, type AnimatablePubInfo, type AnimatableString, type AnimatableValue, type AnimatableVector2, type AnimatableVector3, EMAIL, type Player, type PlayerActions, PlayerContext, type PlayerData, PlayerSlice, type PlayerStore, type PlayerStoreGetter, type PlayerStoreSetter, type Progress, type ProgressiveResult, type RawBoolean, type RawColor, type RawEuler, type RawHSL, type RawNumber, type RawRGB, type RawString, type RawTime, type RawValue, type RawVector2, type RawVector3, Result, type StoreSubscribeWithSelector, type Write, alpha, altColor, angularDistance, closestFrame, composeProgress, composeProgressiveResult, downloadBlob, downloadJSONFile, eulerToRotationMatrix, getDegenerateHexagonPath, getHexagonPath, getId, getLookup, getNamespace, hexToRgbArray, hexToRgba, hslToRgba, incrementProgress, instanceOfRawBoolean, instanceOfRawColor, instanceOfRawEuler, instanceOfRawHSL, instanceOfRawNumber, instanceOfRawRGB, instanceOfRawString, instanceOfRawVector2, instanceOfRawVector3, isMapDeepEqual, isRawObject, log, newPlayer, now, numberToDurationString, overlappingSegments, pairwise, parseJSONFileEvent, parseToMapped, pause, play, pointsToPath, rawHSLToHex, rawRGBToHex, reset, rgbToRgba, rotationMatrixToAngle, seek,
|
|
1433
|
+
export { type AnimatableBoolean, type AnimatableColor, type AnimatableEuler, type AnimatableGroupInfo, AnimatableGroupType, type AnimatableNumber, type AnimatablePubInfo, type AnimatableString, type AnimatableValue, type AnimatableVector2, type AnimatableVector3, type BlendHeuristicOptions, type ContextConfig, type ContextSolutionConfig, type ContextValue, type DeprecatedComplexAnimatableValue, EMAIL, type MapDeepEqualOptions, type MapFilterFn, type OptionalContextProps, type Player, type PlayerActions, PlayerContext, type PlayerData, PlayerDirection, PlayerSlice, type PlayerStore, type PlayerStoreGetter, type PlayerStoreSetter, type Progress, type ProgressiveResult, type RawBoolean, type RawColor, type RawEuler, type RawHSL, type RawNumber, type RawRGB, type RawString, type RawTime, type RawValue, type RawVector2, type RawVector3, Result, type StoreSubscribeWithSelector, type ValuesActions, type ValuesData, type ValuesStore, type WithTooltipContextProps, type Write, alpha, altColor, angularDistance, closestFrame, colorChroma, colorLightness, composeContexts, composeProgress, composeProgressiveResult, createContextChecker, createContextHook, createContextProvider, createContextSolution, downloadBlob, downloadJSONFile, eulerRotationBetween, eulerSlerp, eulerToQuaternion, eulerToRotationMatrix, getDegenerateHexagonPath, getHexagonPath, getId, getLookup, getNamespace, hexToRgbArray, hexToRgba, hslToRgba, incrementProgress, instanceOfRawBoolean, instanceOfRawColor, instanceOfRawEuler, instanceOfRawHSL, instanceOfRawNumber, instanceOfRawRGB, instanceOfRawString, instanceOfRawVector2, instanceOfRawVector3, isMapDeepEqual, isNearNeutralMid, isOrthographicCamera, isPerspectiveCamera, isRawObject, log, mergeValueMaps, newPlayer, now, numberToDurationString, overlappingSegments, pairwise, parseJSONFileEvent, parseToMapped, pause, play, pointsToPath, quaternionConjugate, quaternionMultiply, quaternionSlerp, quaternionToEuler, randomHexString, rawHSLToHex, rawRGBToHex, reset, reversed, rgbChroma, rgbLightness, rgbToRgba, rotationMatrixToAngle, seek, shouldUseBlendForLabelColor, storedEulerXYZtoRPY, stringifyMapped, toDegrees, toRadians, updated, useDeep, useDeepSelector, useLazy, useMediaQuery, useOptionalContext, usePlayerStore, useValuesStore, warnUnexpectedFeatureValue, withBounce, withBounds, withDirection, withDuration, withLooping, withOptionalContext, withSpeed };
|