@vizij/render 1.0.1 → 3.0.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.ts CHANGED
@@ -1,12 +1,140 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
1
  import * as react from 'react';
3
- import { CSSProperties, ComponentProps, ReactNode, RefObject, MouseEvent } from 'react';
4
- import { Canvas, ThreeEvent } from '@react-three/fiber';
5
- import * as THREE from 'three';
6
- import { BufferGeometry, ShapeGeometry, ToneMapping, Group as Group$1, Mesh, AnimationClip, Object3D } from 'three';
2
+ import { CSSProperties, ReactNode } from 'react';
3
+ import { MountOptions, InitProgress, ToneMapping, Fit, Bounds, Pick } from '@vizij/runtime';
7
4
  import * as zustand from 'zustand';
5
+ import * as THREE from 'three';
6
+ import { BufferGeometry, ShapeGeometry, Group as Group$1, Object3D, AnimationClip } from 'three';
8
7
  import { RawValue, AnimatableValue, RawVector2 } from '@vizij/utils';
9
8
 
9
+ /**
10
+ * Resolves with the page's canvas once `<VizijCanvas>` has mounted it, which
11
+ * `loadVizij` requires; rejects if mounting failed.
12
+ */
13
+ declare function canvasMounted(): Promise<HTMLCanvasElement>;
14
+ interface VizijCanvasProps {
15
+ /** `mount`'s options: every face's defaults. Read on the page's first
16
+ * mount; the App keeps them for the page's lifetime. */
17
+ options?: MountOptions;
18
+ /** Replace the default style — fixed over the page, pointer events off —
19
+ * of the element the canvas fills. A page that takes picks gives it
20
+ * pointer events. */
21
+ className?: string;
22
+ style?: CSSProperties;
23
+ }
24
+ /**
25
+ * The page's one canvas, which every `<Vizij>` slot draws on.
26
+ *
27
+ * Its first mount runs `@vizij/runtime`'s `mount`; a second `<VizijCanvas>`,
28
+ * a remount or React StrictMode's second effect shows the same canvas and
29
+ * App. While it is shown, one animation frame loop places each slot's face
30
+ * over the slot and hands each pick to the slot it names: `placeVizij` and
31
+ * `drainPicks` are page-wide, so they have one caller.
32
+ *
33
+ * By default the canvas is fixed over the page with pointer events off, so
34
+ * faces draw wherever their slots lie and the page's own UI keeps the
35
+ * pointer. Content that must draw over the faces stacks above the canvas.
36
+ */
37
+ declare function VizijCanvas({ options, className, style, }: VizijCanvasProps): ReactNode;
38
+
39
+ /**
40
+ * A face's own stages on its way to being drawn, as whoever loads it reports
41
+ * them (`setVizijProgress`): its GLB's bytes arriving (`total` is `null`
42
+ * when the length is unknown), `loadVizij`, then its first frame. `failed`
43
+ * ends the load.
44
+ */
45
+ type VizijProgress = {
46
+ stage: "fetch";
47
+ loaded: number;
48
+ total: number | null;
49
+ } | {
50
+ stage: "load";
51
+ } | {
52
+ stage: "draw";
53
+ } | {
54
+ stage: "failed";
55
+ error: Error;
56
+ };
57
+ /**
58
+ * Where a face's slot is on its way to showing the face: the runtime's
59
+ * stages (`@vizij/runtime`'s `onInitProgress` until `init()` resolves, then
60
+ * `mount`, the page's App being built), then the face's own.
61
+ */
62
+ type LoadingStage = Exclude<InitProgress, {
63
+ stage: "ready";
64
+ }> | {
65
+ stage: "mount";
66
+ } | VizijProgress;
67
+ /**
68
+ * Report face `vizijId`'s own stage, for the loading view of its slot
69
+ * (`<Vizij>`). `@vizij/runtime-react`'s provider reports its faces; a page
70
+ * that loads a face with `loadVizij` itself reports it the same way. `null`
71
+ * says no face is loaded under the id any more: its slot shows the loading
72
+ * view again until a face under the id is drawn.
73
+ *
74
+ * Whatever is reported, a slot hides its loading view once its face has been
75
+ * drawn (`ready(vizijId)`), and keeps it hidden through reloads, whose
76
+ * previous scene draws until the new one is ready.
77
+ */
78
+ declare function setVizijProgress(vizijId: string, progress: VizijProgress | null): void;
79
+
80
+ /** A slot's loading view, as `<Vizij>`'s `loading` render prop receives it. */
81
+ interface VizijLoading {
82
+ stage: LoadingStage;
83
+ /** The stage in words: "Downloading the runtime: 3.1 of 9.8 MB". */
84
+ label: string;
85
+ /** How much of the stage is done, from 0 to 1, for the stages that count
86
+ * bytes against a known total; `null` (indeterminate) for the others. */
87
+ fraction: number | null;
88
+ }
89
+
90
+ interface VizijProps {
91
+ /** The face this slot shows: the id it is loaded under (`loadVizij`). */
92
+ vizijId: string;
93
+ /** Size and place the slot; the face draws over its border box. */
94
+ className?: string;
95
+ style?: CSSProperties;
96
+ /** The face's tone-mapping curve; `none` when absent. */
97
+ toneMapping?: ToneMapping;
98
+ /** How the framed bounds fit the slot; the canvas's `options.fit` when
99
+ * absent. */
100
+ fit?: Fit;
101
+ /** Magnification after the fit; the canvas's `options.zoom` when absent. */
102
+ zoom?: number | [number, number];
103
+ /** The world rectangle the face's camera frames, in place of the GLB's
104
+ * authored `rootBounds`. */
105
+ bounds?: Bounds;
106
+ /** Outline the framed bounds over the face. */
107
+ showSafeArea?: boolean;
108
+ /** The elements whose outlines glow, by the ids their RobotData declares.
109
+ * Absent, the slot leaves the face's selection as it is. */
110
+ selection?: string[];
111
+ /** A press on the face: the element under the pointer, or `null` for a
112
+ * press that hit none. Picks need pointer events on the canvas. */
113
+ onPick?: (pick: Pick) => void;
114
+ /** The image of the default loading view, in place of Vizij's logo,
115
+ * which `@vizij/render` ships; `null` for none. */
116
+ loadingImage?: ReactNode;
117
+ /** The slot's own loading view, in place of the default: called with the
118
+ * stage, its label and its fraction while the face is not drawn. `null`
119
+ * shows none. */
120
+ loading?: ((loading: VizijLoading) => ReactNode) | null;
121
+ }
122
+ /**
123
+ * Where face `vizijId` draws on the page's canvas (`<VizijCanvas>`): a
124
+ * `<div>` the canvas's frame loop places the face over, following it as the
125
+ * page scrolls and lays out. It renders no canvas of its own. One slot shows
126
+ * a face at a time.
127
+ *
128
+ * The element carries `data-vizij-id`, and `data-vizij-ready` — `"true"`
129
+ * once the face's scene shows its device's pose (`ready(vizijId)`).
130
+ *
131
+ * Until its face is first drawn, the slot shows a loading view over its
132
+ * border box: the runtime's stages, then the face's (`setVizijProgress`).
133
+ * The view is a DOM overlay in the slot: under a canvas laid over the page,
134
+ * it shows wherever the canvas draws nothing.
135
+ */
136
+ declare function Vizij({ vizijId, className, style, toneMapping, fit, zoom, bounds, showSafeArea, selection, onPick, loadingImage, loading, }: VizijProps): ReactNode;
137
+
10
138
  /**
11
139
  * A wrapping type to reference an attribute that is animatable.
12
140
  *
@@ -48,6 +176,24 @@ interface StoredAnimatedFeature {
48
176
  * @param value - The id of the {@link AnimatableValue} used to populate this value if animated, or the value {@link RawValue} if static.
49
177
  */
