@liveroom-tech/react-immersive 5.0.2 → 5.2.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 +1030 -59
- package/dist/binding-builder.css +1 -1
- package/dist/binding-builder.js +17 -12
- package/dist/binding-builder.mjs +1 -1
- package/dist/chunk-4NLJSD3S.mjs +1 -0
- package/dist/chunk-B7REIGDG.mjs +1 -0
- package/dist/chunk-HYFJ5DYJ.mjs +1 -0
- package/dist/chunk-QC3NT76G.mjs +3 -0
- package/dist/chunk-T3M3BQ7H.mjs +32 -0
- package/dist/chunk-ZPK67UG7.mjs +1 -0
- package/dist/hosted.css +1 -1
- package/dist/hosted.d.mts +4 -3
- package/dist/hosted.d.ts +4 -3
- package/dist/hosted.js +16 -11
- package/dist/hosted.mjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.mts +85 -10
- package/dist/index.d.ts +85 -10
- package/dist/index.js +15 -10
- package/dist/index.mjs +1 -1
- package/dist/materialVariants-DnZe9eMC.d.mts +309 -0
- package/dist/materialVariants-DnZe9eMC.d.ts +309 -0
- package/dist/modelInfo-BYebMPdZ.d.mts +43 -0
- package/dist/modelInfo-XfUQO7C_.d.ts +43 -0
- package/dist/{ModelViewer-CbbJT85n.d.mts → modelViewerProps-CIZ2R_Fv.d.ts} +164 -43
- package/dist/{ModelViewer-DOexHkJC.d.ts → modelViewerProps-DoRiTZMn.d.mts} +164 -43
- package/dist/{objectCatalog-5W8n5xNQ.d.ts → rendererBackend-QwMzISTn.d.mts} +304 -5
- package/dist/{objectCatalog-5W8n5xNQ.d.mts → rendererBackend-QwMzISTn.d.ts} +304 -5
- package/dist/simple-model-viewer.css +1 -1
- package/dist/simple-model-viewer.d.mts +32 -4
- package/dist/simple-model-viewer.d.ts +32 -4
- package/dist/simple-model-viewer.js +3 -3
- package/dist/simple-model-viewer.mjs +1 -1
- package/dist/utils.d.mts +5 -4
- package/dist/utils.d.ts +5 -4
- package/dist/utils.js +1 -1
- package/dist/utils.mjs +1 -1
- package/package.json +2 -1
- package/dist/chunk-3GX7DOGS.mjs +0 -3
- package/dist/chunk-AH5NAZWX.mjs +0 -27
- package/dist/chunk-BGYK4Y2Y.mjs +0 -1
- package/dist/chunk-WFEYRUZC.mjs +0 -1
- package/dist/chunk-XTLSAYAQ.mjs +0 -1
- package/dist/modelInfo-CEmmvVCH.d.mts +0 -17
- package/dist/modelInfo-CEmmvVCH.d.ts +0 -17
|
@@ -104,6 +104,12 @@ type SceneModelConfig = {
|
|
|
104
104
|
shading: "lit" | "unlit" | "normals";
|
|
105
105
|
autoRotate?: boolean;
|
|
106
106
|
autoRotateSpeed?: number;
|
|
107
|
+
/**
|
|
108
|
+
* The glTF material variants (KHR_materials_variants) to show, by name: at
|
|
109
|
+
* most one from each option group (see `MaterialVariantGroup`). Empty, or
|
|
110
|
+
* left out, for the model's default materials.
|
|
111
|
+
*/
|
|
112
|
+
activeVariants?: string[];
|
|
107
113
|
};
|
|
108
114
|
type SceneCameraConfig = {
|
|
109
115
|
fieldOfView: number;
|
|
@@ -149,7 +155,7 @@ type SceneGroundShadowConfig = {
|
|
|
149
155
|
height: number;
|
|
150
156
|
size: number;
|
|
151
157
|
};
|
|
152
|
-
declare const ANIMATION_LOOP_MODES: readonly ["repeat", "once"];
|
|
158
|
+
declare const ANIMATION_LOOP_MODES: readonly ["repeat", "once", "ping-pong"];
|
|
153
159
|
type AnimationLoopMode = (typeof ANIMATION_LOOP_MODES)[number];
|
|
154
160
|
type SceneAnimationClipConfig = {
|
|
155
161
|
sourceName: string;
|
|
@@ -355,6 +361,22 @@ type ScenePostProcessingConfig = {
|
|
|
355
361
|
rampInvert: boolean;
|
|
356
362
|
};
|
|
357
363
|
};
|
|
364
|
+
type SceneAnnotationCameraView = {
|
|
365
|
+
position: [number, number, number];
|
|
366
|
+
target: [number, number, number];
|
|
367
|
+
azimuthAngle?: number;
|
|
368
|
+
polarAngle?: number;
|
|
369
|
+
fov?: number | null;
|
|
370
|
+
zoom?: number;
|
|
371
|
+
};
|
|
372
|
+
type SceneAnnotationImage = {
|
|
373
|
+
src: string;
|
|
374
|
+
alt?: string;
|
|
375
|
+
};
|
|
376
|
+
type SceneAnnotationLink = {
|
|
377
|
+
href: string;
|
|
378
|
+
label: string;
|
|
379
|
+
};
|
|
358
380
|
type SceneAnnotationMarker = {
|
|
359
381
|
id: number;
|
|
360
382
|
worldPosition: [number, number, number];
|
|
@@ -364,6 +386,14 @@ type SceneAnnotationMarker = {
|
|
|
364
386
|
anchorLocalPosition?: [number, number, number];
|
|
365
387
|
title: string;
|
|
366
388
|
description: string;
|
|
389
|
+
/** World-space camera framing restored on selection and during tours. */
|
|
390
|
+
cameraView?: SceneAnnotationCameraView;
|
|
391
|
+
images?: SceneAnnotationImage[];
|
|
392
|
+
links?: SceneAnnotationLink[];
|
|
393
|
+
category?: string;
|
|
394
|
+
/** Inclusive camera-to-marker distance bounds, in scene units. */
|
|
395
|
+
minDistance?: number;
|
|
396
|
+
maxDistance?: number;
|
|
367
397
|
};
|
|
368
398
|
type SceneCinematicWaypoint = {
|
|
369
399
|
position: [number, number, number];
|
|
@@ -384,6 +414,73 @@ type SceneCinematicConfig = {
|
|
|
384
414
|
loop: boolean;
|
|
385
415
|
autoPlay: boolean;
|
|
386
416
|
};
|
|
417
|
+
declare const SECTION_AXES: readonly ["x", "y", "z"];
|
|
418
|
+
type SceneSectionAxis = (typeof SECTION_AXES)[number];
|
|
419
|
+
type SceneSectionConfig = {
|
|
420
|
+
enabled: boolean;
|
|
421
|
+
/** The world axis the cut runs across; `"y"` gives a floor-plan cut. */
|
|
422
|
+
axis: SceneSectionAxis;
|
|
423
|
+
/**
|
|
424
|
+
* Where the cut is along the axis, as a share of the model's size: 0 at
|
|
425
|
+
* its minimum, 1 at its maximum.
|
|
426
|
+
*/
|
|
427
|
+
position: number;
|
|
428
|
+
/**
|
|
429
|
+
* Keep the part above the cut (the higher side along the axis) instead of
|
|
430
|
+
* the part below it.
|
|
431
|
+
*/
|
|
432
|
+
flip: boolean;
|
|
433
|
+
};
|
|
434
|
+
declare const DEFAULT_SECTION_CONFIG: SceneSectionConfig;
|
|
435
|
+
/**
|
|
436
|
+
* What an object's data must look like for a rule to apply to it. A list
|
|
437
|
+
* applies when every condition in it matches.
|
|
438
|
+
*/
|
|
439
|
+
type SceneStyleCondition = {
|
|
440
|
+
/** A key of `binding.metrics`. */
|
|
441
|
+
metric: string;
|
|
442
|
+
/** Applies when the value is greater than this. */
|
|
443
|
+
above?: number;
|
|
444
|
+
/** Applies when the value is less than this. */
|
|
445
|
+
below?: number;
|
|
446
|
+
} | {
|
|
447
|
+
status: ObjectBindingStatus | ObjectBindingStatus[];
|
|
448
|
+
} | {
|
|
449
|
+
/** A key of `binding.metadata`; dots reach into nested objects. */
|
|
450
|
+
metadata: string;
|
|
451
|
+
equals: string | number | boolean | null;
|
|
452
|
+
};
|
|
453
|
+
type SceneStyleColorScale = {
|
|
454
|
+
/** A key of `binding.metrics`. */
|
|
455
|
+
metric: string;
|
|
456
|
+
/**
|
|
457
|
+
* `[value, "#rrggbb"]` pairs. Values between two stops blend their colours;
|
|
458
|
+
* values outside the stops take the nearest one.
|
|
459
|
+
*/
|
|
460
|
+
stops: [number, string][];
|
|
461
|
+
/** The material colour it sets. Default `"baseColor"`. */
|
|
462
|
+
channel?: "baseColor" | "emissive";
|
|
463
|
+
};
|
|
464
|
+
type SceneStylePulse = {
|
|
465
|
+
/** The glow colour at the pulse's peak. Default `"#ff3b30"`. */
|
|
466
|
+
color?: string;
|
|
467
|
+
/** Pulses per second. Default `1`. */
|
|
468
|
+
speed?: number;
|
|
469
|
+
};
|
|
470
|
+
type SceneStyleRule = {
|
|
471
|
+
id: string;
|
|
472
|
+
label?: string;
|
|
473
|
+
/** The objects the rule considers; every bound object when left out. */
|
|
474
|
+
target?: ObjectBindingTarget;
|
|
475
|
+
/** When the rule applies; always, when left out. */
|
|
476
|
+
when?: SceneStyleCondition | SceneStyleCondition[];
|
|
477
|
+
/** Material overrides, over the object's own `style.material`. */
|
|
478
|
+
material?: ObjectBindingMaterial;
|
|
479
|
+
/** A colour taken from a metric's value. */
|
|
480
|
+
colorScale?: SceneStyleColorScale;
|
|
481
|
+
/** A glow that fades in and out, to draw attention. */
|
|
482
|
+
pulse?: boolean | SceneStylePulse;
|
|
483
|
+
};
|
|
387
484
|
type SceneConfig = {
|
|
388
485
|
model: SceneModelConfig;
|
|
389
486
|
camera: SceneCameraConfig;
|
|
@@ -397,6 +494,13 @@ type SceneConfig = {
|
|
|
397
494
|
animations: SceneAnimationConfig;
|
|
398
495
|
annotations: SceneAnnotationMarker[];
|
|
399
496
|
cinematic?: SceneCinematicConfig;
|
|
497
|
+
/**
|
|
498
|
+
* Data-driven looks for bound objects, applied in order, so a later rule
|
|
499
|
+
* wins over an earlier one where both set something.
|
|
500
|
+
*/
|
|
501
|
+
styleRules?: SceneStyleRule[];
|
|
502
|
+
/** A cut-away view across the model. Off when left out. */
|
|
503
|
+
section?: SceneSectionConfig;
|
|
400
504
|
};
|
|
401
505
|
declare const DEFAULT_SCENE_CONFIG: SceneConfig;
|
|
402
506
|
|
|
@@ -407,6 +511,146 @@ type SceneConfigPatch = DeepPartial<SceneConfig>;
|
|
|
407
511
|
*/
|
|
408
512
|
declare function patchSceneConfig(sceneConfig: SceneConfig, patch: SceneConfigPatch): SceneConfig;
|
|
409
513
|
|
|
514
|
+
type AnimationClipInfo = {
|
|
515
|
+
sourceName: string;
|
|
516
|
+
duration: number;
|
|
517
|
+
};
|
|
518
|
+
/** How `play` starts a clip. */
|
|
519
|
+
type AnimationPlayOptions = {
|
|
520
|
+
/**
|
|
521
|
+
* Keep the clips already playing, instead of stopping them, so several
|
|
522
|
+
* clips run at once (a left and a right door, say). Default `false`.
|
|
523
|
+
*/
|
|
524
|
+
alongside?: boolean;
|
|
525
|
+
/**
|
|
526
|
+
* Seconds to fade the clip in, and to fade out the clips it replaces, for a
|
|
527
|
+
* smooth blend between them. Default `0`.
|
|
528
|
+
*/
|
|
529
|
+
fade?: number;
|
|
530
|
+
/**
|
|
531
|
+
* Play backwards, from wherever the clip is, or from its end. Plays a
|
|
532
|
+
* "door opens" clip as the door closing. Default `false`.
|
|
533
|
+
*/
|
|
534
|
+
reverse?: boolean;
|
|
535
|
+
};
|
|
536
|
+
/**
|
|
537
|
+
* `"finished"`: a play-once clip that reached its end and holds its last pose
|
|
538
|
+
* until it's stopped or played again.
|
|
539
|
+
*/
|
|
540
|
+
type AnimationClipStatus = "playing" | "paused" | "finished";
|
|
541
|
+
/** One clip that is playing, paused, or holding its finished pose. */
|
|
542
|
+
type AnimationClipState = {
|
|
543
|
+
clip: string;
|
|
544
|
+
status: AnimationClipStatus;
|
|
545
|
+
/** Position in the clip, in seconds. */
|
|
546
|
+
time: number;
|
|
547
|
+
/** Length of the clip, in seconds. */
|
|
548
|
+
duration: number;
|
|
549
|
+
speed: number;
|
|
550
|
+
reverse: boolean;
|
|
551
|
+
};
|
|
552
|
+
type AnimationPlaybackState = {
|
|
553
|
+
/** The clip played most recently, while it's active. */
|
|
554
|
+
currentClip: string | null;
|
|
555
|
+
/** Whether any clip is playing. */
|
|
556
|
+
isPlaying: boolean;
|
|
557
|
+
speed: number;
|
|
558
|
+
time: number;
|
|
559
|
+
duration: number;
|
|
560
|
+
/** Every active clip, most recently played last. */
|
|
561
|
+
active: AnimationClipState[];
|
|
562
|
+
};
|
|
563
|
+
/**
|
|
564
|
+
* Leave out `clip` to act on every active clip; pass one to act on that clip
|
|
565
|
+
* alone.
|
|
566
|
+
*/
|
|
567
|
+
type AnimationControls = {
|
|
568
|
+
clips: string[];
|
|
569
|
+
clipDetails?: AnimationClipInfo[];
|
|
570
|
+
play: (clipName: string, options?: AnimationPlayOptions) => void;
|
|
571
|
+
pause: (clipName?: string) => void;
|
|
572
|
+
/** Stops and resets the pose. */
|
|
573
|
+
stop: (clipName?: string) => void;
|
|
574
|
+
/** Without a clip, also the speed of clips played later without their own. */
|
|
575
|
+
setSpeed: (speed: number, clipName?: string) => void;
|
|
576
|
+
seek?: (time: number, clipName?: string) => void;
|
|
577
|
+
getState?: () => AnimationPlaybackState;
|
|
578
|
+
subscribe?: (listener: (state: AnimationPlaybackState) => void) => () => void;
|
|
579
|
+
};
|
|
580
|
+
type ViewerAnimationsProps = {
|
|
581
|
+
clips: string[];
|
|
582
|
+
clipDetails: AnimationClipInfo[];
|
|
583
|
+
currentClip: string | null;
|
|
584
|
+
isPlaying: boolean;
|
|
585
|
+
speed: number;
|
|
586
|
+
time: number;
|
|
587
|
+
duration: number;
|
|
588
|
+
/** Every active clip, most recently played last. */
|
|
589
|
+
active: AnimationClipState[];
|
|
590
|
+
play: (clipName: string, options?: AnimationPlayOptions) => void;
|
|
591
|
+
pause: (clipName?: string) => void;
|
|
592
|
+
stop: (clipName?: string) => void;
|
|
593
|
+
setSpeed: (speed: number, clipName?: string) => void;
|
|
594
|
+
seek: (time: number, clipName?: string) => void;
|
|
595
|
+
handleAnimationsReady: (controls: AnimationControls) => void;
|
|
596
|
+
};
|
|
597
|
+
declare function useViewerAnimations(): ViewerAnimationsProps;
|
|
598
|
+
|
|
599
|
+
/** A glow cycling on one object, from its style rules. */
|
|
600
|
+
type StyledObjectPulse = {
|
|
601
|
+
color: string;
|
|
602
|
+
/** Pulses per second. */
|
|
603
|
+
speed: number;
|
|
604
|
+
};
|
|
605
|
+
type StyledObjectBindings = {
|
|
606
|
+
/**
|
|
607
|
+
* The bindings as the rules style them. A binding no rule changed is the
|
|
608
|
+
* same object as the one passed in.
|
|
609
|
+
*/
|
|
610
|
+
bindings: Record<string, ObjectBinding>;
|
|
611
|
+
/** Pulsing objects, by binding key. */
|
|
612
|
+
pulses: Record<string, StyledObjectPulse>;
|
|
613
|
+
/** The binding a styled one came from (itself when no rule changed it). */
|
|
614
|
+
sourceOf: (binding: ObjectBinding) => ObjectBinding;
|
|
615
|
+
};
|
|
616
|
+
/**
|
|
617
|
+
* The colour a colour scale gives a value: a blend of the two stops around it,
|
|
618
|
+
* or the nearest stop outside them. Null when there's no usable stop.
|
|
619
|
+
*/
|
|
620
|
+
declare function colorScaleValue(stops: SceneStyleColorScale["stops"], value: number): string | null;
|
|
621
|
+
/**
|
|
622
|
+
* Styles bindings with scene style rules, for rendering. Rules apply in order
|
|
623
|
+
* over each object's own `style.material`, so a later rule wins where two set
|
|
624
|
+
* the same thing. The bindings passed in are never changed.
|
|
625
|
+
*/
|
|
626
|
+
declare function applyStyleRules(bindings: Record<string, ObjectBinding>, rules: readonly SceneStyleRule[] | undefined): StyledObjectBindings;
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Objects to focus on. Everything else is ghosted (drawn faintly) or hidden
|
|
630
|
+
* until the isolation is cleared, without changing any binding.
|
|
631
|
+
*/
|
|
632
|
+
type ViewerIsolation = {
|
|
633
|
+
/** The objects that stay: an id, a list of ids, `{ group }`, `{ tag }`, or `{ type }`. */
|
|
634
|
+
target: ObjectBindingTarget;
|
|
635
|
+
/** What happens to everything else. Default `"ghost"`. */
|
|
636
|
+
mode?: "ghost" | "hide";
|
|
637
|
+
/** How visible ghosted objects are, 0–1. Default `0.12`. */
|
|
638
|
+
ghostOpacity?: number;
|
|
639
|
+
};
|
|
640
|
+
type IsolatedObjectBindings = StyledObjectBindings & {
|
|
641
|
+
/** Binding keys that are ghosted or hidden. Pointer picking ignores them. */
|
|
642
|
+
setAside: Set<string>;
|
|
643
|
+
};
|
|
644
|
+
/** The binding keys an isolation keeps; empty when it keeps nothing. */
|
|
645
|
+
declare function isolatedBindingKeys(bindings: Record<string, ObjectBinding>, isolation: ViewerIsolation | null | undefined): Set<string>;
|
|
646
|
+
/**
|
|
647
|
+
* Ghosts or hides every object an isolation doesn't keep, for rendering. The
|
|
648
|
+
* bindings passed in are never changed. An isolation that keeps nothing (a
|
|
649
|
+
* target matching no object) changes nothing either, rather than fading out
|
|
650
|
+
* the whole model.
|
|
651
|
+
*/
|
|
652
|
+
declare function applyIsolation(styled: StyledObjectBindings, isolation: ViewerIsolation | null | undefined): IsolatedObjectBindings;
|
|
653
|
+
|
|
410
654
|
type ObjectBindingsActionEffect = {
|
|
411
655
|
target: ObjectBindingTarget;
|
|
412
656
|
objectBindings: ObjectBindingPatch;
|
|
@@ -437,24 +681,36 @@ type CameraAction = {
|
|
|
437
681
|
type CameraActionEffect = {
|
|
438
682
|
camera: CameraAction;
|
|
439
683
|
};
|
|
440
|
-
|
|
684
|
+
/**
|
|
685
|
+
* `play` replaces the clips already playing unless `alongside` is set. The
|
|
686
|
+
* others act on `clip`, or on every active clip when it's left out.
|
|
687
|
+
*/
|
|
688
|
+
type AnimationAction = ({
|
|
441
689
|
type: "play";
|
|
442
690
|
clip: string;
|
|
443
|
-
} | {
|
|
691
|
+
} & AnimationPlayOptions) | {
|
|
444
692
|
type: "pause";
|
|
693
|
+
clip?: string;
|
|
445
694
|
} | {
|
|
446
695
|
type: "stop";
|
|
696
|
+
clip?: string;
|
|
447
697
|
} | {
|
|
448
698
|
type: "set-speed";
|
|
449
699
|
speed: number;
|
|
700
|
+
clip?: string;
|
|
450
701
|
} | {
|
|
451
702
|
type: "seek";
|
|
452
703
|
time: number;
|
|
704
|
+
clip?: string;
|
|
453
705
|
};
|
|
454
706
|
type AnimationActionEffect = {
|
|
455
707
|
animation: AnimationAction;
|
|
456
708
|
};
|
|
457
|
-
|
|
709
|
+
/** Isolates objects, or with `null` shows everything again. */
|
|
710
|
+
type IsolationActionEffect = {
|
|
711
|
+
isolation: ViewerIsolation | null;
|
|
712
|
+
};
|
|
713
|
+
type ObjectActionEffect = IsolationActionEffect | ObjectBindingsActionEffect | SceneConfigActionEffect | VisibilityActionEffect | CameraActionEffect | AnimationActionEffect;
|
|
458
714
|
|
|
459
715
|
type ObjectBindingAction = {
|
|
460
716
|
id: "change-color" | "apply-texture" | "toggle-visibility" | string;
|
|
@@ -549,6 +805,33 @@ type ObjectBindingCameraState = {
|
|
|
549
805
|
fov?: number;
|
|
550
806
|
zoom?: number;
|
|
551
807
|
};
|
|
808
|
+
/**
|
|
809
|
+
* An image or a line of text printed onto the object's surface: a logo, a
|
|
810
|
+
* label, a personalisation.
|
|
811
|
+
*/
|
|
812
|
+
type ObjectBindingDecal = {
|
|
813
|
+
id: string;
|
|
814
|
+
/** The image to show: a URL or public path. */
|
|
815
|
+
image?: string;
|
|
816
|
+
/** Text to show, when there's no image. */
|
|
817
|
+
text?: string;
|
|
818
|
+
/** Text colour. Default `"#ffffff"`. */
|
|
819
|
+
color?: string;
|
|
820
|
+
/** CSS font family for the text. Default `"sans-serif"`. */
|
|
821
|
+
fontFamily?: string;
|
|
822
|
+
/** Default `"bold"`. */
|
|
823
|
+
fontWeight?: "normal" | "bold";
|
|
824
|
+
/** Where it sits on the object, in the object's own (local) space. */
|
|
825
|
+
position: [number, number, number];
|
|
826
|
+
/** The way the surface faces there, in the object's own space. */
|
|
827
|
+
normal: [number, number, number];
|
|
828
|
+
/** Width, in model units; the height follows the image or text's shape. */
|
|
829
|
+
size: number;
|
|
830
|
+
/** A turn around the surface normal, in radians. Default `0`. */
|
|
831
|
+
rotation?: number;
|
|
832
|
+
/** 0–1. Default `1`. */
|
|
833
|
+
opacity?: number;
|
|
834
|
+
};
|
|
552
835
|
type ObjectBindingStyle = {
|
|
553
836
|
material?: ObjectBindingMaterial;
|
|
554
837
|
};
|
|
@@ -566,6 +849,8 @@ type ObjectBinding = {
|
|
|
566
849
|
hoverable?: boolean;
|
|
567
850
|
transform?: ObjectBindingTransform;
|
|
568
851
|
style?: ObjectBindingStyle;
|
|
852
|
+
/** Images and text printed on the object's surface. */
|
|
853
|
+
decals?: ObjectBindingDecal[];
|
|
569
854
|
actions?: ObjectBindingAction[];
|
|
570
855
|
metrics?: Record<string, number>;
|
|
571
856
|
metadata?: Record<string, unknown>;
|
|
@@ -578,6 +863,12 @@ type ObjectActionEvent = {
|
|
|
578
863
|
screenX?: number;
|
|
579
864
|
screenY?: number;
|
|
580
865
|
};
|
|
866
|
+
/** A point on an object's surface, in the object's own (local) space. */
|
|
867
|
+
type ObjectSurfacePoint = {
|
|
868
|
+
position: [number, number, number];
|
|
869
|
+
/** The way the surface faces at that point. */
|
|
870
|
+
normal: [number, number, number];
|
|
871
|
+
};
|
|
581
872
|
/** A double-click, right-click, or long-press on a model object. */
|
|
582
873
|
type ObjectPointerEvent = {
|
|
583
874
|
binding: ObjectBinding;
|
|
@@ -586,6 +877,11 @@ type ObjectPointerEvent = {
|
|
|
586
877
|
clientY: number;
|
|
587
878
|
/** `"mouse"`, `"pen"`, or `"touch"`. */
|
|
588
879
|
pointerType: string;
|
|
880
|
+
/**
|
|
881
|
+
* Where on the object the pointer was, e.g. to place a decal there. Not
|
|
882
|
+
* reported for streamed (3D Tiles) models.
|
|
883
|
+
*/
|
|
884
|
+
surface?: ObjectSurfacePoint;
|
|
589
885
|
};
|
|
590
886
|
|
|
591
887
|
/** One bindable object in a model, as reported by `onObjectCatalog`. */
|
|
@@ -601,4 +897,7 @@ type ViewerObjectInfo = {
|
|
|
601
897
|
maximum: [number, number, number];
|
|
602
898
|
};
|
|
603
899
|
|
|
604
|
-
|
|
900
|
+
/** Which three.js renderer draws a viewer. */
|
|
901
|
+
type RendererBackend = "webgl" | "webgpu";
|
|
902
|
+
|
|
903
|
+
export { type SceneCinematicConfig as $, type AnimationAction as A, type BindingEdit as B, type CameraAction as C, DEFAULT_SCENE_CONFIG as D, type EnvironmentPreset as E, type ObjectBindingTextureChannel as F, type GlitchModeName as G, type ObjectBindingTextureSlot as H, type IsolatedObjectBindings as I, type ObjectBindingTransform as J, type KernelSizeName as K, type ObjectBindingType as L, MATERIAL_BLENDING_MODES as M, type ObjectBindingsActionEffect as N, type ObjectActionEffect as O, type ObjectPointerEvent as P, type ObjectSurfacePoint as Q, type RampTypeName as R, type RendererBackend as S, type SceneAnimationClipConfig as T, type SceneAnimationConfig as U, type SceneAnnotationCameraView as V, type SceneAnnotationImage as W, type SceneAnnotationLink as X, type SceneAnnotationMarker as Y, type SceneBackgroundConfig as Z, type SceneCameraConfig as _, type AnimationActionEffect as a, type SceneCinematicWaypoint as a0, type SceneConfig as a1, type SceneConfigActionEffect as a2, type SceneConfigPatch as a3, type SceneEnvironmentConfig as a4, type SceneGroundShadowConfig as a5, type SceneLight as a6, type SceneLightAttachment as a7, type SceneLightType as a8, type SceneLightingConfig as a9, selectBindingKeys as aA, selectBindings as aB, useViewerAnimations as aC, type SceneModelConfig as aa, type SceneModelRenderer as ab, type ScenePostProcessingConfig as ac, type SceneSectionAxis as ad, type SceneSectionConfig as ae, type SceneShadowConfig as af, type SceneStyleColorScale as ag, type SceneStyleCondition as ah, type SceneStylePulse as ai, type SceneStyleRule as aj, type SceneWireframeConfig as ak, type StyledObjectBindings as al, type StyledObjectPulse as am, type ViewerAnimationsProps as an, type ViewerCameraConfig as ao, type ViewerCameraState as ap, type ViewerIsolation as aq, type ViewerObjectInfo as ar, type VisibilityActionEffect as as, applyIsolation as at, applyStyleRules as au, colorScaleValue as av, isolatedBindingKeys as aw, material as ax, patchBindings as ay, patchSceneConfig as az, type AnimationClipInfo as b, type AnimationClipState as c, type AnimationClipStatus as d, type AnimationControls as e, type AnimationLoopMode as f, type AnimationPlayOptions as g, type AnimationPlaybackState as h, type CameraActionEffect as i, DEFAULT_SECTION_CONFIG as j, type DeepPartial as k, type IsolationActionEffect as l, MATERIAL_SIDES as m, type ObjectActionEvent as n, type ObjectBinding as o, type ObjectBindingAction as p, type ObjectBindingCameraState as q, type ObjectBindingDecal as r, type ObjectBindingMaterial as s, type ObjectBindingMaterialBlendingMode as t, type ObjectBindingMaterialSide as u, type ObjectBindingPatch as v, type ObjectBindingSelector as w, type ObjectBindingStatus as x, type ObjectBindingStyle as y, type ObjectBindingTarget as z };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.bb-loadingOverlay{position:absolute;inset:0;z-index:5;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;padding:24px;text-align:center;border-radius:14px;background:#f8fafcd1;backdrop-filter:blur(2px)}.bb-loadingSpinner{width:40px;height:40px;border-radius:999px;border:3px solid rgba(148,163,184,.3);border-top-color:#2563eb;animation:bb-spin .8s linear infinite}.bb-loadingProgressRow{display:flex;align-items:center;gap:8px;width:100%;max-width:240px}.bb-loadingProgress{flex:1;height:6px;border-radius:999px;background:#94a3b84d;overflow:hidden}.bb-loadingProgress__bar{height:100%;border-radius:inherit;background:#2563eb;transition:width .15s ease-out}.bb-loadingProgress__label{flex-shrink:0;min-width:34px;text-align:right;color:#475569;font-size:12px;font-weight:600;font-variant-numeric:tabular-nums}.bb-loadingMessage{max-width:320px;color:#475569;font-size:13px;font-weight:600;line-height:1.5}:root{--ri-styles-simple-model-viewer: 1}.smv-root{--smv-panel-font-family: Inter, "Segoe UI", Helvetica, Arial, sans-serif;--smv-panel-bg: #141824;--smv-panel-bg-strong: #1a1f2e;--smv-panel-bg-strong-hover: #252b3b;--smv-panel-border: rgba(255, 255, 255, .06);--smv-panel-border-strong: rgba(255, 255, 255, .08);--smv-panel-border-active: rgba(255, 255, 255, .18);--smv-panel-shadow-left: 4px 0 24px rgba(0, 0, 0, .35);--smv-panel-shadow-right: -4px 0 24px rgba(0, 0, 0, .35);--smv-panel-text: #f1f5f9;--smv-panel-text-emphasis: #ffffff;--smv-panel-text-muted: #94a3b8;--smv-panel-text-subtle: #64748b;--smv-panel-surface: rgba(255, 255, 255, .05);--smv-panel-surface-hover: rgba(255, 255, 255, .1);--smv-panel-surface-soft: rgba(255, 255, 255, .04);--smv-panel-accent: #3b82f6;--smv-panel-accent-contrast: #ffffff;position:relative;width:100%;height:100%;min-height:0;overflow:hidden;display:flex;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;font-synthesis:none}.smv-canvasArea{flex:1;position:relative;min-width:0}.smv-upload-input{display:none}.smv-upload-toolbar{position:absolute;top:12px;left:50%;z-index:120;display:flex;align-items:center;gap:10px;max-width:calc(100% - 32px);padding:5px 6px;border:1px solid var(--smv-panel-border-strong);border-radius:10px;background:#141824e0;color:var(--smv-panel-text);box-shadow:0 16px 30px #00000047;backdrop-filter:blur(14px);transform:translate(-50%)}.smv-upload-toolbar__name{max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--smv-panel-text-muted);font-size:12px;font-weight:500}.smv-upload-toolbar__button{display:inline-flex;align-items:center;gap:7px;min-height:34px;padding:0 14px;border:1px solid rgba(255,255,255,.08);border-radius:10px;background:#3b82f62e;color:var(--smv-panel-text-emphasis);font-size:12px;font-weight:600;cursor:pointer}.smv-upload-toolbar__button--ghost{background:var(--smv-panel-surface);color:var(--smv-panel-text-muted)}.smv-upload-empty-state{display:flex;align-items:center;justify-content:center;width:100%;height:100%;padding:24px}.smv-upload-empty-state__card{width:min(440px,100%);padding:28px;border:1px dashed rgba(255,255,255,.2);border-radius:8px;color:var(--smv-panel-text);text-align:center;box-shadow:0 24px 40px #00000047;backdrop-filter:blur(14px)}.smv-upload-empty-state__icon{display:inline-flex;align-items:center;justify-content:center;width:56px;height:56px;margin-bottom:18px;border-radius:10px;background:#3b82f62e;color:#bfdbfe}.smv-upload-empty-state__title{margin:0 0 10px;color:var(--smv-panel-text-emphasis);font-size:24px;line-height:1.15}.smv-upload-empty-state__body{margin:0 0 18px;color:var(--smv-panel-text-muted);font-size:14px;font-weight:700;line-height:1.6}.smv-upload-empty-state__body code{color:var(--smv-panel-text-emphasis);font-family:var(--smv-panel-font-family)}.smv-upload-empty-state__button{display:inline-flex;align-items:center;gap:8px;min-height:40px;padding:0 18px;border:none;border-radius:8px;background:#3b82f6;color:#eff6ff;font-size:13px;font-weight:700;cursor:pointer}.smv-upload-drop-overlay{position:absolute;inset:0;z-index:130;display:flex;align-items:center;justify-content:center;padding:24px;background:#080c147a;backdrop-filter:blur(4px)}.smv-upload-drop-overlay__card{display:inline-flex;align-items:center;gap:10px;padding:16px 20px;border:1px dashed rgba(191,219,254,.75);border-radius:10px;background:#1e293beb;color:#dbeafe;font-size:14px;font-weight:700;box-shadow:0 18px 36px #00000047}.smv-canvasArea .bb-loadingOverlay{position:absolute;inset:0;z-index:110;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;padding:24px;text-align:center;border-radius:14px;background:#0f172a75;backdrop-filter:blur(1px)}.smv-canvasArea .bb-loadingSpinner{width:40px;height:40px;border-radius:999px;border:3px solid rgba(226,232,240,.24);border-top-color:#93c5fd;animation:bb-spin .8s linear infinite}.smv-canvasArea .bb-loadingProgressRow{display:flex;align-items:center;gap:8px;width:100%;max-width:240px}.smv-canvasArea .bb-loadingProgress{flex:1;height:6px;border-radius:999px;background:#e2e8f03d;overflow:hidden}.smv-canvasArea .bb-loadingProgress__bar{height:100%;border-radius:inherit;background:#93c5fd;transition:width .15s ease-out}.smv-canvasArea .bb-loadingProgress__label{flex-shrink:0;min-width:34px;text-align:right;color:#f7f8fa;font-size:12px;font-weight:600;font-variant-numeric:tabular-nums}.smv-canvasArea .bb-loadingMessage{max-width:320px;color:#f7f8fa;font-size:13px;font-weight:600;line-height:1.5}@keyframes bb-spin{to{transform:rotate(360deg)}}.right-panel-wrapper{height:100%;transition:width .45s cubic-bezier(.4,0,.2,1);overflow:visible}.right-panel-wrapper--open{width:300px;flex-shrink:0}.right-panel-wrapper--closed{width:0;flex-shrink:0}.left-panel-wrapper{height:100%;transition:width .45s cubic-bezier(.4,0,.2,1);overflow:visible;order:-1}.left-panel-wrapper--open{width:280px;flex-shrink:0}.left-panel-wrapper--closed{width:0;flex-shrink:0}.side-panel__open-btn.side-panel__open-btn--left{left:12px;right:auto}.side-panel.side-panel--left{left:0;right:auto;width:280px;transform:translate(-100%);border-left:none;border-right:1px solid var(--smv-panel-border);box-shadow:var(--smv-panel-shadow-left)}.side-panel.side-panel--open-left{transform:translate(0)}.side-panel.side-panel--closed-left{transform:translate(-100%)}.env-controls{display:flex;flex-direction:column;overflow-y:auto;flex:1}.env-section{border-bottom:1px solid var(--smv-panel-border-strong)}.env-section__header{display:flex;align-items:center;gap:6px;width:100%;padding:9px 14px;border:none;background:var(--smv-panel-surface-soft);color:var(--smv-panel-text-muted);font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;cursor:pointer}.env-section__chevron{transition:transform .15s}.env-section__chevron--collapsed{transform:rotate(-90deg)}.env-section__body{display:flex;flex-direction:column}.env-row{display:flex;gap:6px;align-items:center;min-height:32px;border-bottom:1px solid var(--smv-panel-surface)}.env-row__label{flex:0 0 42%;padding:0 0 0 14px;font-size:11.5px;font-weight:500;color:var(--smv-panel-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.env-row__value{flex:1;display:flex;align-items:center;padding:5px 10px 5px 8px;min-width:0}.env-row__value--slider{gap:6px}.env-checkbox-btn{display:flex;align-items:center;cursor:pointer;background:none;border:none;padding:0}.env-checkbox{width:15px;height:15px;border-radius:3px;border:1.5px solid var(--smv-panel-border-active);background:var(--smv-panel-surface-soft);display:flex;align-items:center;justify-content:center;transition:background .15s,border-color .15s}.env-checkbox--checked{background:var(--smv-panel-accent);border-color:var(--smv-panel-accent)}.env-select{width:100%;padding:5px 8px;border-radius:4px;border:none;background:var(--smv-panel-surface-hover);color:var(--smv-panel-text);font-size:11.5px;outline:none;box-sizing:border-box;text-transform:capitalize}.env-color-swatch{position:relative;width:100%;height:22px;border-radius:4px;border:1px solid rgba(255,255,255,.15);display:flex;align-items:center;justify-content:center;overflow:hidden;cursor:pointer}.env-color-swatch__hex{font-size:10.5px;font-weight:700;color:#0f172a;text-shadow:0 1px 1px rgba(255,255,255,.35);pointer-events:none;text-transform:uppercase}.env-color-swatch__input{position:absolute;inset:0;width:100%;height:100%;border:none;padding:0;opacity:0;cursor:pointer}.env-slider{flex:1;accent-color:var(--smv-panel-accent);cursor:pointer;min-width:0}.env-slider__value{flex-shrink:0;min-width:32px;padding:2px 5px;border-radius:4px;background:var(--smv-panel-surface-hover);color:var(--smv-panel-accent);font-size:10.5px;font-weight:600;text-align:center}.side-panel__open-btn{position:absolute;top:12px;right:12px;display:flex;align-items:center;gap:7px;padding:7px 13px;border-radius:7px;border:1px solid var(--smv-panel-border-strong);background:var(--smv-panel-bg-strong);cursor:pointer;font-size:13px;font-weight:500;color:var(--smv-panel-text);z-index:190;transition:background .15s}.side-panel__open-btn:hover{background:var(--smv-panel-bg-strong-hover)}.side-panel{position:absolute;top:0;right:0;width:300px;height:100%;background:var(--smv-panel-bg);display:flex;flex-direction:column;font-family:var(--smv-panel-font-family);transform:translate(100%);transition:transform .45s cubic-bezier(.4,0,.2,1);z-index:200;border-left:1px solid var(--smv-panel-border);box-shadow:var(--smv-panel-shadow-right)}.side-panel--open{transform:translate(0)}.side-panel--closed{transform:translate(100%)}.side-panel__header{padding:24px 20px 16px;border-bottom:1px solid var(--smv-panel-border-strong)}.side-panel__header-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:4px}.side-panel__eyebrow{font-size:15px;font-weight:700;letter-spacing:.12em;color:var(--smv-panel-text-subtle);text-transform:uppercase}.side-panel__title{font-size:22px;font-weight:700;color:var(--smv-panel-text);margin:0;line-height:1.2}.side-panel__close-btn{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:8px;border:1px solid var(--smv-panel-border-strong);background:var(--smv-panel-surface);cursor:pointer;color:var(--smv-panel-text-muted);transition:background .15s,color .15s;flex-shrink:0}.side-panel__close-btn:hover{background:var(--smv-panel-surface-hover);color:var(--smv-panel-text)}.side-panel__search-wrap{padding:14px 16px;border-bottom:1px solid var(--smv-panel-border-strong)}.side-panel__search{width:100%;padding:10px 14px;border-radius:10px;border:1px solid var(--smv-panel-border-strong);background:var(--smv-panel-surface);color:var(--smv-panel-text);font-size:13px;outline:none;box-sizing:border-box;transition:border-color .15s,background .15s}.side-panel__search::placeholder{color:var(--smv-panel-text-subtle)}.side-panel__search:focus{border-color:var(--smv-panel-border-active);background:var(--smv-panel-surface-hover)}.side-panel__list{display:flex;flex-direction:column;padding:10px 0;overflow-y:auto;flex:1}.side-panel__list::-webkit-scrollbar{width:4px}.side-panel__list::-webkit-scrollbar-track{background:transparent}.side-panel__list::-webkit-scrollbar-thumb{background:var(--smv-panel-surface-hover);border-radius:4px}.side-panel__row{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;cursor:pointer;transition:background .12s;border-bottom:1px solid var(--smv-panel-surface-soft)}.side-panel__row:hover,.side-panel__row--hovered{background:var(--smv-panel-surface)}.side-panel__label{font-size:14px;font-weight:600;color:var(--smv-panel-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.side-panel__label--hovered{color:var(--smv-panel-text-emphasis)}.side-panel__vis-btn{display:flex;align-items:center;flex-shrink:0;cursor:pointer;background:none;border:none;padding:0;margin-left:10px}.side-panel__checkbox{width:16px;height:16px;border-radius:4px;border:1.5px solid var(--smv-panel-border-active);background:transparent;display:flex;align-items:center;justify-content:center;transition:background .15s,border-color .15s}.side-panel__checkbox--checked{background:var(--smv-panel-accent);border-color:var(--smv-panel-accent)}@media(max-width:900px){.smv-upload-toolbar{top:56px;gap:8px;max-width:calc(100% - 24px);padding:8px 10px}.smv-upload-toolbar__name{max-width:140px}.right-panel-wrapper--open,.left-panel-wrapper--open{width:0}.side-panel,.side-panel.side-panel--left{width:min(300px,85vw)}}.smv-largeModelBanner{position:absolute;bottom:12px;left:50%;transform:translate(-50%);z-index:20;display:flex;align-items:center;gap:8px;padding:7px 12px 7px 10px;border-radius:8px;background:#1e1400e0;border:1px solid rgba(251,191,36,.35);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);color:#fbbf24;font-size:12px;font-weight:500;line-height:1.4;pointer-events:auto;max-width:calc(100% - 32px);text-align:center}.smv-largeModelBanner__icon{flex-shrink:0}.smv-largeModelBanner__dismiss{flex-shrink:0;display:flex;align-items:center;justify-content:center;margin-left:4px;padding:2px;background:none;border:none;border-radius:4px;color:#fbbf24b3;cursor:pointer;transition:color .15s ease,background .15s ease}.smv-largeModelBanner__dismiss:hover{color:#fbbf24;background:#fbbf241f}
|
|
1
|
+
.bb-loadingOverlay{position:absolute;inset:0;z-index:5;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;padding:24px;text-align:center;border-radius:14px;background:#f8fafcd1;backdrop-filter:blur(2px)}.bb-loadingSpinner{width:40px;height:40px;border-radius:999px;border:3px solid rgba(148,163,184,.3);border-top-color:#2563eb;animation:bb-spin .8s linear infinite}.bb-loadingProgressRow{display:flex;align-items:center;gap:8px;width:100%;max-width:240px}.bb-loadingProgress{flex:1;height:6px;border-radius:999px;background:#94a3b84d;overflow:hidden}.bb-loadingProgress__bar{height:100%;border-radius:inherit;background:#2563eb;transition:width .15s ease-out}.bb-loadingProgress__label{flex-shrink:0;min-width:34px;text-align:right;color:#475569;font-size:12px;font-weight:600;font-variant-numeric:tabular-nums}.bb-loadingMessage{max-width:320px;color:#475569;font-size:13px;font-weight:600;line-height:1.5}.ri-viewerSlot{position:relative;width:100%;height:100%;min-width:0;min-height:0}.ri-viewerPlaceholder{position:relative;overflow:hidden}.ri-viewerPlaceholder--inset{position:absolute;inset:0}.ri-poster{position:absolute;inset:0;z-index:0;width:100%;height:100%;object-fit:var(--ri-poster-fit, contain);pointer-events:none;user-select:none;transition:opacity .3s ease}.ri-poster--hidden{opacity:0}[data-reduced-motion] .ri-poster{transition:none}@media(prefers-reduced-motion:reduce){.ri-poster{transition:none}}.ri-revealButton{position:absolute;top:50%;left:50%;z-index:2;display:inline-flex;align-items:center;gap:8px;padding:10px 18px;border:0;border-radius:999px;background:#111827d1;color:#f9fafb;font:600 14px/1.2 Inter,Segoe UI,Helvetica,Arial,sans-serif;white-space:nowrap;cursor:pointer;transform:translate(-50%,-50%);box-shadow:0 6px 20px #00000040}.ri-revealButton:hover{background:#111827f0}.ri-revealButton:focus-visible{outline:2px solid #93c5fd;outline-offset:3px}:root{--ri-styles-simple-model-viewer: 1}.smv-root{--smv-panel-font-family: Inter, "Segoe UI", Helvetica, Arial, sans-serif;--smv-panel-bg: #141824;--smv-panel-bg-strong: #1a1f2e;--smv-panel-bg-strong-hover: #252b3b;--smv-panel-border: rgba(255, 255, 255, .06);--smv-panel-border-strong: rgba(255, 255, 255, .08);--smv-panel-border-active: rgba(255, 255, 255, .18);--smv-panel-shadow-left: 4px 0 24px rgba(0, 0, 0, .35);--smv-panel-shadow-right: -4px 0 24px rgba(0, 0, 0, .35);--smv-panel-text: #f1f5f9;--smv-panel-text-emphasis: #ffffff;--smv-panel-text-muted: #94a3b8;--smv-panel-text-subtle: #64748b;--smv-panel-surface: rgba(255, 255, 255, .05);--smv-panel-surface-hover: rgba(255, 255, 255, .1);--smv-panel-surface-soft: rgba(255, 255, 255, .04);--smv-panel-accent: #3b82f6;--smv-panel-accent-contrast: #ffffff;position:relative;width:100%;height:100%;min-height:0;overflow:hidden;display:flex;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;font-synthesis:none}.smv-canvasArea{flex:1;position:relative;min-width:0}.smv-upload-input{display:none}.smv-upload-toolbar{position:absolute;top:12px;left:50%;z-index:120;display:flex;align-items:center;gap:10px;max-width:calc(100% - 32px);padding:5px 6px;border:1px solid var(--smv-panel-border-strong);border-radius:10px;background:#141824e0;color:var(--smv-panel-text);box-shadow:0 16px 30px #00000047;backdrop-filter:blur(14px);transform:translate(-50%)}.smv-upload-toolbar__name{max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--smv-panel-text-muted);font-size:12px;font-weight:500}.smv-upload-toolbar__button{display:inline-flex;align-items:center;gap:7px;min-height:34px;padding:0 14px;border:1px solid rgba(255,255,255,.08);border-radius:10px;background:#3b82f62e;color:var(--smv-panel-text-emphasis);font-size:12px;font-weight:600;cursor:pointer}.smv-upload-toolbar__button--ghost{background:var(--smv-panel-surface);color:var(--smv-panel-text-muted)}.smv-upload-empty-state{display:flex;align-items:center;justify-content:center;width:100%;height:100%;padding:24px}.smv-upload-empty-state__card{width:min(440px,100%);padding:28px;border:1px dashed rgba(255,255,255,.2);border-radius:8px;color:var(--smv-panel-text);text-align:center;box-shadow:0 24px 40px #00000047;backdrop-filter:blur(14px)}.smv-upload-empty-state__icon{display:inline-flex;align-items:center;justify-content:center;width:56px;height:56px;margin-bottom:18px;border-radius:10px;background:#3b82f62e;color:#bfdbfe}.smv-upload-empty-state__title{margin:0 0 10px;color:var(--smv-panel-text-emphasis);font-size:24px;line-height:1.15}.smv-upload-empty-state__body{margin:0 0 18px;color:var(--smv-panel-text-muted);font-size:14px;font-weight:700;line-height:1.6}.smv-upload-empty-state__body code{color:var(--smv-panel-text-emphasis);font-family:var(--smv-panel-font-family)}.smv-upload-empty-state__button{display:inline-flex;align-items:center;gap:8px;min-height:40px;padding:0 18px;border:none;border-radius:8px;background:#3b82f6;color:#eff6ff;font-size:13px;font-weight:700;cursor:pointer}.smv-upload-drop-overlay{position:absolute;inset:0;z-index:130;display:flex;align-items:center;justify-content:center;padding:24px;background:#080c147a;backdrop-filter:blur(4px)}.smv-upload-drop-overlay__card{display:inline-flex;align-items:center;gap:10px;padding:16px 20px;border:1px dashed rgba(191,219,254,.75);border-radius:10px;background:#1e293beb;color:#dbeafe;font-size:14px;font-weight:700;box-shadow:0 18px 36px #00000047}.smv-canvasArea .bb-loadingOverlay{position:absolute;inset:0;z-index:110;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;padding:24px;text-align:center;border-radius:14px;background:#0f172a75;backdrop-filter:blur(1px)}.smv-canvasArea .bb-loadingSpinner{width:40px;height:40px;border-radius:999px;border:3px solid rgba(226,232,240,.24);border-top-color:#93c5fd;animation:bb-spin .8s linear infinite}.smv-canvasArea .bb-loadingProgressRow{display:flex;align-items:center;gap:8px;width:100%;max-width:240px}.smv-canvasArea .bb-loadingProgress{flex:1;height:6px;border-radius:999px;background:#e2e8f03d;overflow:hidden}.smv-canvasArea .bb-loadingProgress__bar{height:100%;border-radius:inherit;background:#93c5fd;transition:width .15s ease-out}.smv-canvasArea .bb-loadingProgress__label{flex-shrink:0;min-width:34px;text-align:right;color:#f7f8fa;font-size:12px;font-weight:600;font-variant-numeric:tabular-nums}.smv-canvasArea .bb-loadingMessage{max-width:320px;color:#f7f8fa;font-size:13px;font-weight:600;line-height:1.5}@keyframes bb-spin{to{transform:rotate(360deg)}}.right-panel-wrapper{height:100%;transition:width .45s cubic-bezier(.4,0,.2,1);overflow:visible}.right-panel-wrapper--open{width:300px;flex-shrink:0}.right-panel-wrapper--closed{width:0;flex-shrink:0}.left-panel-wrapper{height:100%;transition:width .45s cubic-bezier(.4,0,.2,1);overflow:visible;order:-1}.left-panel-wrapper--open{width:280px;flex-shrink:0}.left-panel-wrapper--closed{width:0;flex-shrink:0}.side-panel__open-btn.side-panel__open-btn--left{left:12px;right:auto}.side-panel.side-panel--left{left:0;right:auto;width:280px;transform:translate(-100%);border-left:none;border-right:1px solid var(--smv-panel-border);box-shadow:var(--smv-panel-shadow-left)}.side-panel.side-panel--open-left{transform:translate(0)}.side-panel.side-panel--closed-left{transform:translate(-100%)}.env-controls{display:flex;flex-direction:column;overflow-y:auto;flex:1}.env-section{border-bottom:1px solid var(--smv-panel-border-strong)}.env-section__header{display:flex;align-items:center;gap:6px;width:100%;padding:9px 14px;border:none;background:var(--smv-panel-surface-soft);color:var(--smv-panel-text-muted);font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;cursor:pointer}.env-section__chevron{transition:transform .15s}.env-section__chevron--collapsed{transform:rotate(-90deg)}.env-section__body{display:flex;flex-direction:column}.env-row{display:flex;gap:6px;align-items:center;min-height:32px;border-bottom:1px solid var(--smv-panel-surface)}.env-row__label{flex:0 0 42%;padding:0 0 0 14px;font-size:11.5px;font-weight:500;color:var(--smv-panel-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.env-row__value{flex:1;display:flex;align-items:center;padding:5px 10px 5px 8px;min-width:0}.env-row__value--slider{gap:6px}.env-checkbox-btn{display:flex;align-items:center;cursor:pointer;background:none;border:none;padding:0}.env-checkbox{width:15px;height:15px;border-radius:3px;border:1.5px solid var(--smv-panel-border-active);background:var(--smv-panel-surface-soft);display:flex;align-items:center;justify-content:center;transition:background .15s,border-color .15s}.env-checkbox--checked{background:var(--smv-panel-accent);border-color:var(--smv-panel-accent)}.env-select{width:100%;padding:5px 8px;border-radius:4px;border:none;background:var(--smv-panel-surface-hover);color:var(--smv-panel-text);font-size:11.5px;outline:none;box-sizing:border-box;text-transform:capitalize}.env-color-swatch{position:relative;width:100%;height:22px;border-radius:4px;border:1px solid rgba(255,255,255,.15);display:flex;align-items:center;justify-content:center;overflow:hidden;cursor:pointer}.env-color-swatch__hex{font-size:10.5px;font-weight:700;color:#0f172a;text-shadow:0 1px 1px rgba(255,255,255,.35);pointer-events:none;text-transform:uppercase}.env-color-swatch__input{position:absolute;inset:0;width:100%;height:100%;border:none;padding:0;opacity:0;cursor:pointer}.env-slider{flex:1;accent-color:var(--smv-panel-accent);cursor:pointer;min-width:0}.env-slider__value{flex-shrink:0;min-width:32px;padding:2px 5px;border-radius:4px;background:var(--smv-panel-surface-hover);color:var(--smv-panel-accent);font-size:10.5px;font-weight:600;text-align:center}.side-panel__open-btn{position:absolute;top:12px;right:12px;display:flex;align-items:center;gap:7px;padding:7px 13px;border-radius:7px;border:1px solid var(--smv-panel-border-strong);background:var(--smv-panel-bg-strong);cursor:pointer;font-size:13px;font-weight:500;color:var(--smv-panel-text);z-index:190;transition:background .15s}.side-panel__open-btn:hover{background:var(--smv-panel-bg-strong-hover)}.side-panel{position:absolute;top:0;right:0;width:300px;height:100%;background:var(--smv-panel-bg);display:flex;flex-direction:column;font-family:var(--smv-panel-font-family);transform:translate(100%);transition:transform .45s cubic-bezier(.4,0,.2,1);z-index:200;border-left:1px solid var(--smv-panel-border);box-shadow:var(--smv-panel-shadow-right)}.side-panel--open{transform:translate(0)}.side-panel--closed{transform:translate(100%)}.side-panel__header{padding:24px 20px 16px;border-bottom:1px solid var(--smv-panel-border-strong)}.side-panel__header-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:4px}.side-panel__eyebrow{font-size:15px;font-weight:700;letter-spacing:.12em;color:var(--smv-panel-text-subtle);text-transform:uppercase}.side-panel__title{font-size:22px;font-weight:700;color:var(--smv-panel-text);margin:0;line-height:1.2}.side-panel__close-btn{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:8px;border:1px solid var(--smv-panel-border-strong);background:var(--smv-panel-surface);cursor:pointer;color:var(--smv-panel-text-muted);transition:background .15s,color .15s;flex-shrink:0}.side-panel__close-btn:hover{background:var(--smv-panel-surface-hover);color:var(--smv-panel-text)}.side-panel__search-wrap{padding:14px 16px;border-bottom:1px solid var(--smv-panel-border-strong)}.side-panel__search{width:100%;padding:10px 14px;border-radius:10px;border:1px solid var(--smv-panel-border-strong);background:var(--smv-panel-surface);color:var(--smv-panel-text);font-size:13px;outline:none;box-sizing:border-box;transition:border-color .15s,background .15s}.side-panel__search::placeholder{color:var(--smv-panel-text-subtle)}.side-panel__search:focus{border-color:var(--smv-panel-border-active);background:var(--smv-panel-surface-hover)}.side-panel__list{display:flex;flex-direction:column;padding:10px 0;overflow-y:auto;flex:1}.side-panel__list::-webkit-scrollbar{width:4px}.side-panel__list::-webkit-scrollbar-track{background:transparent}.side-panel__list::-webkit-scrollbar-thumb{background:var(--smv-panel-surface-hover);border-radius:4px}.side-panel__row{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;cursor:pointer;transition:background .12s;border-bottom:1px solid var(--smv-panel-surface-soft)}.side-panel__row:hover,.side-panel__row--hovered{background:var(--smv-panel-surface)}.side-panel__label{font-size:14px;font-weight:600;color:var(--smv-panel-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.side-panel__labelButton{min-width:0;padding:0;background:none;border:none;font-family:inherit;text-align:left;cursor:pointer}.side-panel__labelButton:focus-visible{outline:2px solid var(--smv-panel-text);outline-offset:2px;border-radius:4px}.side-panel__label--hovered{color:var(--smv-panel-text-emphasis)}.side-panel__vis-btn{display:flex;align-items:center;flex-shrink:0;cursor:pointer;background:none;border:none;padding:0;margin-left:10px}.side-panel__checkbox{width:16px;height:16px;border-radius:4px;border:1.5px solid var(--smv-panel-border-active);background:transparent;display:flex;align-items:center;justify-content:center;transition:background .15s,border-color .15s}.side-panel__checkbox--checked{background:var(--smv-panel-accent);border-color:var(--smv-panel-accent)}@media(max-width:900px){.smv-upload-toolbar{top:56px;gap:8px;max-width:calc(100% - 24px);padding:8px 10px}.smv-upload-toolbar__name{max-width:140px}.right-panel-wrapper--open,.left-panel-wrapper--open{width:0}.side-panel,.side-panel.side-panel--left{width:min(300px,85vw)}}.smv-largeModelBanner{position:absolute;bottom:12px;left:50%;transform:translate(-50%);z-index:20;display:flex;align-items:center;gap:8px;padding:7px 12px 7px 10px;border-radius:8px;background:#1e1400e0;border:1px solid rgba(251,191,36,.35);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);color:#fbbf24;font-size:12px;font-weight:500;line-height:1.4;pointer-events:auto;max-width:calc(100% - 32px);text-align:center}.smv-largeModelBanner__icon{flex-shrink:0}.smv-largeModelBanner__dismiss{flex-shrink:0;display:flex;align-items:center;justify-content:center;margin-left:4px;padding:2px;background:none;border:none;border-radius:4px;color:#fbbf24b3;cursor:pointer;transition:color .15s ease,background .15s ease}.smv-largeModelBanner__dismiss:hover{color:#fbbf24;background:#fbbf241f}.smv-root[data-reduced-motion] *,.smv-root[data-reduced-motion] *:before,.smv-root[data-reduced-motion] *:after{transition-duration:0s!important;transition-delay:0s!important}
|
|
@@ -1,10 +1,31 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import {
|
|
3
|
-
export {
|
|
2
|
+
import { c as ModelViewerLabels, R as ReducedMotionSetting } from './materialVariants-DnZe9eMC.mjs';
|
|
3
|
+
export { D as DEFAULT_MODEL_VIEWER_LABELS, M as MaterialVariantGroup, a as MaterialVariantOption, b as ModelViewerLabelKey } from './materialVariants-DnZe9eMC.mjs';
|
|
4
|
+
import { V as ViewerLoading, c as ViewerReveal, M as ModelFormat, b as ViewerModelInfo } from './modelInfo-BYebMPdZ.mjs';
|
|
5
|
+
export { a as ViewerModelBounds } from './modelInfo-BYebMPdZ.mjs';
|
|
4
6
|
import { PresetsType } from '@react-three/drei/helpers/environment-assets';
|
|
5
7
|
|
|
6
8
|
type SimpleModelViewerProps = {
|
|
9
|
+
/** Plain-text overrides for built-in viewer text. */
|
|
10
|
+
labels?: ModelViewerLabels;
|
|
7
11
|
modelUrl: string;
|
|
12
|
+
/**
|
|
13
|
+
* An image shown in the viewer's place until its 3D view is drawn: a render
|
|
14
|
+
* or photo of the model, best framed as the viewer frames it.
|
|
15
|
+
*/
|
|
16
|
+
poster?: string;
|
|
17
|
+
/**
|
|
18
|
+
* `"lazy"` (default) starts the 3D view when the viewer is on or near the
|
|
19
|
+
* screen. When the page needs room for viewers in view, one scrolled away
|
|
20
|
+
* from goes back to a picture of itself, and comes back as it was. `"eager"`
|
|
21
|
+
* starts at once and keeps its view.
|
|
22
|
+
*/
|
|
23
|
+
loading?: ViewerLoading;
|
|
24
|
+
/**
|
|
25
|
+
* `"interaction"` keeps the poster, with a "View in 3D" button, until the
|
|
26
|
+
* visitor asks for the 3D view. Default `"auto"`.
|
|
27
|
+
*/
|
|
28
|
+
reveal?: ViewerReveal;
|
|
8
29
|
/** Explicit format for extensionless or signed model URLs. */
|
|
9
30
|
modelFormat?: ModelFormat;
|
|
10
31
|
/** Directory containing the DRACO decoder files, or false. */
|
|
@@ -21,6 +42,13 @@ type SimpleModelViewerProps = {
|
|
|
21
42
|
highlightOnHover?: boolean;
|
|
22
43
|
showLoadingOverlay?: boolean;
|
|
23
44
|
refitOnResize?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Cuts motion the viewer starts on its own: auto-rotate doesn't start, and
|
|
47
|
+
* camera moves jump instead of gliding. `"user"` (default) follows the
|
|
48
|
+
* visitor's `prefers-reduced-motion` setting; `"always"` and `"never"`
|
|
49
|
+
* override it.
|
|
50
|
+
*/
|
|
51
|
+
reducedMotion?: ReducedMotionSetting;
|
|
24
52
|
backgroundEnabled?: boolean;
|
|
25
53
|
autoRotate?: boolean;
|
|
26
54
|
envPreset?: PresetsType;
|
|
@@ -33,6 +61,6 @@ type SimpleModelViewerProps = {
|
|
|
33
61
|
onModelLoaded?: (model: ViewerModelInfo) => void;
|
|
34
62
|
onLoadError?: (error: unknown) => void;
|
|
35
63
|
};
|
|
36
|
-
declare function SimpleModelViewer(
|
|
64
|
+
declare function SimpleModelViewer(props: SimpleModelViewerProps): react.JSX.Element;
|
|
37
65
|
|
|
38
|
-
export { ModelFormat, SimpleModelViewer, type SimpleModelViewerProps, ViewerModelInfo };
|
|
66
|
+
export { ModelFormat, ModelViewerLabels, ReducedMotionSetting, SimpleModelViewer, type SimpleModelViewerProps, ViewerLoading, ViewerModelInfo, ViewerReveal };
|
|
@@ -1,10 +1,31 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import {
|
|
3
|
-
export {
|
|
2
|
+
import { c as ModelViewerLabels, R as ReducedMotionSetting } from './materialVariants-DnZe9eMC.js';
|
|
3
|
+
export { D as DEFAULT_MODEL_VIEWER_LABELS, M as MaterialVariantGroup, a as MaterialVariantOption, b as ModelViewerLabelKey } from './materialVariants-DnZe9eMC.js';
|
|
4
|
+
import { V as ViewerLoading, c as ViewerReveal, M as ModelFormat, b as ViewerModelInfo } from './modelInfo-XfUQO7C_.js';
|
|
5
|
+
export { a as ViewerModelBounds } from './modelInfo-XfUQO7C_.js';
|
|
4
6
|
import { PresetsType } from '@react-three/drei/helpers/environment-assets';
|
|
5
7
|
|
|
6
8
|
type SimpleModelViewerProps = {
|
|
9
|
+
/** Plain-text overrides for built-in viewer text. */
|
|
10
|
+
labels?: ModelViewerLabels;
|
|
7
11
|
modelUrl: string;
|
|
12
|
+
/**
|
|
13
|
+
* An image shown in the viewer's place until its 3D view is drawn: a render
|
|
14
|
+
* or photo of the model, best framed as the viewer frames it.
|
|
15
|
+
*/
|
|
16
|
+
poster?: string;
|
|
17
|
+
/**
|
|
18
|
+
* `"lazy"` (default) starts the 3D view when the viewer is on or near the
|
|
19
|
+
* screen. When the page needs room for viewers in view, one scrolled away
|
|
20
|
+
* from goes back to a picture of itself, and comes back as it was. `"eager"`
|
|
21
|
+
* starts at once and keeps its view.
|
|
22
|
+
*/
|
|
23
|
+
loading?: ViewerLoading;
|
|
24
|
+
/**
|
|
25
|
+
* `"interaction"` keeps the poster, with a "View in 3D" button, until the
|
|
26
|
+
* visitor asks for the 3D view. Default `"auto"`.
|
|
27
|
+
*/
|
|
28
|
+
reveal?: ViewerReveal;
|
|
8
29
|
/** Explicit format for extensionless or signed model URLs. */
|
|
9
30
|
modelFormat?: ModelFormat;
|
|
10
31
|
/** Directory containing the DRACO decoder files, or false. */
|
|
@@ -21,6 +42,13 @@ type SimpleModelViewerProps = {
|
|
|
21
42
|
highlightOnHover?: boolean;
|
|
22
43
|
showLoadingOverlay?: boolean;
|
|
23
44
|
refitOnResize?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Cuts motion the viewer starts on its own: auto-rotate doesn't start, and
|
|
47
|
+
* camera moves jump instead of gliding. `"user"` (default) follows the
|
|
48
|
+
* visitor's `prefers-reduced-motion` setting; `"always"` and `"never"`
|
|
49
|
+
* override it.
|
|
50
|
+
*/
|
|
51
|
+
reducedMotion?: ReducedMotionSetting;
|
|
24
52
|
backgroundEnabled?: boolean;
|
|
25
53
|
autoRotate?: boolean;
|
|
26
54
|
envPreset?: PresetsType;
|
|
@@ -33,6 +61,6 @@ type SimpleModelViewerProps = {
|
|
|
33
61
|
onModelLoaded?: (model: ViewerModelInfo) => void;
|
|
34
62
|
onLoadError?: (error: unknown) => void;
|
|
35
63
|
};
|
|
36
|
-
declare function SimpleModelViewer(
|
|
64
|
+
declare function SimpleModelViewer(props: SimpleModelViewerProps): react.JSX.Element;
|
|
37
65
|
|
|
38
|
-
export { ModelFormat, SimpleModelViewer, type SimpleModelViewerProps, ViewerModelInfo };
|
|
66
|
+
export { ModelFormat, ModelViewerLabels, ReducedMotionSetting, SimpleModelViewer, type SimpleModelViewerProps, ViewerLoading, ViewerModelInfo, ViewerReveal };
|