@ericchen1990/pano-view 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -31,6 +31,11 @@ type HotspotDragEvent = HotspotInteractionEvent & {
31
31
  };
32
32
  /** When a hotspot tooltip is shown. Defaults to `"always"`. */
33
33
  type HotspotTooltipTrigger = "always" | "hover" | "click";
34
+ /**
35
+ * Pointer hit-testing for a hotspot. `"none"` ignores mouse, touch, and pen
36
+ * so events pass through to the panorama. Defaults to `"auto"`.
37
+ */
38
+ type HotspotPointerEvents = "auto" | "none";
34
39
  /** Where the tooltip sits relative to the hotspot. Defaults to `"top"`. */
35
40
  type HotspotTooltipPlacement = "top" | "bottom" | "left" | "right";
36
41
  /** Plain-text and/or image content for a hotspot tooltip. */
@@ -39,6 +44,16 @@ type HotspotTooltipContent = {
39
44
  image?: string;
40
45
  imageAlt?: string;
41
46
  };
47
+ /** Visual styling for a hotspot tooltip bubble. */
48
+ type HotspotTooltipAppearance = {
49
+ background?: string;
50
+ color?: string;
51
+ border?: string;
52
+ borderRadius?: number | string;
53
+ shadow?: string;
54
+ padding?: number | string;
55
+ fontSize?: number | string;
56
+ };
42
57
  type HotspotCommonProps = {
43
58
  id: string;
44
59
  position: HotspotPosition;
@@ -47,15 +62,17 @@ type HotspotCommonProps = {
47
62
  * Defaults to always visible when content is present.
48
63
  */
49
64
  tooltip?: string | HotspotTooltipContent;
50
- /** Defaults to `"always"`. `"hover"` and `"click"` require `interactive`. */
65
+ /** Defaults to `"always"`. `"hover"` and `"click"` require `interactive` and `pointerEvents` other than `"none"`. */
51
66
  tooltipTrigger?: HotspotTooltipTrigger;
52
- /** Defaults to `"top"`. */
67
+ /** Screen direction for the tooltip. Defaults to `"top"`. */
53
68
  tooltipPlacement?: HotspotTooltipPlacement;
54
69
  /**
55
70
  * Screen-space gap in CSS pixels between the hotspot edge and the tooltip.
56
71
  * Defaults to 12.
57
72
  */
58
73
  tooltipOffset?: number;
74
+ /** Optional bubble paint overrides. Unset fields use the library default theme. */
75
+ tooltipAppearance?: HotspotTooltipAppearance;
59
76
  /** Angular width in degrees. Defaults to 12. */
60
77
  width?: number;
61
78
  /** Angular height in degrees. Defaults to 8. */
@@ -80,6 +97,12 @@ type HotspotCommonProps = {
80
97
  visible?: boolean;
81
98
  /** Whether the hotspot accepts pointer and keyboard interaction. Defaults to true. */
82
99
  interactive?: boolean;
100
+ /**
101
+ * Pointer hit-testing. `"none"` ignores mouse, touch, and pen so events
102
+ * pass through to the panorama. Defaults to `"auto"`.
103
+ * `interactive={false}` also disables pointer hits.
104
+ */
105
+ pointerEvents?: HotspotPointerEvents;
83
106
  /**
84
107
  * Canvas cursor while this hotspot is hovered. Defaults to the viewer's
85
108
  * `cursors.hotspot` value (`"pointer"`).
@@ -145,7 +168,8 @@ declare function cycleSceneId(scenes: readonly {
145
168
  * Adds keyboard navigation to the nearest PanoViewer. Enabled by default;
146
169
  * render this component only to override properties, bindings, or scene
147
170
  * callbacks. Hold movement/zoom keys for continuous motion; scene and reset
148
- * bindings fire once per key press.
171
+ * bindings fire once per key press. Click the viewer to focus it before
172
+ * keys are received.
149
173
  */
150
174
  declare function KeyboardControls({ enabled, keys, rotateSpeed, zoomSpeed, shiftMultiplier, invert, fovSpeed, onPreviousScene, onNextScene, }: KeyboardControlsProps): null;
151
175
 
@@ -493,6 +517,150 @@ type AutoRotateProps = {
493
517
  */
494
518
  declare function AutoRotate({ enabled, speed, acceleration, startDelay, }: AutoRotateProps): null;
495
519
 
520
+ declare const PANO_FILTER_PRESETS: readonly ["none", "grayscale", "sepia", "vintage", "cool", "warm", "pencil", "coloredPencil", "crayon", "watercolor", "cartoon", "crosshatch"];
521
+ type PanoFilterPreset = (typeof PANO_FILTER_PRESETS)[number];
522
+
523
+ type PanoFilterProps = {
524
+ /** Built-in look. Defaults to `none` (identity). */
525
+ preset?: PanoFilterPreset;
526
+ /** Mix with the original panorama, 0–1. Defaults to 1. */
527
+ intensity?: number;
528
+ /** When false, the panorama renders without a filter. Defaults to true. */
529
+ enabled?: boolean;
530
+ };
531
+ /**
532
+ * Applies a color or artistic filter to the panorama source of the nearest
533
+ * PanoViewer. Render one instance as a child of PanoViewer. Hotspots and HTML
534
+ * chrome are not filtered.
535
+ */
536
+ declare function PanoFilter({ preset, intensity, enabled, }: PanoFilterProps): null;
537
+
538
+ type GyroTouchMode = "off" | "horizontaloffset" | "full" | "disablegyro";
539
+
540
+ type GyroHandle = {
541
+ resetSensor: (yaw?: number, pitch?: number) => void;
542
+ isAvailable: () => boolean;
543
+ isEnabled: () => boolean;
544
+ /**
545
+ * Requests iOS sensor permission. Call this directly from a user gesture
546
+ * before setting `enabled` to true.
547
+ */
548
+ requestPermission: () => Promise<boolean>;
549
+ };
550
+ type GyroProps = {
551
+ /** Whether device-orientation control is requested. Defaults to false. */
552
+ enabled?: boolean;
553
+ /** Whether device roll levels the camera. Defaults to true. */
554
+ camroll?: boolean;
555
+ /** Whether to follow compass-oriented headings. Defaults to false. */
556
+ absolute?: boolean;
557
+ /** Panorama yaw that represents North, in degrees. Defaults to 0. */
558
+ north?: number;
559
+ /** Sensor smoothing from 0 (none) to 0.99 (strong). Defaults to 0. */
560
+ friction?: number;
561
+ /** How touch dragging combines with gyro movement. Defaults to "full". */
562
+ touchMode?: GyroTouchMode;
563
+ /** Seconds used to blend from the current view when enabling. Defaults to 0.5. */
564
+ softstart?: number;
565
+ /** Allow capability detection on desktop-class devices. Defaults to false. */
566
+ desktopSupport?: boolean;
567
+ onAvailable?: () => void;
568
+ onUnavailable?: () => void;
569
+ onEnable?: () => void;
570
+ onDisable?: () => void;
571
+ onDenied?: () => void;
572
+ };
573
+ /**
574
+ * Adds device-orientation navigation to the nearest PanoViewer.
575
+ * Sensor access is opt-in and disabled by default.
576
+ */
577
+ declare const Gyro: react.ForwardRefExoticComponent<GyroProps & react.RefAttributes<GyroHandle>>;
578
+
579
+ type WebVRMode = "webxr" | "mobilevr" | "fake";
580
+ type WebVRProfileId = "none" | "cardboard-v1" | "cardboard-v2" | "gear-vr" | "daydream";
581
+ type WebVRProfile = {
582
+ id?: string;
583
+ label?: string;
584
+ /** Vertical field of view for each eye, in degrees. */
585
+ fov: number;
586
+ /** Distance between the eyes, in millimetres. */
587
+ ipdMm: number;
588
+ /** Distance from the display to the headset lens, in millimetres. */
589
+ screenToLensMm?: number;
590
+ /** Radial lens distortion coefficients. Zero disables distortion. */
591
+ k1: number;
592
+ k2: number;
593
+ };
594
+ type WebVRChromeAppearance = {
595
+ background?: CSSProperties["background"];
596
+ color?: CSSProperties["color"];
597
+ accent?: CSSProperties["color"];
598
+ borderRadius?: CSSProperties["borderRadius"];
599
+ fontSize?: CSSProperties["fontSize"];
600
+ setupTitle?: ReactNode;
601
+ };
602
+ type WebVRChrome = boolean | WebVRChromeAppearance;
603
+ type WebVRProps = {
604
+ /** Mount the built-in Enter / Exit / Setup chrome. Defaults to true. */
605
+ chrome?: WebVRChrome;
606
+ /** Enable the phone stereoscopic fallback. Defaults to true. */
607
+ mobileVr?: boolean;
608
+ /** Treat desktop device-orientation sensors as MobileVR. Defaults to false. */
609
+ desktopSupport?: boolean;
610
+ /** Allow a mouse-driven stereoscopic desktop simulation. Defaults to true. */
611
+ fakeSupport?: boolean;
612
+ /** Physical diagonal screen size in inches, or automatic detection. */
613
+ screensize?: number | "auto";
614
+ /** Headset preset or a custom lens profile. */
615
+ profile?: WebVRProfileId | WebVRProfile;
616
+ /** Show a center reticle in VR. Defaults to true. */
617
+ cursor?: boolean;
618
+ /**
619
+ * Milliseconds to keep looking at a hotspot before a gaze click.
620
+ * Defaults to 1500. Set to 0 to disable auto-click.
621
+ */
622
+ cursorDwellMs?: number;
623
+ /**
624
+ * Keep the display awake while MobileVR or simulated VR is active.
625
+ * Uses the Screen Wake Lock API when available, otherwise a looping
626
+ * hidden video. Defaults to true.
627
+ */
628
+ wakelock?: boolean;
629
+ /**
630
+ * Lock the mouse in simulated desktop VR so movement looks around with
631
+ * no visible cursor. Click the view to re-lock after Escape. Defaults to true.
632
+ */
633
+ mousePointerLock?: boolean;
634
+ onAvailable?: () => void;
635
+ onUnavailable?: () => void;
636
+ onEnterVR?: (mode: WebVRMode) => void;
637
+ onExitVR?: (mode: WebVRMode) => void;
638
+ onDenied?: (error?: unknown) => void;
639
+ onUnknownDevice?: () => void;
640
+ };
641
+ type WebVRHandle = {
642
+ enterVR: () => Promise<boolean>;
643
+ exitVR: () => Promise<void>;
644
+ toggleVR: () => Promise<boolean>;
645
+ isAvailable: () => boolean;
646
+ isEnabled: () => boolean;
647
+ getMode: () => WebVRMode | null;
648
+ requestPermission: () => Promise<boolean>;
649
+ };
650
+ type WebVRSettings = {
651
+ screensize: number | "auto";
652
+ profileId: WebVRProfileId;
653
+ };
654
+
655
+ declare const WebVR: react.ForwardRefExoticComponent<WebVRProps & react.RefAttributes<WebVRHandle>>;
656
+
657
+ declare const DEFAULT_WEBVR_CHROME_APPEARANCE: Required<Omit<WebVRChromeAppearance, "setupTitle">>;
658
+
659
+ declare const WEBVR_PROFILE_IDS: readonly ["none", "cardboard-v1", "cardboard-v2", "gear-vr", "daydream"];
660
+ declare const WEBVR_PROFILES: Record<WebVRProfileId, WebVRProfile>;
661
+
662
+ declare const DEFAULT_WEBVR_CURSOR_DWELL_MS = 1500;
663
+
496
664
  type ViewInteractionSource = "mouse" | "touch" | "keyboard";
497
665
  type PanoWheelEvent = {
498
666
  /** Signed wheel delta (same sign convention as WheelEvent.deltaY). */
@@ -526,6 +694,23 @@ type PanoEventMap = {
526
694
  autorotatestart: undefined;
527
695
  autorotatestop: undefined;
528
696
  autorotateoneround: undefined;
697
+ gyroavailable: undefined;
698
+ gyrounavailable: undefined;
699
+ gyroenable: undefined;
700
+ gyrodisable: undefined;
701
+ gyrodenied: undefined;
702
+ vravailable: undefined;
703
+ vrunavailable: undefined;
704
+ vrenter: {
705
+ mode: WebVRMode;
706
+ };
707
+ vrexit: {
708
+ mode: WebVRMode;
709
+ };
710
+ vrdenied: {
711
+ error?: unknown;
712
+ };
713
+ vrunknowndevice: undefined;
529
714
  };
530
715
  type PanoEventType = keyof PanoEventMap;
531
716
  type PanoEventListener<T extends PanoEventType> = (payload: PanoEventMap[T]) => void;
@@ -559,12 +744,23 @@ type PanoEventsProps = {
559
744
  onAutoRotateStart?: () => void;
560
745
  onAutoRotateStop?: () => void;
561
746
  onAutoRotateOneRound?: () => void;
747
+ onGyroAvailable?: () => void;
748
+ onGyroUnavailable?: () => void;
749
+ onGyroEnable?: () => void;
750
+ onGyroDisable?: () => void;
751
+ onGyroDenied?: () => void;
752
+ onVRAvailable?: () => void;
753
+ onVRUnavailable?: () => void;
754
+ onVREnter?: (mode: WebVRMode) => void;
755
+ onVRExit?: (mode: WebVRMode) => void;
756
+ onVRDenied?: (error?: unknown) => void;
757
+ onVRUnknownDevice?: () => void;
562
758
  };
563
759
  /**
564
760
  * Subscribes to viewer-level panorama events. Must run inside PanoViewer.
565
761
  * Prefer the {@link PanoEvents} component for declarative usage.
566
762
  */
567
- declare function usePanoEvents({ idleTime, onViewChange, onViewSettled, onViewInteractionStart, onViewInteractionEnd, onClick, onDoubleClick, onPointerDown, onPointerUp, onPointerMove, onContextMenu, onWheel, onIdle, onIdleEnd, onEnterFullscreen, onExitFullscreen, onResize, onAutoRotateStart, onAutoRotateStop, onAutoRotateOneRound, }: PanoEventsProps): void;
763
+ declare function usePanoEvents({ idleTime, onViewChange, onViewSettled, onViewInteractionStart, onViewInteractionEnd, onClick, onDoubleClick, onPointerDown, onPointerUp, onPointerMove, onContextMenu, onWheel, onIdle, onIdleEnd, onEnterFullscreen, onExitFullscreen, onResize, onAutoRotateStart, onAutoRotateStop, onAutoRotateOneRound, onGyroAvailable, onGyroUnavailable, onGyroEnable, onGyroDisable, onGyroDenied, onVRAvailable, onVRUnavailable, onVREnter, onVRExit, onVRDenied, onVRUnknownDevice, }: PanoEventsProps): void;
568
764
  /**
569
765
  * Declarative viewer-level event listeners for the nearest PanoViewer.
570
766
  * Multiple instances may coexist; each tracks its own idle timer.
@@ -594,14 +790,197 @@ declare function TouchControls({ enabled, rotateSpeed, invert, pinchZoom, }: Tou
594
790
 
595
791
  type SphereProps = {
596
792
  src: string;
793
+ /**
794
+ * Low-resolution 2:1 equirectangular image shown while `src` loads.
795
+ * Relative paths resolve against the directory of `src`. Root-absolute and
796
+ * `http(s)` / `blob:` / `data:` URLs are used as-is. For krpano sphere
797
+ * scenes, copy `<preview url>`.
798
+ */
799
+ previewUrl: string;
597
800
  /** Horizontal image offset in degrees. */
598
801
  yawOffset?: number;
802
+ /** Called once the first paintable texture (preview or `src`) is ready. */
803
+ onReady?: () => void;
599
804
  onLoad?: (texture: Texture) => void;
600
805
  onError?: (error: unknown) => void;
806
+ /** Called when `previewUrl` cannot be loaded; `src` still continues. */
807
+ onPreviewError?: (error: unknown) => void;
808
+ /** Keeps the source mounted for preloading without drawing it. */
809
+ visible?: boolean;
810
+ };
811
+ declare function Sphere({ src, previewUrl, yawOffset, onReady, onLoad, onError, onPreviewError, visible, }: SphereProps): react.JSX.Element | null;
812
+
813
+ type VideoPlaybackState = "playing" | "paused" | "ended" | "blocked";
814
+ type VideoHotspotErrorEvent = {
815
+ id: string;
816
+ source: "poster" | "video";
817
+ error: unknown;
818
+ };
819
+ type VideoHotspotProps = HotspotCommonProps & {
820
+ src: string;
821
+ playing: boolean;
822
+ poster?: string;
823
+ loop?: boolean;
824
+ muted?: boolean;
825
+ volume?: number;
826
+ playsInline?: boolean;
827
+ preload?: "none" | "metadata" | "auto";
828
+ crossOrigin?: "" | "anonymous" | "use-credentials";
829
+ onPlaybackStateChange?: (state: VideoPlaybackState) => void;
830
+ onPlaybackError?: (error: unknown) => void;
831
+ onEnded?: () => void;
832
+ onError?: (event: VideoHotspotErrorEvent) => void;
833
+ };
834
+ declare function VideoHotspot({ id, src, playing, poster, loop, muted, volume, playsInline, preload, crossOrigin, width, height, opacity, onPlaybackStateChange, onPlaybackError, onEnded, onError, ...anchorProps }: VideoHotspotProps): react.JSX.Element;
835
+
836
+ type PanoVideoSource = {
837
+ src: string;
838
+ type?: string;
839
+ };
840
+ type PanoVideoVariant = {
841
+ id: string;
842
+ label: string;
843
+ poster?: string;
844
+ sources: readonly PanoVideoSource[];
845
+ };
846
+ type PanoVideoTrackKind = "subtitles" | "captions";
847
+ type PanoVideoTrack = {
848
+ /** Defaults to `srcLang`. */
849
+ id?: string;
850
+ src: string;
851
+ srcLang: string;
852
+ label: string;
853
+ kind?: PanoVideoTrackKind;
854
+ default?: boolean;
855
+ };
856
+ type PanoVideoCaptionAppearance = {
857
+ color?: string;
858
+ background?: string;
859
+ fontSize?: number | string;
860
+ fontFamily?: string;
861
+ fontWeight?: CSSProperties["fontWeight"];
862
+ textShadow?: string;
863
+ padding?: string;
864
+ borderRadius?: number | string;
865
+ maxWidth?: number | string;
866
+ bottom?: number | string;
867
+ lineHeight?: number | string;
868
+ };
869
+ type PanoVideoControlsAppearance = {
870
+ background?: string;
871
+ color?: string;
872
+ accent?: string;
873
+ borderRadius?: number | string;
874
+ fontSize?: number | string;
875
+ padding?: string;
876
+ };
877
+ type PanoVideoErrorSource = "poster" | "video" | "track";
878
+ type PanoVideoErrorEvent = {
879
+ source: PanoVideoErrorSource;
880
+ error: unknown;
881
+ };
882
+ type PanoVideoPlaybackSnapshot = {
883
+ ready: boolean;
884
+ playing: boolean;
885
+ blocked: boolean;
886
+ ended: boolean;
887
+ currentTime: number;
888
+ duration: number;
889
+ volume: number;
890
+ /** False when the element ignores `volume` (iOS Safari). Mute still works. */
891
+ volumeAdjustable: boolean;
892
+ muted: boolean;
893
+ playbackRate: number;
894
+ variantId: string;
895
+ variants: readonly PanoVideoVariant[];
896
+ trackId: string | null;
897
+ tracks: readonly PanoVideoTrack[];
898
+ captionText: string;
899
+ captionAppearance: Required<PanoVideoCaptionAppearance>;
900
+ captionsEnabled: boolean;
901
+ playbackRates: readonly number[];
902
+ playbackState: VideoPlaybackState;
903
+ };
904
+ type PanoVideoController = {
905
+ subscribe: (onStoreChange: () => void) => () => void;
906
+ getSnapshot: () => PanoVideoPlaybackSnapshot;
907
+ play: () => Promise<void>;
908
+ pause: () => void;
909
+ togglePlay: () => void;
910
+ seek: (time: number) => void;
911
+ setVolume: (volume: number) => void;
912
+ setMuted: (muted: boolean) => void;
913
+ toggleMuted: () => void;
914
+ setPlaybackRate: (rate: number) => void;
915
+ setVariantId: (id: string) => void;
916
+ setTrackId: (id: string | null) => void;
917
+ setCaptionAppearance: (appearance: Partial<PanoVideoCaptionAppearance>) => void;
918
+ };
919
+
920
+ type PanoVideoProps = {
921
+ /** Single-file shortcut when `variants` is omitted. */
922
+ src?: string;
923
+ poster?: string;
924
+ variants?: readonly PanoVideoVariant[];
925
+ defaultVariantId?: string;
926
+ tracks?: readonly PanoVideoTrack[];
927
+ /**
928
+ * Caption overlay. `true` / omit uses the default appearance; `false`
929
+ * hides captions and the control-bar language menu; an object merges
930
+ * with the defaults.
931
+ */
932
+ captions?: boolean | PanoVideoCaptionAppearance;
933
+ /**
934
+ * Playback chrome. `true` / omit mounts the default bar; `false` skips
935
+ * it; an object mounts the default bar with appearance overrides.
936
+ * Render `PanoVideoControls` as a PanoViewer child to replace the default.
937
+ */
938
+ controls?: boolean | PanoVideoControlsAppearance;
939
+ /** Horizontal video offset in degrees. */
940
+ yawOffset?: number;
941
+ loop?: boolean;
942
+ muted?: boolean;
943
+ volume?: number;
944
+ autoPlay?: boolean;
945
+ playsInline?: boolean;
946
+ preload?: "none" | "metadata" | "auto";
947
+ crossOrigin?: "" | "anonymous" | "use-credentials";
948
+ playbackRates?: readonly number[];
601
949
  /** Keeps the source mounted for preloading without drawing it. */
602
950
  visible?: boolean;
951
+ onLoad?: () => void;
952
+ onError?: (event: PanoVideoErrorEvent) => void;
953
+ onPlaybackStateChange?: (state: VideoPlaybackState) => void;
954
+ onEnded?: () => void;
955
+ onVariantChange?: (id: string) => void;
956
+ onTrackChange?: (id: string | null) => void;
957
+ };
958
+ /**
959
+ * Equirectangular 360 video mapped onto the panorama sphere. Mount inside
960
+ * PanoViewer. Default playback chrome and captions portal to the viewer overlay.
961
+ */
962
+ declare function PanoVideo({ src, poster, variants: variantsProp, defaultVariantId, tracks: tracksProp, captions, controls, yawOffset, loop, muted, volume, autoPlay, playsInline, preload, crossOrigin, playbackRates, visible, onLoad, onError, onPlaybackStateChange, onEnded, onVariantChange, onTrackChange, }: PanoVideoProps): react.JSX.Element | null;
963
+
964
+ declare const DEFAULT_PANO_VIDEO_CONTROLS_APPEARANCE: Required<PanoVideoControlsAppearance>;
965
+ type PanoVideoControlsProps = {
966
+ appearance?: PanoVideoControlsAppearance;
967
+ };
968
+ /**
969
+ * Claims the default playback chrome slot for a custom replacement.
970
+ * Render inside PanoViewer when overriding the built-in controls.
971
+ */
972
+ declare function PanoVideoControls({ appearance }: PanoVideoControlsProps): null;
973
+
974
+ declare const DEFAULT_PANO_VIDEO_PLAYBACK_RATES: readonly [0.5, 1, 1.25, 1.5, 2];
975
+
976
+ declare const DEFAULT_PANO_VIDEO_CAPTION_APPEARANCE: Required<PanoVideoCaptionAppearance>;
977
+
978
+ type SceneTransitionPreset = "none" | "crossfade" | "zoom" | "blackout" | "whiteFlash" | "slideRightToLeft" | "slideTopToBottom" | "slideDiagonal" | "circleOpen" | "verticalOpen" | "horizontalOpen" | "ellipticZoomOpen" | "pixelate" | "gridWipe" | "gridWipeUp" | "gridWipeRight" | "gridWipeDiagonal" | "gridWipeCenter" | "gridWipeChecker" | "dissolve" | "shatter" | "particles" | "glitch" | "swirl" | "clockWipe" | "ripple" | "zoomBlur" | "hexDissolve" | "filmBurn";
979
+ type SceneTransition = SceneTransitionPreset | {
980
+ preset: SceneTransitionPreset;
981
+ /** Overrides the preset default duration in seconds. */
982
+ duration?: number;
603
983
  };
604
- declare function Sphere({ src, yawOffset, onLoad, onError, visible, }: SphereProps): react.JSX.Element | null;
605
984
 
606
985
  type CubeFaceCode = "f" | "r" | "b" | "l" | "u" | "d";
607
986
  type TileAddress = {
@@ -633,18 +1012,30 @@ type TileLoadError = {
633
1012
  };
634
1013
  type TileProps = {
635
1014
  baseUrl: string;
1015
+ /**
1016
+ * Tile size followed by ascending cube-face sizes (`TILESIZE,LEVELSIZE1,...`).
1017
+ * For krpano output, copy `image.cube.multires` from the XML.
1018
+ */
636
1019
  multires: string | TileMultiresConfig;
637
- /** Defaults to `${baseUrl}/previews/cube-vertical.webp`. */
638
- previewUrl?: string | null;
1020
+ /**
1021
+ * Preview atlas path. Relative paths resolve against `baseUrl`; root-absolute
1022
+ * and `http(s)` / `blob:` / `data:` URLs are used as-is. For krpano output,
1023
+ * copy `<preview url>` (often `preview.jpg` at the scene root). This package's
1024
+ * common cube atlas path is `previews/cube-vertical.webp`.
1025
+ */
1026
+ previewUrl: string;
639
1027
  /**
640
1028
  * Face order in the vertical preview atlas, from top to bottom. Defaults to
641
- * `l/f/r/b/u/d`.
1029
+ * `l/f/r/b/u/d`, matching krpano `preview.striporder` `LFRBUD`.
642
1030
  */
643
1031
  previewFaceOrder?: readonly CubeFaceCode[];
644
1032
  /**
645
- * Relative to `baseUrl`; supports krpano cube-tile `%s` and `%l` placeholders,
646
- * horizontal `%h`/`%x`/`%u`/`%c`, vertical `%v`/`%y`/`%w`/`%r`, and index padding
647
- * such as `%0h` or `%00v`.
1033
+ * Path relative to `baseUrl`. Defaults to
1034
+ * `tiles/%s/l%l/%v/l%l_%s_%h_%v.webp`. For krpano output, copy `<cube url>`
1035
+ * from the XML; krpano templates often use `%v_%h` instead of this default
1036
+ * `%h_%v`, so omitting `urlTemplate` requests the wrong files. Supports
1037
+ * krpano cube-tile `%s` and `%l` placeholders, horizontal `%h`/`%x`/`%u`/`%c`,
1038
+ * vertical `%v`/`%y`/`%w`/`%r`, and index padding such as `%0h` or `%00v`.
648
1039
  */
649
1040
  urlTemplate?: string;
650
1041
  /** Returns a path relative to `baseUrl`; takes precedence over `urlTemplate`. */
@@ -668,16 +1059,11 @@ type TileProps = {
668
1059
  onLevelChange?: (level: number) => void;
669
1060
  };
670
1061
 
671
- type SceneTransitionPreset = "none" | "crossfade" | "zoom" | "blackout" | "whiteFlash" | "slideRightToLeft" | "slideTopToBottom" | "slideDiagonal" | "circleOpen" | "verticalOpen" | "horizontalOpen" | "ellipticZoomOpen";
672
- type SceneTransition = SceneTransitionPreset | {
673
- preset: SceneTransitionPreset;
674
- /** Overrides the KRpano-compatible default duration in seconds. */
675
- duration?: number;
676
- };
677
1062
  type SphereScene = {
678
1063
  id: string;
679
1064
  type: "sphere";
680
1065
  src: string;
1066
+ previewUrl: string;
681
1067
  yawOffset?: number;
682
1068
  };
683
1069
  type TileScene = Omit<TileProps, "loadMode" | "visible" | "onReady" | "onPreviewError" | "onLoadProgress" | "onTileError" | "onLevelChange"> & {
@@ -739,6 +1125,10 @@ type PolygonHotspotProps = Omit<HotspotCommonProps, "position" | "width" | "heig
739
1125
  strokeWidth?: number;
740
1126
  /** Opacity of the polygon boundary, from 0 to 1. Defaults to 1. */
741
1127
  strokeOpacity?: number;
1128
+ /** Dash length in CSS pixels. Omit or 0 for a solid stroke. */
1129
+ strokeDashSize?: number;
1130
+ /** Gap length in CSS pixels. Defaults to `strokeDashSize` when dashed. */
1131
+ strokeGapSize?: number;
742
1132
  onVerticesChange?: (event: PolygonVerticesChangeEvent) => void;
743
1133
  onDragStart?: (event: PolygonVerticesChangeEvent) => void;
744
1134
  onDragEnd?: (event: PolygonVerticesChangeEvent) => void;
@@ -749,7 +1139,7 @@ type UnwrappedVertex = HotspotPosition & {
749
1139
  };
750
1140
  declare function unwrapPolygonVertices(vertices: HotspotPosition[]): UnwrappedVertex[];
751
1141
  declare function validatePolygonVertices(vertices: HotspotPosition[]): PolygonValidationIssue[];
752
- declare function PolygonHotspot({ id, vertices, fill, fillOpacity, stroke, strokeWidth, strokeOpacity, interactive, renderOrder, draggable, onVerticesChange, onDragStart, onDragEnd, onInvalid, ...anchorProps }: PolygonHotspotProps): react.JSX.Element | null;
1142
+ declare function PolygonHotspot({ id, vertices, fill, fillOpacity, stroke, strokeWidth, strokeOpacity, strokeDashSize, strokeGapSize, interactive, renderOrder, draggable, onVerticesChange, onDragStart, onDragEnd, onInvalid, ...anchorProps }: PolygonHotspotProps): react.JSX.Element | null;
753
1143
 
754
1144
  type PolylineValidationIssue = {
755
1145
  code: "too_few_vertices";
@@ -768,13 +1158,17 @@ type PolylineHotspotProps = Omit<HotspotCommonProps, "position" | "width" | "hei
768
1158
  /** Screen-space line width in CSS pixels. Defaults to 2. */
769
1159
  strokeWidth?: number;
770
1160
  strokeOpacity?: number;
1161
+ /** Dash length in CSS pixels. Omit or 0 for a solid stroke. */
1162
+ strokeDashSize?: number;
1163
+ /** Gap length in CSS pixels. Defaults to `strokeDashSize` when dashed. */
1164
+ strokeGapSize?: number;
771
1165
  onVerticesChange?: (event: PolylineVerticesChangeEvent) => void;
772
1166
  onDragStart?: (event: PolylineVerticesChangeEvent) => void;
773
1167
  onDragEnd?: (event: PolylineVerticesChangeEvent) => void;
774
1168
  onInvalid?: (issues: PolylineValidationIssue[]) => void;
775
1169
  };
776
1170
  declare function validatePolylineVertices(vertices: HotspotPosition[]): PolylineValidationIssue[];
777
- declare function PolylineHotspot({ id, vertices, stroke, strokeWidth, strokeOpacity, renderOrder, draggable, onVerticesChange, onDragStart, onDragEnd, onInvalid, ...anchorProps }: PolylineHotspotProps): react.JSX.Element | null;
1171
+ declare function PolylineHotspot({ id, vertices, stroke, strokeWidth, strokeOpacity, strokeDashSize, strokeGapSize, renderOrder, draggable, onVerticesChange, onDragStart, onDragEnd, onInvalid, ...anchorProps }: PolylineHotspotProps): react.JSX.Element | null;
778
1172
 
779
1173
  type GraphicPaint = {
780
1174
  fill?: string;
@@ -857,29 +1251,6 @@ type SequenceHotspotProps = HotspotCommonProps & {
857
1251
  };
858
1252
  declare function SequenceHotspot({ id, src, frameCount: requestedFrameCount, frameDirection, playing, fps, loop, width, height, opacity, onFrameChange, onLoadProgress, onPlaybackStateChange, onEnded, onError, ...anchorProps }: SequenceHotspotProps): react.JSX.Element;
859
1253
 
860
- type VideoPlaybackState = "playing" | "paused" | "ended" | "blocked";
861
- type VideoHotspotErrorEvent = {
862
- id: string;
863
- source: "poster" | "video";
864
- error: unknown;
865
- };
866
- type VideoHotspotProps = HotspotCommonProps & {
867
- src: string;
868
- playing: boolean;
869
- poster?: string;
870
- loop?: boolean;
871
- muted?: boolean;
872
- volume?: number;
873
- playsInline?: boolean;
874
- preload?: "none" | "metadata" | "auto";
875
- crossOrigin?: "" | "anonymous" | "use-credentials";
876
- onPlaybackStateChange?: (state: VideoPlaybackState) => void;
877
- onPlaybackError?: (error: unknown) => void;
878
- onEnded?: () => void;
879
- onError?: (event: VideoHotspotErrorEvent) => void;
880
- };
881
- declare function VideoHotspot({ id, src, playing, poster, loop, muted, volume, playsInline, preload, crossOrigin, width, height, opacity, onPlaybackStateChange, onPlaybackError, onEnded, onError, ...anchorProps }: VideoHotspotProps): react.JSX.Element;
882
-
883
1254
  type TextHotspotAlign = "left" | "center" | "right";
884
1255
  type TextHotspotVerticalAlign = "top" | "middle" | "bottom";
885
1256
  type TextHotspotWhiteSpace = "normal" | "nowrap";
@@ -887,9 +1258,11 @@ type TextHotspotFontStyle = "normal" | "italic";
887
1258
  /** Serializable typography and panel paint for a text hotspot. */
888
1259
  type TextHotspotStyle = {
889
1260
  fontFamily?: string;
890
- /** Fraction of the texture height. Defaults to 0.18. */
1261
+ /** Canvas pixels. Defaults to 96. */
891
1262
  fontSize?: number;
1263
+ /** CSS font-weight. Defaults to 600. */
892
1264
  fontWeight?: number | string;
1265
+ /** CSS font-style. Defaults to `"normal"`. */
893
1266
  fontStyle?: TextHotspotFontStyle;
894
1267
  color?: string;
895
1268
  /** CSS color. An empty string skips the panel fill. */
@@ -931,7 +1304,7 @@ type IframeHotspotProps = HotspotCommonProps & {
931
1304
  onLoad?: () => void;
932
1305
  onError?: (error: unknown) => void;
933
1306
  };
934
- declare function IframeHotspot({ src, title, sandbox, allow, referrerPolicy, loading, pointerPolicy, background, opacity, width, height, onLoad, onError, ...anchorProps }: IframeHotspotProps): react.JSX.Element;
1307
+ declare function IframeHotspot({ src, title, sandbox, allow, referrerPolicy, loading, pointerPolicy, background, opacity, width, height, onLoad, onError, interactive, pointerEvents, ...anchorProps }: IframeHotspotProps): react.JSX.Element;
935
1308
 
936
1309
  declare function Tile({ baseUrl, multires, previewUrl, previewFaceOrder, urlTemplate, resolveTileUrl, maxTextureMemoryMb, maxConcurrentLoads, retryCount, loadMode, visible, onReady, onPreviewError, onLoadProgress, onTileError, onLevelChange, }: TileProps): react.JSX.Element;
937
1310
 
@@ -942,6 +1315,7 @@ declare function panoPositionToVector3(position: HotspotPosition, radius?: numbe
942
1315
  declare function vector3ToPanoPosition(vector: Pick<Vector3, "x" | "y" | "z">): HotspotPosition;
943
1316
 
944
1317
  declare const DEFAULT_HOTSPOT_TOOLTIP_OFFSET = 12;
1318
+ declare const DEFAULT_HOTSPOT_TOOLTIP_APPEARANCE: Required<HotspotTooltipAppearance>;
945
1319
 
946
1320
  /** Shared serializable fields for every saved hotspot definition. */
947
1321
  type HotspotDefinitionBase = {
@@ -950,6 +1324,8 @@ type HotspotDefinitionBase = {
950
1324
  label?: string;
951
1325
  visible?: boolean;
952
1326
  interactive?: boolean;
1327
+ /** Pointer hit-testing. `"none"` ignores mouse, touch, and pen. */
1328
+ pointerEvents?: HotspotPointerEvents;
953
1329
  /** Canvas cursor while this hotspot is hovered. */
954
1330
  cursor?: CSSProperties["cursor"];
955
1331
  renderOrder?: number;
@@ -957,6 +1333,7 @@ type HotspotDefinitionBase = {
957
1333
  tooltipTrigger?: HotspotTooltipTrigger;
958
1334
  tooltipPlacement?: HotspotTooltipPlacement;
959
1335
  tooltipOffset?: number;
1336
+ tooltipAppearance?: HotspotTooltipAppearance;
960
1337
  };
961
1338
  /** Shared serializable fields for a hotspot anchored at one yaw/pitch point. */
962
1339
  type PointHotspotDefinitionBase = HotspotDefinitionBase & {
@@ -1023,6 +1400,8 @@ type PolygonHotspotDefinition = HotspotDefinitionBase & {
1023
1400
  stroke?: string;
1024
1401
  strokeWidth?: number;
1025
1402
  strokeOpacity?: number;
1403
+ strokeDashSize?: number;
1404
+ strokeGapSize?: number;
1026
1405
  };
1027
1406
  /** An open path. This extends the original point and polygon hotspot categories. */
1028
1407
  type PolylineHotspotDefinition = HotspotDefinitionBase & {
@@ -1031,9 +1410,11 @@ type PolylineHotspotDefinition = HotspotDefinitionBase & {
1031
1410
  stroke?: string;
1032
1411
  strokeWidth?: number;
1033
1412
  strokeOpacity?: number;
1413
+ strokeDashSize?: number;
1414
+ strokeGapSize?: number;
1034
1415
  };
1035
1416
  type PointHotspotDefinition = ImageHotspotDefinition | GraphicHotspotDefinition | SequenceHotspotDefinition | VideoHotspotDefinition | TextHotspotDefinition | IframeHotspotDefinition;
1036
1417
  /** A serializable, discriminated hotspot collection item. */
1037
1418
  type HotspotDefinition = PointHotspotDefinition | PolygonHotspotDefinition | PolylineHotspotDefinition;
1038
1419
 
1039
- export { type ArrowGraphic, AutoRotate, type AutoRotateProps, type CircleGraphic, type CubeFaceCode, DEFAULT_HOTSPOT_TOOLTIP_OFFSET, DEFAULT_PANO_CURSORS, type DiamondGraphic, type GraphicDefinition, GraphicHotspot, type GraphicHotspotDefinition, type GraphicHotspotProps, type HotspotCommonProps, type HotspotDefinition, type HotspotDefinitionBase, type HotspotDragEvent, type HotspotInputSource, type HotspotInteractionEvent, type HotspotMode, type HotspotPosition, type HotspotScaleMode, type HotspotTooltipContent, type HotspotTooltipPlacement, type HotspotTooltipTrigger, IframeHotspot, type IframeHotspotDefinition, type IframeHotspotProps, type IframePointerPolicy, ImageHotspot, type ImageHotspotDefinition, type ImageHotspotProps, type KeyboardControlAction, type KeyboardControlKeys, KeyboardControls, type KeyboardControlsProps, MAX_HOTSPOT_PITCH, MIN_PANO_CONTEXT_MENU_BACKGROUND_OPACITY, type MouseControlButton, MouseControls, type MouseControlsOptions, type MouseControlsProps, PanoContextMenu, type PanoContextMenuActionItem, type PanoContextMenuAppearance, type PanoContextMenuEntry, type PanoContextMenuItem, type PanoContextMenuPresetActions, type PanoContextMenuPresetId, type PanoContextMenuPresetRef, type PanoContextMenuPresets, type PanoContextMenuProps, type PanoContextMenuRenderProps, type PanoContextMenuSelectContext, type PanoContextMenuSeparatorItem, type PanoCursor, type PanoCursors, type PanoEventBus, type PanoEventListener, type PanoEventMap, type PanoEventType, PanoEvents, type PanoEventsProps, type PanoResizeEvent, PanoViewer, type PanoViewerHandle, type PanoViewerProps, type PanoViewerState, type PanoWheelEvent, type PanoramaControlsOptions, type PanoramaPointerEvent, type PointHotspotDefinition, type PointHotspotDefinitionBase, PolygonHotspot, type PolygonHotspotDefinition, type PolygonHotspotProps, type PolygonValidationCode, type PolygonValidationIssue, type PolygonVerticesChangeEvent, PolylineHotspot, type PolylineHotspotDefinition, type PolylineHotspotProps, type PolylineValidationIssue, type PolylineVerticesChangeEvent, type RectangleGraphic, type RingGraphic, type Scene, type SceneTransition, type SceneTransitionEndEvent, type SceneTransitionErrorEvent, type SceneTransitionPreset, Scenes, type ScenesProps, type SequenceFrameDirection, type SequenceFrameEvent, SequenceHotspot, type SequenceHotspotDefinition, type SequenceHotspotErrorEvent, type SequenceHotspotProps, type SequenceLoadProgress, type SequencePlaybackState, type SetPanoViewerOptions, Sphere, type SphereProps, type SphereScene, type StarGraphic, type SvgGraphic, type SvgPathGraphic, TextHotspot, type TextHotspotAlign, type TextHotspotDefinition, type TextHotspotFontStyle, type TextHotspotProps, type TextHotspotStyle, type TextHotspotVerticalAlign, type TextHotspotWhiteSpace, Tile, type TileAddress, type TileLoadError, type TileLoadProgress, type TileMultiresConfig, type TileProps, type TileScene, TouchControls, type TouchControlsOptions, type TouchControlsProps, type TriangleGraphic, VideoHotspot, type VideoHotspotDefinition, type VideoHotspotErrorEvent, type VideoHotspotProps, type VideoPlaybackState, type ViewInteractionEvent, type ViewInteractionSource, clampPanoPitch, composePanoContextMenuItems, createDefaultPanoContextMenuItems, createPanoContextMenuPresets, cycleSceneId, normalizePanoPosition, normalizePanoYaw, panoPositionToVector3, resolvePanoContextMenuEntries, unwrapPolygonVertices, usePanoEvents, validatePolygonVertices, validatePolylineVertices, vector3ToPanoPosition };
1420
+ export { type ArrowGraphic, AutoRotate, type AutoRotateProps, type CircleGraphic, type CubeFaceCode, DEFAULT_HOTSPOT_TOOLTIP_APPEARANCE, DEFAULT_HOTSPOT_TOOLTIP_OFFSET, DEFAULT_PANO_CURSORS, DEFAULT_PANO_VIDEO_CAPTION_APPEARANCE, DEFAULT_PANO_VIDEO_CONTROLS_APPEARANCE, DEFAULT_PANO_VIDEO_PLAYBACK_RATES, DEFAULT_WEBVR_CHROME_APPEARANCE, DEFAULT_WEBVR_CURSOR_DWELL_MS, type DiamondGraphic, type GraphicDefinition, GraphicHotspot, type GraphicHotspotDefinition, type GraphicHotspotProps, Gyro, type GyroHandle, type GyroProps, type GyroTouchMode, type HotspotCommonProps, type HotspotDefinition, type HotspotDefinitionBase, type HotspotDragEvent, type HotspotInputSource, type HotspotInteractionEvent, type HotspotMode, type HotspotPointerEvents, type HotspotPosition, type HotspotScaleMode, type HotspotTooltipAppearance, type HotspotTooltipContent, type HotspotTooltipPlacement, type HotspotTooltipTrigger, IframeHotspot, type IframeHotspotDefinition, type IframeHotspotProps, type IframePointerPolicy, ImageHotspot, type ImageHotspotDefinition, type ImageHotspotProps, type KeyboardControlAction, type KeyboardControlKeys, KeyboardControls, type KeyboardControlsProps, MAX_HOTSPOT_PITCH, MIN_PANO_CONTEXT_MENU_BACKGROUND_OPACITY, type MouseControlButton, MouseControls, type MouseControlsOptions, type MouseControlsProps, PANO_FILTER_PRESETS, PanoContextMenu, type PanoContextMenuActionItem, type PanoContextMenuAppearance, type PanoContextMenuEntry, type PanoContextMenuItem, type PanoContextMenuPresetActions, type PanoContextMenuPresetId, type PanoContextMenuPresetRef, type PanoContextMenuPresets, type PanoContextMenuProps, type PanoContextMenuRenderProps, type PanoContextMenuSelectContext, type PanoContextMenuSeparatorItem, type PanoCursor, type PanoCursors, type PanoEventBus, type PanoEventListener, type PanoEventMap, type PanoEventType, PanoEvents, type PanoEventsProps, PanoFilter, type PanoFilterPreset, type PanoFilterProps, type PanoResizeEvent, PanoVideo, type PanoVideoCaptionAppearance, type PanoVideoController, PanoVideoControls, type PanoVideoControlsAppearance, type PanoVideoControlsProps, type PanoVideoErrorEvent, type PanoVideoErrorSource, type PanoVideoPlaybackSnapshot, type PanoVideoProps, type PanoVideoSource, type PanoVideoTrack, type PanoVideoTrackKind, type PanoVideoVariant, PanoViewer, type PanoViewerHandle, type PanoViewerProps, type PanoViewerState, type PanoWheelEvent, type PanoramaControlsOptions, type PanoramaPointerEvent, type PointHotspotDefinition, type PointHotspotDefinitionBase, PolygonHotspot, type PolygonHotspotDefinition, type PolygonHotspotProps, type PolygonValidationCode, type PolygonValidationIssue, type PolygonVerticesChangeEvent, PolylineHotspot, type PolylineHotspotDefinition, type PolylineHotspotProps, type PolylineValidationIssue, type PolylineVerticesChangeEvent, type RectangleGraphic, type RingGraphic, type Scene, type SceneTransition, type SceneTransitionEndEvent, type SceneTransitionErrorEvent, type SceneTransitionPreset, Scenes, type ScenesProps, type SequenceFrameDirection, type SequenceFrameEvent, SequenceHotspot, type SequenceHotspotDefinition, type SequenceHotspotErrorEvent, type SequenceHotspotProps, type SequenceLoadProgress, type SequencePlaybackState, type SetPanoViewerOptions, Sphere, type SphereProps, type SphereScene, type StarGraphic, type SvgGraphic, type SvgPathGraphic, TextHotspot, type TextHotspotAlign, type TextHotspotDefinition, type TextHotspotFontStyle, type TextHotspotProps, type TextHotspotStyle, type TextHotspotVerticalAlign, type TextHotspotWhiteSpace, Tile, type TileAddress, type TileLoadError, type TileLoadProgress, type TileMultiresConfig, type TileProps, type TileScene, TouchControls, type TouchControlsOptions, type TouchControlsProps, type TriangleGraphic, VideoHotspot, type VideoHotspotDefinition, type VideoHotspotErrorEvent, type VideoHotspotProps, type VideoPlaybackState, type ViewInteractionEvent, type ViewInteractionSource, WEBVR_PROFILES, WEBVR_PROFILE_IDS, WebVR, type WebVRChrome, type WebVRChromeAppearance, type WebVRHandle, type WebVRMode, type WebVRProfile, type WebVRProfileId, type WebVRProps, type WebVRSettings, clampPanoPitch, composePanoContextMenuItems, createDefaultPanoContextMenuItems, createPanoContextMenuPresets, cycleSceneId, normalizePanoPosition, normalizePanoYaw, panoPositionToVector3, resolvePanoContextMenuEntries, unwrapPolygonVertices, usePanoEvents, validatePolygonVertices, validatePolylineVertices, vector3ToPanoPosition };