50
178
  type Feature = AnimatedFeature | StaticFeature;
179
+ /**
180
+ * A compound feature in its per-axis form: one feature per component, named
181
+ * `<feature>.<axis>` (`translation.x`, `rotation.r`, `color.g`), each a
182
+ * number. Semio Studio writes its faces this way. An element may carry a
183
+ * compound feature whole, per axis, or both; a component named per axis
184
+ * stands over that component of the whole value.
185
+ */
186
+ type PerAxisFeatures<Name extends string, Axis extends string> = {
187
+ [Key in `${Name}.${Axis}`]?: Feature;
188
+ };
189
+ /** The components of a translation or a scale. */
190
+ type VectorAxis = "x" | "y" | "z";
191
+ /** The components of a rotation: roll, pitch and yaw, the euler's x, y and z. */
192
+ type RotationAxis = "r" | "p" | "y";
193
+ /** The components of a colour. */
194
+ type ColorAxis = "r" | "g" | "b";
195
+ /** An element's translation, rotation and scale, per axis. */
196
+ type PerAxisTransformFeatures = PerAxisFeatures<"translation", VectorAxis> & PerAxisFeatures<"rotation", RotationAxis> & PerAxisFeatures<"scale", VectorAxis>;
51
197
 
52
198
  interface RenderableBase {
53
199
  id: string;
@@ -70,17 +216,17 @@ interface Stored<T extends Omit<RenderableBase, "refs">> {
70
216
  type StoredRenderable = Stored<RenderableBase>;
71
217
 
72
218
  /**
73
- * An object for creating rectangles
219
+ * An object for creating hierarchies/bodies
74
220
  *
75
- * @param id - The id of the rectangle
76
- * @param name - The name of the rectangle
77
- * @param tags - The tags of the rectangle
221
+ * @param id - The id of the ellipse
222
+ * @param name - The name of the ellipse
223
+ * @param tags - The tags of the ellipse
78
224
  * @param type - Type flag
79
- * @param features - The features of the rectangle (translation, rotation, and scale)
80
- * @param children - The children of the rectangle (list of ids for other bodies or shapes)
225
+ * @param features - The features of the ellipse (translation, rotation, and scale)
226
+ * @param children - The children of the ellipse (list of ids for other bodies or shapes)
81
227
  */
82
- interface Rectangle extends RenderableBase {
83
- type: "rectangle";
228
+ interface Ellipse extends RenderableBase {
229
+ type: "ellipse";
84
230
  features: {
85
231
  height: Feature;
86
232
  width: Feature;
@@ -89,27 +235,26 @@ interface Rectangle extends RenderableBase {
89
235
  fillColor?: Feature;
90
236
  strokeColor?: Feature;
91
237
  strokeWidth?: Feature;
92
- strokeRadius?: Feature;
93
238
  strokeOffset?: Feature;
94
- translation: Feature;
95
- rotation: Feature;
96
- };
239
+ translation?: Feature;
240
+ rotation?: Feature;
241
+ } & PerAxisFeatures<"translation", VectorAxis> & PerAxisFeatures<"rotation", RotationAxis> & PerAxisFeatures<"fillColor", ColorAxis> & PerAxisFeatures<"strokeColor", ColorAxis>;
97
242
  }
98
- type RectangleFeature = keyof Rectangle["features"];
99
- type StoredRectangle = Stored<Rectangle>;
243
+ type EllipseFeature = keyof Ellipse["features"];
244
+ type StoredEllipse = Stored<Ellipse>;
100
245
 
101
246
  /**
102
- * An object for creating hierarchies/bodies
247
+ * An object for creating rectangles
103
248
  *
104
- * @param id - The id of the ellipse
105
- * @param name - The name of the ellipse
106
- * @param tags - The tags of the ellipse
249
+ * @param id - The id of the rectangle
250
+ * @param name - The name of the rectangle
251
+ * @param tags - The tags of the rectangle
107
252
  * @param type - Type flag
108
- * @param features - The features of the ellipse (translation, rotation, and scale)
109
- * @param children - The children of the ellipse (list of ids for other bodies or shapes)
253
+ * @param features - The features of the rectangle (translation, rotation, and scale)
254
+ * @param children - The children of the rectangle (list of ids for other bodies or shapes)
110
255
  */
111
- interface Ellipse extends RenderableBase {
112
- type: "ellipse";
256
+ interface Rectangle extends RenderableBase {
257
+ type: "rectangle";
113
258
  features: {
114
259
  height: Feature;
115
260
  width: Feature;
@@ -118,13 +263,14 @@ interface Ellipse extends RenderableBase {
118
263
  fillColor?: Feature;
119
264
  strokeColor?: Feature;
120
265
  strokeWidth?: Feature;
266
+ strokeRadius?: Feature;
121
267
  strokeOffset?: Feature;
122
- translation: Feature;
123
- rotation: Feature;
124
- };
268
+ translation?: Feature;
269
+ rotation?: Feature;
270
+ } & PerAxisFeatures<"translation", VectorAxis> & PerAxisFeatures<"rotation", RotationAxis> & PerAxisFeatures<"fillColor", ColorAxis> & PerAxisFeatures<"strokeColor", ColorAxis>;
125
271
  }
126
- type EllipseFeature = keyof Ellipse["features"];
127
- type StoredEllipse = Stored<Ellipse>;
272
+ type RectangleFeature = keyof Rectangle["features"];
273
+ type StoredRectangle = Stored<Rectangle>;
128
274
 
129
275
  /**
130
276
  * An object for creating hierarchies/groups
@@ -140,11 +286,12 @@ type StoredEllipse = Stored<Ellipse>;
140
286
  interface Group extends RenderableBase {
141
287
  type: "group";
142
288
  root: boolean;
289
+ /** Translation and rotation, each whole or per axis. */
143
290
  features: {
144
- translation: Feature;
145
- rotation: Feature;
291
+ translation?: Feature;
292
+ rotation?: Feature;
146
293
  scale?: Feature;
147
- };
294
+ } & PerAxisTransformFeatures;
148
295
  rootBounds?: {
149
296
  center: RawVector2;
150
297
  size: RawVector2;
@@ -183,10 +330,10 @@ interface Shape extends RenderableBase {
183
330
  emissive?: Feature;
184
331
  emissiveIntensity?: Feature;
185
332
  specular?: Feature;
186
- translation: Feature;
187
- rotation: Feature;
333
+ translation?: Feature;
334
+ rotation?: Feature;
188
335
  scale?: Feature;
189
- };
336
+ } & PerAxisTransformFeatures & PerAxisFeatures<"color", ColorAxis> & PerAxisFeatures<"emissive", ColorAxis> & PerAxisFeatures<"specular", ColorAxis>;
190
337
  material: ShapeMaterial;
191
338
  geometry: BufferGeometry | ShapeGeometry;
192
339
  morphTargets?: string[];
@@ -208,6 +355,8 @@ declare enum ShapeMaterial {
208
355
  type ShapeFeature = keyof Shape["features"];
209
356
  type StoredShape = Stored<Omit<Shape, "geometry">>;
210
357
 
358
+ type World = Record<string, Group | Ellipse | Rectangle | Shape>;
359
+
211
360
  type RenderableFeature = GroupFeature | EllipseFeature;
212
361
 
213
362
  /**
@@ -230,27 +379,20 @@ interface Selection {
230
379
  };
231
380
  }
232
381
 
233
- type World = Record<string, Group | Ellipse | Rectangle | Shape>;
234
-
235
382
  /**
236
- * Vizij-level tone-mapping selection.
237
- *
238
- * This is a stable, serializable string enum rather than a raw three.js
239
- * constant so it can be persisted in the `VIZIJ_bundle` extension and round-trip
240
- * through import/export without leaking three's numeric enum values into stored
241
- * data.
242
- *
243
- * - `"none"` — no tone mapping. Values are written to the framebuffer as-is and
244
- * clip at 1.0. This matches plain web/canvas rendering and is the historical
245
- * vizij default (chosen so studio colors match the canvas).
246
- * - `"agx"` — AgX, Blender 4.x's default view transform. Compresses
247
- * over-1.0 emissive into soft, slightly-desaturated color; matches faces
248
- * authored/exported from Blender.
383
+ * A face's tone-mapping curve, as a bundle stores it and the view applies it
384
+ * (`@vizij/runtime`'s `ToneMapping`):
385
+ *
386
+ * - `"none"` — no curve: colors as shaded, clipped at 1.0, as plain web
387
+ * rendering shows them. The default.
388
+ * - `"agx"` — AgX, Blender 4.x's default view transform: over-1.0 emissive
389
+ * compressed into soft, slightly desaturated color, as faces authored in
390
+ * Blender expect.
249
391
  * - `"aces"` — ACES Filmic, a punchier cinematic curve.
250
- * - `"neutral"` — Khronos PBR Neutral, a mild curve that preserves hue/saturation
251
- * while taming highlights.
392
+ * - `"neutral"` — Khronos PBR Neutral, a mild curve that keeps hue and
393
+ * saturation while taming highlights.
252
394
  */
253
- type ToneMappingMode = "none" | "agx" | "aces" | "neutral";
395
+ type ToneMappingMode = ToneMapping;
254
396
  /**
255
397
  * The set of supported tone-mapping modes, in display order. Useful for
256
398
  * building selection UIs.
@@ -260,21 +402,12 @@ declare const TONE_MAPPING_MODES: ToneMappingMode[];
260
402
  * Human-readable labels for each tone-mapping mode.
261
403
  */
262
404
  declare const TONE_MAPPING_LABELS: Record<ToneMappingMode, string>;
263
- /**
264
- * The default tone-mapping mode used when a face/scene has not specified one.
265
- * `"none"` preserves the historical web-matching behavior.
266
- */
405
+ /** The tone-mapping mode of a face that specifies none. */
267
406
  declare const DEFAULT_TONE_MAPPING_MODE: ToneMappingMode;
268
407
  /**
269
408
  * Type guard: is `value` a valid {@link ToneMappingMode}?
270
409
  */
271
410
  declare function isToneMappingMode(value: unknown): value is ToneMappingMode;
272
- /**
273
- * Resolve a {@link ToneMappingMode} (or an unknown/undefined stored value) to
274
- * the corresponding three.js tone-mapping constant. Falls back to
275
- * {@link DEFAULT_TONE_MAPPING_MODE} for missing/invalid input.
276
- */
277
- declare function resolveToneMapping(mode: unknown): ToneMapping;
278
411
  /**
279
412
  * Normalize an unknown/stored value into a valid {@link ToneMappingMode},
280
413
  * falling back to {@link DEFAULT_TONE_MAPPING_MODE}.
@@ -503,68 +636,14 @@ interface VizijAnimationClipData {
503
636
  tracks: VizijAnimationTrackData[];
504
637
  }
505
638
 
506
- interface VizijProps {
507
- style?: CSSProperties;
508
- className?: string;
509
- rootId: string;
510
- namespace?: string;
511
- showSafeArea?: boolean;
512
- showSelectionGlow?: boolean;
513
- /**
514
- * View-transform applied by the WebGL renderer. Defaults to `"none"`
515
- * (no tone mapping — matches plain web/canvas rendering). Faces authored in
516
- * Blender typically want `"agx"` to compress over-driven emissive. Applied
517
- * reactively, so it can be changed at runtime without remounting the canvas.
518
- */
519
- toneMapping?: ToneMappingMode;
520
- onPointerMissed?: ComponentProps<typeof Canvas>["onPointerMissed"];
521
- }
522
- /**
523
- * Renders the Vizij component.
524
- *
525
- * @param style - The style object for the Vizij component.
526
- *
527
- * @param className - The CSS class name for the Vizij component
528
- *
529
- * @param rootId - The root identifier for the Vizij component.
530
- *
531
- * @param namespace - The namespace for the Vizij component
532
- *
533
- * @param showSafeArea - Whether to show the safe area.
534
- *
535
- * @returns The rendered ReactNode.
536
- */
537
- declare function Vizij({ style, className, rootId, namespace, showSafeArea, showSelectionGlow, toneMapping, onPointerMissed, }: VizijProps): ReactNode;
538
- interface InnerVizijProps {
539
- rootId: string;
540
- namespace: string;
541
- container?: {
542
- width: number;
543
- height: number;
544
- resolution: number;
545
- };
546
- showSafeArea?: boolean;
547
- showSelectionGlow?: boolean;
548
- toneMapping?: ToneMappingMode;
549
- }
550
- declare function InnerVizij({ rootId, namespace, container, showSafeArea, showSelectionGlow, toneMapping, }: InnerVizijProps): react_jsx_runtime.JSX.Element;
551
-
552
639
  interface VizijData {
553
640
  world: World;
554
- /**
555
- * The mounted three.js object of each world element, by element id and then
556
- * namespace. It lives beside `world` so that the world stays plain data.
557
- */
558
- refs: Record<string, Record<string, RefObject<Group$1 | Mesh | null>>>;
559
641
  animatables: Record<string, AnimatableValue>;
560
642
  values: Map<string, RawValue | undefined>;
561
- renderHit: boolean;
562
643
  preferences: {
563
644
  damping: boolean;
564
645
  };
565
646
  elementSelection: Selection[];
566
- hoveredElement: Selection | null;
567
- slotConfig: Record<string, string>;
568
647
  }
569
648
  interface VizijActions {
570
649
  setValue: (id: string, namespace: string, value: RawValue | ((current: RawValue | undefined) => RawValue | undefined)) => void;
@@ -575,15 +654,9 @@ interface VizijActions {
575
654
  }>) => void;
576
655
  setWorldElementName: (id: string, value: string) => void;
577
656
  setVizij: (scene: World, animatables: Record<string, AnimatableValue>) => void;
578
- setSlot: (parentId: string, parentNamespace: string, childId: string, childNamespace: string) => void;
579
- setSlots: (slots: Record<string, string>, replace?: boolean) => void;
580
- clearSlot: (parentId: string, parentNamespace: string) => void;
581
657
  addWorldElements: (world: World, animatables: Record<string, AnimatableValue>, replace?: boolean) => void;
582
658
  setPreferences: (preferences: Partial<VizijData["preferences"]>) => void;
583
- getExportableBodies: (filterIds?: string[]) => Group$1[];
584
659
  updateElementSelection: (selection: Selection, chain: string[]) => void;
585
- setHoveredElement: (selection: Selection | null) => void;
586
- onElementClick: (selection: Selection, chain: string[], event: ThreeEvent<MouseEvent>) => void;
587
660
  clearSelection: () => void;
588
661
  setOrigin: (id: string, origin: {
589
662
  translation?: THREE.Vector3;
@@ -598,7 +671,6 @@ interface VizijActions {
598
671
  setChildren: (id: string, children: string[]) => void;
599
672
  setGeometry: (id: string, geometry: THREE.BufferGeometry) => void;
600
673
  setMaterial: (id: string, material: string) => void;
601
- setReference: (id: string, namespace: string, object: RefObject<Group$1 | Mesh | null>) => void;
602
674
  createGroup: (root: boolean) => void;
603
675
  createAnimatable: (elementId: string, featureName: string, value: Partial<AnimatableValue>) => void;
604
676
  createStatic: (elementId: string, featureName: string, value: RawValue) => void;
@@ -606,23 +678,16 @@ interface VizijActions {
606
678
  type VizijStoreSetter = (partial: (VizijData & VizijActions) | Partial<VizijData & VizijActions> | ((state: VizijData & VizijActions) => (VizijData & VizijActions) | Partial<VizijData & VizijActions>), replace?: false | undefined) => void;
607
679
  type VizijStoreGetter = () => VizijData & VizijActions;
608
680
 
609
- declare const VizijSlice: (set: VizijStoreSetter, get: VizijStoreGetter) => {
681
+ declare const VizijSlice: (set: VizijStoreSetter, _get: VizijStoreGetter) => {
610
682
  world: {};
611
- refs: {};
612
683
  animatables: {};
613
684
  values: Map<any, any>;
614
- renderHit: boolean;
615
685
  preferences: {
616
686
  damping: boolean;
617
687
  };
618
688
  elementSelection: never[];
619
- hoveredElement: null;
620
- slotConfig: {};
621
689
  clearSelection: () => void;
622
690
  updateElementSelection: (selection: Selection, _chain: string[]) => void;
623
- setHoveredElement: (selection: Selection | null) => void;
624
- onElementClick: (selection: Selection, _chain: string[], event: ThreeEvent<MouseEvent>) => void;
625
- getExportableBodies: (filterIds?: string[]) => THREE.Group<THREE.Object3DEventMap>[];
626
691
  setGeometry: (id: string, geometry: THREE.BufferGeometry) => void;
627
692
  setValue: (id: string, namespace: string, value: RawValue | ((current: RawValue | undefined) => RawValue | undefined)) => void;
628
693
  setValues: (writes?: Array<{
@@ -646,13 +711,9 @@ declare const VizijSlice: (set: VizijStoreSetter, get: VizijStoreGetter) => {
646
711
  createAnimatable: (elementId: string, featureName: string, value: Partial<AnimatableValue>) => void;
647
712
  createStatic: (elementId: string, featureName: string, value: RawValue) => void;
648
713
  setAnimatableValue: (id: string, value: AnimatableValue) => void;
649
- setSlot: (parentId: string, parentNamespace: string, childId: string, childNamespace: string) => void;
650
- setSlots: (slots: Record<string, string>, replace?: boolean) => void;
651
- clearSlot: (parentId: string, parentNamespace: string) => void;
652
714
  setVizij: (scene: World, animatables: Record<string, AnimatableValue>) => void;
653
715
  addWorldElements(world: World, animatables: Record<string, AnimatableValue>, replace?: boolean): void;
654
716
  setPreferences: (preferences: Partial<VizijData["preferences"]>) => void;
655
- setReference: (id: string, namespace: string, ref: RefObject<Group$1 | Mesh | null>) => void;
656
717
  };
657
718
  declare const useDefaultVizijStore: zustand.UseBoundStore<Omit<zustand.StoreApi<VizijData & VizijActions>, "subscribe"> & {
658
719
  subscribe: {
@@ -688,25 +749,6 @@ declare function useVizijStore<T>(selector: (state: VizijData & VizijActions) =>
688
749
 
689
750
  declare function useVizijStoreSubscription<T>(selector: (state: VizijData & VizijActions) => T, listener: (state: T) => void): void;
690
751
 
691
- /**
692
- * Custom React hook to manage and subscribe to feature values.
693
- *
694
- * @param namespace - The namespace for the features.
695
- * @param features - A record of feature objects keyed by their IDs.
696
- * @param callbacks - A record of callback functions keyed by feature IDs.
697
- * @param debugInfo - Optional debug information to log in case of errors.
698
- *
699
- * @throws [Error] If the SceneContext store is not found.
700
- *
701
- * @returns [void]
702
- *
703
- * This hook sets up subscriptions to feature values and invokes the provided callbacks when the values change.
704
- * It handles both animated and non-animated features. For animated features, it subscribes to the animatable value
705
- * in the store and invokes the callback whenever the value changes. For non-animated features, it immediately
706
- * invokes the callback with the feature's value.
707
- */
708
- declare function useFeatures(namespace: string, features: Record<string, Feature>, callbacks: Record<string, (current: RawValue) => void>, debugInfo?: any): void;
709
-
710
752
  declare function useVizijStoreSetter(): {
711
753
  (partial: (VizijData & VizijActions) | Partial<VizijData & VizijActions> | ((state: VizijData & VizijActions) => (VizijData & VizijActions) | Partial<VizijData & VizijActions>), replace?: false): void;
712
754
  (state: (VizijData & VizijActions) | ((state: VizijData & VizijActions) => VizijData & VizijActions), replace: true): void;
@@ -714,9 +756,15 @@ declare function useVizijStoreSetter(): {
714
756
 
715
757
  declare function useVizijStoreGetter(): () => VizijData & VizijActions;
716
758
 
759
+ /**
760
+ * The error a load ends with when the GLB holds no face: no element carries
761
+ * `RobotData`, and the aggressive import finds no mesh, ellipse or rectangle
762
+ * to make one from.
763
+ */
717
764
  declare class EmptyModelError extends Error {
718
765
  constructor(message: string);
719
766
  }
767
+
720
768
  type ParserJsonFallbackSource = {
721
769
  url?: string;
722
770
  arrayBuffer?: ArrayBuffer;
@@ -752,7 +800,11 @@ declare function loadGLTFFromBlobWithBundle(blob: Blob, aggressiveImport?: boole
752
800
  size: RawVector2;
753
801
  }): Promise<LoadedVizijAsset>;
754
802
 
755
- declare function deriveRootBounds(group: Group$1): {
803
+ /**
804
+ * The bounds of everything under `group` in the XY plane: its meshes, and its
805
+ * `ellipse` and `rectangle` elements' shapes. `null` when it holds neither.
806
+ */
807
+ declare function deriveRootBounds(group: Object3D): {
756
808
  center: RawVector2;
757
809
  size: RawVector2;
758
810
  } | null;
@@ -794,6 +846,64 @@ declare function patchVizijBundleMetadata(glb: ArrayBuffer, metadata: Record<str
794
846
  */
795
847
  declare function exportScene(root: THREE.Object3D, options?: ExportSceneOptions): Promise<ArrayBuffer>;
796
848
 
849
+ /** A glTF-animatable node property, under three.js's property name. */
850
+ type ExportAnimationProperty = "position" | "quaternion" | "scale" | "morphTargetInfluences";
851
+ /** One node property's keys, to export as a glTF animation channel. */
852
+ interface ExportAnimationTrack {
853
+ /**
854
+ * The property-binding path: `<node>.<property>`, or
855
+ * `<node>.morphTargetInfluences[<morph target name>]`.
856
+ */
857
+ name: string;
858
+ property: ExportAnimationProperty;
859
+ /** The name of the node the track drives. */
860
+ elementName: string;
861
+ /** Key times, in seconds, ascending. */
862
+ times: number[];
863
+ /** Flattened key values, `times.length * stride` of them. */
864
+ values: number[];
865
+ /** Values per key: 3 for a position or scale, 4 for a quaternion, 1 for a morph weight. */
866
+ stride: number;
867
+ }
868
+ interface ExportAnimationIssue {
869
+ trackName: string;
870
+ reason: "node-not-found" | "morph-target-not-found" | "bad-stride";
871
+ detail?: string;
872
+ }
873
+ /**
874
+ * What a track binds against: the export root and its descendants, found by
875
+ * name. The graph `buildSceneGraph` returns is one.
876
+ */
877
+ interface ExportAnimationRoot {
878
+ name: string;
879
+ traverse: (callback: (child: ExportAnimationRoot) => void) => void;
880
+ morphTargetDictionary?: Record<string, number>;
881
+ }
882
+ interface ExportAnimationResult {
883
+ /** For `exportScene({ animations })`; `null` when no track binds. */
884
+ animation: AnimationClip | null;
885
+ /** The tracks left out, each with why. */
886
+ issues: ExportAnimationIssue[];
887
+ }
888
+ /**
889
+ * An animation for `exportScene`, from baked tracks, each checked against the
890
+ * tree it will be exported with.
891
+ *
892
+ * The exporter drops a whole animation when one track fails to bind, and
893
+ * throws when a morph target name is missing from the mesh's
894
+ * `morphTargetDictionary`. So each track is bound here first, by node name
895
+ * (`exportScene` clones a root that is not a `Scene`, which keeps names and
896
+ * changes uuids), and a track that would not bind is left out and reported.
897
+ */
898
+ declare function createExportAnimation(options: {
899
+ name: string;
900
+ /** In seconds. */
901
+ duration: number;
902
+ tracks: ReadonlyArray<ExportAnimationTrack>;
903
+ /** The tree the animation will be exported with. */
904
+ root: ExportAnimationRoot;
905
+ }): ExportAnimationResult;
906
+
797
907
  /**
798
908
  * Build the three.js graph of the world element `rootId` and its descendants,
799
909
  * for `exportScene`.
@@ -803,6 +913,12 @@ declare function exportScene(root: THREE.Object3D, options?: ExportSceneOptions)
803
913
  * them, with the element's `RobotData` in `userData`. No renderer is involved,
804
914
  * so this runs in Node.
805
915
  *
916
+ * A compound feature — translation, rotation, scale, a colour — is read whole,
917
+ * per axis (`translation.x`, `rotation.r`, `color.g`: Semio Studio's form),
918
+ * or both, a component given per axis standing over the whole value's. A
919
+ * rotation is an euler `{ x, y, z }` or, as Studio names it, `{ r, p, y }`
920
+ * (roll, pitch, yaw), applied in ZYX order.
921
+ *
806
922
  * Every feature takes its authored value: a static feature its value, an
807
923
  * animated one its animatable's `default` in `animatables`. Node translation,
808
924
  * rotation and scale, morph weights and material factors in the exported file
@@ -810,9 +926,14 @@ declare function exportScene(root: THREE.Object3D, options?: ExportSceneOptions)
810
926
  * pose. A caller that wants other values in the file passes them as the
811
927
  * defaults of `animatables`.
812
928
  *
813
- * Throws when an element is missing from `world`, when an animated feature
814
- * names an animatable missing from `animatables`, and for ellipse and
815
- * rectangle elements, which have no exported form.
929
+ * An ellipse or a rectangle becomes a node with no mesh: its RobotData —
930
+ * `type`, `width`, `height`, `fillColor`, `fillOpacity` among its features —
931
+ * is what the Bevy view draws it from (a unit circle or square scaled by the
932
+ * width and height, filled with the colour and opacity). The node carries its
933
+ * translation and rotation, and the width and height as its scale on X and Y.
934
+ *
935
+ * Throws when an element is missing from `world`, and when an animated
936
+ * feature names an animatable missing from `animatables`.
816
937
  */
817
938
  declare function buildSceneGraph(world: World, animatables: Record<string, AnimatableValue>, rootId: string): THREE.Object3D;
818
939
 
@@ -854,4 +975,4 @@ declare function sanitizeMorphKey(name: string, fallbackIndex: number, used: Set
854
975
  */
855
976
  declare function deriveMorphFeatureKeys(names: ReadonlyArray<string>): string[];
856
977
 
857
- export { type AnimatedFeature, DEFAULT_TONE_MAPPING_MODE, type Ellipse, type EllipseFeature, EmptyModelError, type ExportSceneOptions, type Feature, type Group, type GroupFeature, InnerVizij, type InnerVizijProps, type LoadedVizijAsset, type Rectangle, type RectangleFeature, type RenderableBase, type RenderableFeature, type Selection, type Shape, type ShapeFeature, ShapeMaterial, type StaticFeature, type Stored, type StoredAnimatedFeature, type StoredEllipse, type StoredFeatures, type StoredGroup, type StoredRectangle, type StoredRenderable, type StoredShape, TONE_MAPPING_LABELS, TONE_MAPPING_MODES, type ToneMappingMode, Vizij, type VizijActions, type VizijAnimationClipData, type VizijAnimationId, type VizijAnimationTrackData, type VizijBundleAnimationClip, type VizijBundleAnimationEntry, type VizijBundleAnimationKeyframe, type VizijBundleAnimationTrack, type VizijBundleExtension, type VizijBundleGraphEntry, type VizijBundleGraphKind, type VizijBundleGraphMetadata, type VizijBundlePoseSection, type VizijBundleProfile, type VizijBundleStarredSection, type VizijBundleVersion, VizijContext, type VizijData, type VizijGraphId, type VizijPoseDefinition, type VizijPoseId, type VizijPoseRigConfig, type VizijProfileKey, type VizijProps, VizijSlice, type VizijSpeechConfig, type VizijStarredItem, type VizijStarredKind, type VizijStore, type VizijStoreGetter, type VizijStoreSetter, type World, applyVizijBundle, buildSceneGraph, createVizijStore, deriveMorphFeatureKeys, deriveRootBounds, exportScene, extractVizijBundle, isToneMappingMode, loadGLTF, loadGLTFFromBlob, loadGLTFFromBlobWithBundle, loadGLTFWithBundle, normalizeToneMappingMode, parseGlbJsonChunk, patchGlbJson, patchVizijBundleMetadata, resolveToneMapping, sanitizeMorphKey, useDefaultVizijStore, useFeatures, useVizijStore, useVizijStoreGetter, useVizijStoreSetter, useVizijStoreSubscription };
978
+ export { type AnimatedFeature, type ColorAxis, DEFAULT_TONE_MAPPING_MODE, type Ellipse, type EllipseFeature, EmptyModelError, type ExportAnimationIssue, type ExportAnimationProperty, type ExportAnimationResult, type ExportAnimationRoot, type ExportAnimationTrack, type ExportSceneOptions, type Feature, type Group, type GroupFeature, type LoadedVizijAsset, type LoadingStage, type PerAxisFeatures, type PerAxisTransformFeatures, type Rectangle, type RectangleFeature, type RenderableBase, type RenderableFeature, type RotationAxis, type Selection, type Shape, type ShapeFeature, ShapeMaterial, type StaticFeature, type Stored, type StoredAnimatedFeature, type StoredEllipse, type StoredFeatures, type StoredGroup, type StoredRectangle, type StoredRenderable, type StoredShape, TONE_MAPPING_LABELS, TONE_MAPPING_MODES, type ToneMappingMode, type VectorAxis, Vizij, type VizijActions, type VizijAnimationClipData, type VizijAnimationId, type VizijAnimationTrackData, type VizijBundleAnimationClip, type VizijBundleAnimationEntry, type VizijBundleAnimationKeyframe, type VizijBundleAnimationTrack, type VizijBundleExtension, type VizijBundleGraphEntry, type VizijBundleGraphKind, type VizijBundleGraphMetadata, type VizijBundlePoseSection, type VizijBundleProfile, type VizijBundleStarredSection, type VizijBundleVersion, VizijCanvas, type VizijCanvasProps, VizijContext, type VizijData, type VizijGraphId, type VizijLoading, type VizijPoseDefinition, type VizijPoseId, type VizijPoseRigConfig, type VizijProfileKey, type VizijProgress, type VizijProps, VizijSlice, type VizijSpeechConfig, type VizijStarredItem, type VizijStarredKind, type VizijStore, type VizijStoreGetter, type VizijStoreSetter, type World, applyVizijBundle, buildSceneGraph, canvasMounted, createExportAnimation, createVizijStore, deriveMorphFeatureKeys, deriveRootBounds, exportScene, extractVizijBundle, isToneMappingMode, loadGLTF, loadGLTFFromBlob, loadGLTFFromBlobWithBundle, loadGLTFWithBundle, normalizeToneMappingMode, parseGlbJsonChunk, patchGlbJson, patchVizijBundleMetadata, sanitizeMorphKey, setVizijProgress, useDefaultVizijStore, useVizijStore, useVizijStoreGetter, useVizijStoreSetter, useVizijStoreSubscription };