@ericchen1990/pano-view 0.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ReactNode, CSSProperties, ComponentPropsWithoutRef } from 'react';
2
+ import { CSSProperties, ReactNode, ComponentPropsWithoutRef, IframeHTMLAttributes } from 'react';
3
3
  import { Texture, ColorRepresentation, Vector3 } from 'three';
4
4
 
5
5
  declare const MAX_HOTSPOT_PITCH = 90;
@@ -29,9 +29,50 @@ type HotspotDragEvent = HotspotInteractionEvent & {
29
29
  source: "pointer";
30
30
  startPosition: HotspotPosition;
31
31
  };
32
+ /** When a hotspot tooltip is shown. Defaults to `"always"`. */
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";
39
+ /** Where the tooltip sits relative to the hotspot. Defaults to `"top"`. */
40
+ type HotspotTooltipPlacement = "top" | "bottom" | "left" | "right";
41
+ /** Plain-text and/or image content for a hotspot tooltip. */
42
+ type HotspotTooltipContent = {
43
+ text?: string;
44
+ image?: string;
45
+ imageAlt?: string;
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
+ };
32
57
  type HotspotCommonProps = {
33
58
  id: string;
34
59
  position: HotspotPosition;
60
+ /**
61
+ * Tooltip shown at the hotspot anchor. A string is treated as `{ text }`.
62
+ * Defaults to always visible when content is present.
63
+ */
64
+ tooltip?: string | HotspotTooltipContent;
65
+ /** Defaults to `"always"`. `"hover"` and `"click"` require `interactive` and `pointerEvents` other than `"none"`. */
66
+ tooltipTrigger?: HotspotTooltipTrigger;
67
+ /** Screen direction for the tooltip. Defaults to `"top"`. */
68
+ tooltipPlacement?: HotspotTooltipPlacement;
69
+ /**
70
+ * Screen-space gap in CSS pixels between the hotspot edge and the tooltip.
71
+ * Defaults to 12.
72
+ */
73
+ tooltipOffset?: number;
74
+ /** Optional bubble paint overrides. Unset fields use the library default theme. */
75
+ tooltipAppearance?: HotspotTooltipAppearance;
35
76
  /** Angular width in degrees. Defaults to 12. */
36
77
  width?: number;
37
78
  /** Angular height in degrees. Defaults to 8. */
@@ -56,6 +97,17 @@ type HotspotCommonProps = {
56
97
  visible?: boolean;
57
98
  /** Whether the hotspot accepts pointer and keyboard interaction. Defaults to true. */
58
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;
106
+ /**
107
+ * Canvas cursor while this hotspot is hovered. Defaults to the viewer's
108
+ * `cursors.hotspot` value (`"pointer"`).
109
+ */
110
+ cursor?: CSSProperties["cursor"];
59
111
  draggable?: boolean;
60
112
  /** Required for keyboard-accessible clickable hotspots. */
61
113
  ariaLabel?: string;
@@ -96,7 +148,7 @@ type KeyboardControlsProps = {
96
148
  invert?: boolean;
97
149
  /**
98
150
  * Maximum FOV change rate in degrees per second. When omitted, no extra
99
- * rate cap is applied. Usually supplied by PanoView from `controls.fovSpeed`.
151
+ * rate cap is applied. Usually supplied by PanoViewer from `controls.fovSpeed`.
100
152
  */
101
153
  fovSpeed?: number;
102
154
  /** Called once when the previous-scene binding is pressed. */
@@ -113,14 +165,15 @@ declare function cycleSceneId(scenes: readonly {
113
165
  id: string;
114
166
  }[], activeSceneId: string, step: 1 | -1): string | null;
115
167
  /**
116
- * Adds keyboard navigation to the nearest PanoView. PanoView mounts a default
117
- * instance; render your own to customize bindings or scene callbacks. Hold
118
- * movement/zoom keys for continuous motion; scene and reset bindings fire once
119
- * per key press.
168
+ * Adds keyboard navigation to the nearest PanoViewer. Enabled by default;
169
+ * render this component only to override properties, bindings, or scene
170
+ * callbacks. Hold movement/zoom keys for continuous motion; scene and reset
171
+ * bindings fire once per key press. Click the viewer to focus it before
172
+ * keys are received.
120
173
  */
121
174
  declare function KeyboardControls({ enabled, keys, rotateSpeed, zoomSpeed, shiftMultiplier, invert, fovSpeed, onPreviousScene, onNextScene, }: KeyboardControlsProps): null;
122
175
 
123
- type PanoViewState = {
176
+ type PanoViewerState = {
124
177
  /** Horizontal look angle in degrees. Positive values look right. */
125
178
  yaw: number;
126
179
  /** Vertical look angle in degrees. Positive values look up. */
@@ -128,13 +181,13 @@ type PanoViewState = {
128
181
  /** Vertical perspective field of view in degrees. */
129
182
  fov: number;
130
183
  };
131
- type SetPanoViewOptions = {
184
+ type SetPanoViewerOptions = {
132
185
  /** Apply the new view immediately instead of preserving current inertia. */
133
186
  immediate?: boolean;
134
187
  };
135
- type PanoViewHandle = {
136
- getView: () => PanoViewState;
137
- setView: (view: Partial<PanoViewState>, options?: SetPanoViewOptions) => void;
188
+ type PanoViewerHandle = {
189
+ getView: () => PanoViewerState;
190
+ setView: (view: Partial<PanoViewerState>, options?: SetPanoViewerOptions) => void;
138
191
  reset: () => void;
139
192
  /** @deprecated Control an AutoRotate component's enabled prop instead. */
140
193
  startAutoRotate: () => void;
@@ -172,12 +225,12 @@ type TouchControlsOptions = {
172
225
  type PanoramaControlsOptions = {
173
226
  /**
174
227
  * Master switch for user view controls. Defaults to true. Setting
175
- * `controls={false}` on PanoView still disables all user input.
228
+ * `controls={false}` on PanoViewer still disables all user input.
176
229
  */
177
230
  enabled?: boolean;
178
231
  /** Enables drag and zoom inertia. Defaults to true. */
179
232
  inertia?: boolean;
180
- /** @deprecated Render <AutoRotate enabled /> inside PanoView instead. */
233
+ /** @deprecated Render <AutoRotate enabled /> inside PanoViewer instead. */
181
234
  autoRotate?: boolean;
182
235
  /** @deprecated Use AutoRotate's speed prop instead. */
183
236
  autoRotateSpeed?: number;
@@ -222,9 +275,9 @@ type PanoramaControlsOptions = {
222
275
  */
223
276
  zoomDamping?: number;
224
277
  /**
225
- * Mouse channel. `true` / omit mounts defaults; `false` skips the default
226
- * instance (render a custom MouseControls child); an object merges with
227
- * defaults and supports `enabled`.
278
+ * Mouse channel. `true` / omit mounts defaults; `false` disables the
279
+ * default instance; an object merges with defaults and supports `enabled`.
280
+ * Rendering `<MouseControls />` as a child also replaces the default.
228
281
  */
229
282
  mouse?: boolean | MouseControlsOptions;
230
283
  /**
@@ -232,8 +285,8 @@ type PanoramaControlsOptions = {
232
285
  */
233
286
  touch?: boolean | TouchControlsOptions;
234
287
  /**
235
- * Keyboard channel. Same shape as `mouse`. Set to false when providing a
236
- * custom KeyboardControls child.
288
+ * Keyboard channel. Same shape as `mouse`. Rendering `<KeyboardControls />`
289
+ * as a child replaces the default (no need to set this to false).
237
290
  */
238
291
  keyboard?: boolean | KeyboardControlsProps;
239
292
  };
@@ -242,7 +295,7 @@ type PanoramaControlsOptions = {
242
295
  declare const MIN_PANO_CONTEXT_MENU_BACKGROUND_OPACITY = 0.4;
243
296
  type PanoContextMenuSelectContext = {
244
297
  position: PanoramaPointerEvent["position"];
245
- view: PanoViewState;
298
+ view: PanoViewerState;
246
299
  nativeEvent: MouseEvent | PointerEvent;
247
300
  close: () => void;
248
301
  };
@@ -308,7 +361,7 @@ type PanoContextMenuAppearance = {
308
361
  };
309
362
  type PanoContextMenuRenderProps = {
310
363
  event: PanoramaPointerEvent;
311
- view: PanoViewState;
364
+ view: PanoViewerState;
312
365
  close: () => void;
313
366
  };
314
367
  type PanoContextMenuProps = {
@@ -341,8 +394,8 @@ type PanoContextMenuProps = {
341
394
  children?: (props: PanoContextMenuRenderProps) => ReactNode;
342
395
  };
343
396
  /**
344
- * Custom panorama context menu. Must render inside PanoView. Prefer
345
- * PanoView's `contextMenu` prop for the default menu; use this component
397
+ * Custom panorama context menu. Must render inside PanoViewer. Prefer
398
+ * PanoViewer's `contextMenu` prop for the default menu; use this component
346
399
  * when replacing the default instance (`contextMenu={false}`).
347
400
  */
348
401
  declare function PanoContextMenu({ items, prepend, append, appearance, className, style, itemClassName, separatorClassName, children, }: PanoContextMenuProps): null;
@@ -362,7 +415,7 @@ type PanoContextMenuPresets = {
362
415
  /**
363
416
  * Builds reusable built-in context-menu items. Prefer preset id strings
364
417
  * (`"resetView"`, `"fullscreen"`) in `items` / `append` / `prepend` when
365
- * configuring `PanoView`; use this helper when assembling items manually.
418
+ * configuring `PanoViewer`; use this helper when assembling items manually.
366
419
  */
367
420
  declare function createPanoContextMenuPresets(actions: PanoContextMenuPresetActions): PanoContextMenuPresets;
368
421
  /** Alias for `createPanoContextMenuPresets(actions).defaults`. */
@@ -376,12 +429,33 @@ declare function resolvePanoContextMenuEntries(entries: readonly PanoContextMenu
376
429
  */
377
430
  declare function composePanoContextMenuItems(props: Pick<PanoContextMenuProps, "items" | "prepend" | "append">, presets: PanoContextMenuPresets): PanoContextMenuItem[];
378
431
 
379
- type PanoViewProps = Omit<ComponentPropsWithoutRef<"div">, "children" | "onChange" | "contextMenu"> & {
432
+ /** A CSS `cursor` value applied to the panorama canvas. */
433
+ type PanoCursor = NonNullable<CSSProperties["cursor"]>;
434
+ /** Canvas cursor values for viewer idle, drag, and hotspot interaction. */
435
+ type PanoCursors = {
436
+ /** Idle canvas cursor. Defaults to `"grab"`. */
437
+ default?: PanoCursor;
438
+ /** Cursor while dragging the panorama with the mouse. Defaults to `"grabbing"`. */
439
+ dragging?: PanoCursor;
440
+ /** Cursor while hovering an interactive hotspot. Defaults to `"pointer"`. */
441
+ hotspot?: PanoCursor;
442
+ /** Cursor while dragging a hotspot. Defaults to `"move"`. */
443
+ hotspotDragging?: PanoCursor;
444
+ };
445
+ declare const DEFAULT_PANO_CURSORS: Required<PanoCursors>;
446
+
447
+ type PanoViewerProps = Omit<ComponentPropsWithoutRef<"div">, "children" | "onChange" | "contextMenu"> & {
380
448
  children?: ReactNode;
381
- initialView?: Partial<PanoViewState>;
449
+ initialView?: Partial<PanoViewerState>;
382
450
  minFov?: number;
383
451
  maxFov?: number;
384
452
  controls?: boolean | PanoramaControlsOptions;
453
+ /**
454
+ * Canvas cursor. `true` / omit uses grab / grabbing / pointer / move;
455
+ * `false` leaves the canvas cursor unchanged; an object merges with the
456
+ * defaults (`default`, `dragging`, `hotspot`, `hotspotDragging`).
457
+ */
458
+ cursors?: boolean | PanoCursors;
385
459
  /**
386
460
  * Default context menu. `true` / omit mounts Reset view + Fullscreen;
387
461
  * `false` skips the default instance; an object merges appearance and
@@ -389,19 +463,25 @@ type PanoViewProps = Omit<ComponentPropsWithoutRef<"div">, "children" | "onChang
389
463
  * `append` to keep the defaults and add entries.
390
464
  */
391
465
  contextMenu?: boolean | PanoContextMenuProps;
392
- onViewChange?: (view: PanoViewState) => void;
466
+ onViewChange?: (view: PanoViewerState) => void;
393
467
  onPanoramaClick?: (event: PanoramaPointerEvent) => void;
394
468
  onPanoramaDoubleClick?: (event: PanoramaPointerEvent) => void;
395
469
  onPanoramaPointerMove?: (event: PanoramaPointerEvent) => void;
396
470
  /** Canvas pixel ratio. Defaults to a capped range of 1–2. */
397
471
  dpr?: number | [number, number];
398
472
  };
399
- declare const PanoView: react.ForwardRefExoticComponent<Omit<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "children" | "contextMenu" | "onChange"> & {
473
+ declare const PanoViewer: react.ForwardRefExoticComponent<Omit<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "children" | "contextMenu" | "onChange"> & {
400
474
  children?: ReactNode;
401
- initialView?: Partial<PanoViewState>;
475
+ initialView?: Partial<PanoViewerState>;
402
476
  minFov?: number;
403
477
  maxFov?: number;
404
478
  controls?: boolean | PanoramaControlsOptions;
479
+ /**
480
+ * Canvas cursor. `true` / omit uses grab / grabbing / pointer / move;
481
+ * `false` leaves the canvas cursor unchanged; an object merges with the
482
+ * defaults (`default`, `dragging`, `hotspot`, `hotspotDragging`).
483
+ */
484
+ cursors?: boolean | PanoCursors;
405
485
  /**
406
486
  * Default context menu. `true` / omit mounts Reset view + Fullscreen;
407
487
  * `false` skips the default instance; an object merges appearance and
@@ -409,13 +489,13 @@ declare const PanoView: react.ForwardRefExoticComponent<Omit<Omit<react.Detailed
409
489
  * `append` to keep the defaults and add entries.
410
490
  */
411
491
  contextMenu?: boolean | PanoContextMenuProps;
412
- onViewChange?: (view: PanoViewState) => void;
492
+ onViewChange?: (view: PanoViewerState) => void;
413
493
  onPanoramaClick?: (event: PanoramaPointerEvent) => void;
414
494
  onPanoramaDoubleClick?: (event: PanoramaPointerEvent) => void;
415
495
  onPanoramaPointerMove?: (event: PanoramaPointerEvent) => void;
416
496
  /** Canvas pixel ratio. Defaults to a capped range of 1–2. */
417
497
  dpr?: number | [number, number];
418
- } & react.RefAttributes<PanoViewHandle>>;
498
+ } & react.RefAttributes<PanoViewerHandle>>;
419
499
 
420
500
  /** Options for automatic horizontal panorama rotation. */
421
501
  type AutoRotateProps = {
@@ -432,11 +512,155 @@ type AutoRotateProps = {
432
512
  startDelay?: number;
433
513
  };
434
514
  /**
435
- * Adds automatic rotation to the nearest PanoView. Render one instance as a
436
- * child of PanoView, alongside its panorama source.
515
+ * Adds automatic rotation to the nearest PanoViewer. Render one instance as a
516
+ * child of PanoViewer, alongside its panorama source.
437
517
  */
438
518
  declare function AutoRotate({ enabled, speed, acceleration, startDelay, }: AutoRotateProps): null;
439
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
+
440
664
  type ViewInteractionSource = "mouse" | "touch" | "keyboard";
441
665
  type PanoWheelEvent = {
442
666
  /** Signed wheel delta (same sign convention as WheelEvent.deltaY). */
@@ -451,8 +675,8 @@ type ViewInteractionEvent = {
451
675
  source: ViewInteractionSource;
452
676
  };
453
677
  type PanoEventMap = {
454
- viewchange: PanoViewState;
455
- viewsettled: PanoViewState;
678
+ viewchange: PanoViewerState;
679
+ viewsettled: PanoViewerState;
456
680
  viewinteractionstart: ViewInteractionEvent;
457
681
  viewinteractionend: ViewInteractionEvent;
458
682
  click: PanoramaPointerEvent;
@@ -470,6 +694,23 @@ type PanoEventMap = {
470
694
  autorotatestart: undefined;
471
695
  autorotatestop: undefined;
472
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;
473
714
  };
474
715
  type PanoEventType = keyof PanoEventMap;
475
716
  type PanoEventListener<T extends PanoEventType> = (payload: PanoEventMap[T]) => void;
@@ -484,8 +725,8 @@ type PanoEventsProps = {
484
725
  * Each PanoEvents instance tracks idle independently.
485
726
  */
486
727
  idleTime?: number;
487
- onViewChange?: (view: PanoViewState) => void;
488
- onViewSettled?: (view: PanoViewState) => void;
728
+ onViewChange?: (view: PanoViewerState) => void;
729
+ onViewSettled?: (view: PanoViewerState) => void;
489
730
  onViewInteractionStart?: (event: ViewInteractionEvent) => void;
490
731
  onViewInteractionEnd?: (event: ViewInteractionEvent) => void;
491
732
  onClick?: (event: PanoramaPointerEvent) => void;
@@ -503,14 +744,25 @@ type PanoEventsProps = {
503
744
  onAutoRotateStart?: () => void;
504
745
  onAutoRotateStop?: () => void;
505
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;
506
758
  };
507
759
  /**
508
- * Subscribes to viewer-level panorama events. Must run inside PanoView.
760
+ * Subscribes to viewer-level panorama events. Must run inside PanoViewer.
509
761
  * Prefer the {@link PanoEvents} component for declarative usage.
510
762
  */
511
- 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;
512
764
  /**
513
- * Declarative viewer-level event listeners for the nearest PanoView.
765
+ * Declarative viewer-level event listeners for the nearest PanoViewer.
514
766
  * Multiple instances may coexist; each tracks its own idle timer.
515
767
  */
516
768
  declare function PanoEvents(props: PanoEventsProps): null;
@@ -518,21 +770,21 @@ declare function PanoEvents(props: PanoEventsProps): null;
518
770
  type MouseControlsProps = MouseControlsOptions & {
519
771
  /**
520
772
  * Maximum FOV change rate in degrees per second for wheel zoom. When
521
- * omitted, no extra rate cap is applied. Usually supplied by PanoView from
773
+ * omitted, no extra rate cap is applied. Usually supplied by PanoViewer from
522
774
  * `controls.fovSpeed`.
523
775
  */
524
776
  fovSpeed?: number;
525
777
  };
526
778
  /**
527
- * Adds mouse (and pen) drag / wheel navigation to the nearest PanoView.
528
- * PanoView mounts a default instance; render your own only to override.
779
+ * Adds mouse (and pen) drag / wheel navigation to the nearest PanoViewer.
780
+ * Enabled by default; render this component only to override properties.
529
781
  */
530
782
  declare function MouseControls({ enabled, rotateSpeed, zoomSpeed, wheel, invert, buttons, fovSpeed, }: MouseControlsProps): null;
531
783
 
532
784
  type TouchControlsProps = TouchControlsOptions;
533
785
  /**
534
- * Adds touch drag and pinch-zoom navigation to the nearest PanoView.
535
- * PanoView mounts a default instance; render your own only to override.
786
+ * Adds touch drag and pinch-zoom navigation to the nearest PanoViewer.
787
+ * Enabled by default; render this component only to override properties.
536
788
  */
537
789
  declare function TouchControls({ enabled, rotateSpeed, invert, pinchZoom, }: TouchControlsProps): null;
538
790
 
@@ -547,6 +799,178 @@ type SphereProps = {
547
799
  };
548
800
  declare function Sphere({ src, yawOffset, onLoad, onError, visible, }: SphereProps): react.JSX.Element | null;
549
801
 
802
+ type VideoPlaybackState = "playing" | "paused" | "ended" | "blocked";
803
+ type VideoHotspotErrorEvent = {
804
+ id: string;
805
+ source: "poster" | "video";
806
+ error: unknown;
807
+ };
808
+ type VideoHotspotProps = HotspotCommonProps & {
809
+ src: string;
810
+ playing: boolean;
811
+ poster?: string;
812
+ loop?: boolean;
813
+ muted?: boolean;
814
+ volume?: number;
815
+ playsInline?: boolean;
816
+ preload?: "none" | "metadata" | "auto";
817
+ crossOrigin?: "" | "anonymous" | "use-credentials";
818
+ onPlaybackStateChange?: (state: VideoPlaybackState) => void;
819
+ onPlaybackError?: (error: unknown) => void;
820
+ onEnded?: () => void;
821
+ onError?: (event: VideoHotspotErrorEvent) => void;
822
+ };
823
+ 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;
824
+
825
+ type PanoVideoSource = {
826
+ src: string;
827
+ type?: string;
828
+ };
829
+ type PanoVideoVariant = {
830
+ id: string;
831
+ label: string;
832
+ poster?: string;
833
+ sources: readonly PanoVideoSource[];
834
+ };
835
+ type PanoVideoTrackKind = "subtitles" | "captions";
836
+ type PanoVideoTrack = {
837
+ /** Defaults to `srcLang`. */
838
+ id?: string;
839
+ src: string;
840
+ srcLang: string;
841
+ label: string;
842
+ kind?: PanoVideoTrackKind;
843
+ default?: boolean;
844
+ };
845
+ type PanoVideoCaptionAppearance = {
846
+ color?: string;
847
+ background?: string;
848
+ fontSize?: number | string;
849
+ fontFamily?: string;
850
+ fontWeight?: CSSProperties["fontWeight"];
851
+ textShadow?: string;
852
+ padding?: string;
853
+ borderRadius?: number | string;
854
+ maxWidth?: number | string;
855
+ bottom?: number | string;
856
+ lineHeight?: number | string;
857
+ };
858
+ type PanoVideoControlsAppearance = {
859
+ background?: string;
860
+ color?: string;
861
+ accent?: string;
862
+ borderRadius?: number | string;
863
+ fontSize?: number | string;
864
+ padding?: string;
865
+ };
866
+ type PanoVideoErrorSource = "poster" | "video" | "track";
867
+ type PanoVideoErrorEvent = {
868
+ source: PanoVideoErrorSource;
869
+ error: unknown;
870
+ };
871
+ type PanoVideoPlaybackSnapshot = {
872
+ ready: boolean;
873
+ playing: boolean;
874
+ blocked: boolean;
875
+ ended: boolean;
876
+ currentTime: number;
877
+ duration: number;
878
+ volume: number;
879
+ /** False when the element ignores `volume` (iOS Safari). Mute still works. */
880
+ volumeAdjustable: boolean;
881
+ muted: boolean;
882
+ playbackRate: number;
883
+ variantId: string;
884
+ variants: readonly PanoVideoVariant[];
885
+ trackId: string | null;
886
+ tracks: readonly PanoVideoTrack[];
887
+ captionText: string;
888
+ captionAppearance: Required<PanoVideoCaptionAppearance>;
889
+ captionsEnabled: boolean;
890
+ playbackRates: readonly number[];
891
+ playbackState: VideoPlaybackState;
892
+ };
893
+ type PanoVideoController = {
894
+ subscribe: (onStoreChange: () => void) => () => void;
895
+ getSnapshot: () => PanoVideoPlaybackSnapshot;
896
+ play: () => Promise<void>;
897
+ pause: () => void;
898
+ togglePlay: () => void;
899
+ seek: (time: number) => void;
900
+ setVolume: (volume: number) => void;
901
+ setMuted: (muted: boolean) => void;
902
+ toggleMuted: () => void;
903
+ setPlaybackRate: (rate: number) => void;
904
+ setVariantId: (id: string) => void;
905
+ setTrackId: (id: string | null) => void;
906
+ setCaptionAppearance: (appearance: Partial<PanoVideoCaptionAppearance>) => void;
907
+ };
908
+
909
+ type PanoVideoProps = {
910
+ /** Single-file shortcut when `variants` is omitted. */
911
+ src?: string;
912
+ poster?: string;
913
+ variants?: readonly PanoVideoVariant[];
914
+ defaultVariantId?: string;
915
+ tracks?: readonly PanoVideoTrack[];
916
+ /**
917
+ * Caption overlay. `true` / omit uses the default appearance; `false`
918
+ * hides captions and the control-bar language menu; an object merges
919
+ * with the defaults.
920
+ */
921
+ captions?: boolean | PanoVideoCaptionAppearance;
922
+ /**
923
+ * Playback chrome. `true` / omit mounts the default bar; `false` skips
924
+ * it; an object mounts the default bar with appearance overrides.
925
+ * Render `PanoVideoControls` as a PanoViewer child to replace the default.
926
+ */
927
+ controls?: boolean | PanoVideoControlsAppearance;
928
+ /** Horizontal video offset in degrees. */
929
+ yawOffset?: number;
930
+ loop?: boolean;
931
+ muted?: boolean;
932
+ volume?: number;
933
+ autoPlay?: boolean;
934
+ playsInline?: boolean;
935
+ preload?: "none" | "metadata" | "auto";
936
+ crossOrigin?: "" | "anonymous" | "use-credentials";
937
+ playbackRates?: readonly number[];
938
+ /** Keeps the source mounted for preloading without drawing it. */
939
+ visible?: boolean;
940
+ onLoad?: () => void;
941
+ onError?: (event: PanoVideoErrorEvent) => void;
942
+ onPlaybackStateChange?: (state: VideoPlaybackState) => void;
943
+ onEnded?: () => void;
944
+ onVariantChange?: (id: string) => void;
945
+ onTrackChange?: (id: string | null) => void;
946
+ };
947
+ /**
948
+ * Equirectangular 360 video mapped onto the panorama sphere. Mount inside
949
+ * PanoViewer. Default playback chrome and captions portal to the viewer overlay.
950
+ */
951
+ 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;
952
+
953
+ declare const DEFAULT_PANO_VIDEO_CONTROLS_APPEARANCE: Required<PanoVideoControlsAppearance>;
954
+ type PanoVideoControlsProps = {
955
+ appearance?: PanoVideoControlsAppearance;
956
+ };
957
+ /**
958
+ * Claims the default playback chrome slot for a custom replacement.
959
+ * Render inside PanoViewer when overriding the built-in controls.
960
+ */
961
+ declare function PanoVideoControls({ appearance }: PanoVideoControlsProps): null;
962
+
963
+ declare const DEFAULT_PANO_VIDEO_PLAYBACK_RATES: readonly [0.5, 1, 1.25, 1.5, 2];
964
+
965
+ declare const DEFAULT_PANO_VIDEO_CAPTION_APPEARANCE: Required<PanoVideoCaptionAppearance>;
966
+
967
+ 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";
968
+ type SceneTransition = SceneTransitionPreset | {
969
+ preset: SceneTransitionPreset;
970
+ /** Overrides the preset default duration in seconds. */
971
+ duration?: number;
972
+ };
973
+
550
974
  type CubeFaceCode = "f" | "r" | "b" | "l" | "u" | "d";
551
975
  type TileAddress = {
552
976
  face: CubeFaceCode;
@@ -612,40 +1036,34 @@ type TileProps = {
612
1036
  onLevelChange?: (level: number) => void;
613
1037
  };
614
1038
 
615
- type PanoramaTransitionPreset = "none" | "crossfade" | "zoom" | "blackout" | "whiteFlash" | "slideRightToLeft" | "slideTopToBottom" | "slideDiagonal" | "circleOpen" | "verticalOpen" | "horizontalOpen" | "ellipticZoomOpen";
616
- type PanoramaTransition = PanoramaTransitionPreset | {
617
- preset: PanoramaTransitionPreset;
618
- /** Overrides the KRpano-compatible default duration in seconds. */
619
- duration?: number;
620
- };
621
- type SpherePanoramaScene = {
1039
+ type SphereScene = {
622
1040
  id: string;
623
1041
  type: "sphere";
624
1042
  src: string;
625
1043
  yawOffset?: number;
626
1044
  };
627
- type TilePanoramaScene = Omit<TileProps, "loadMode" | "visible" | "onReady" | "onPreviewError" | "onLoadProgress" | "onTileError" | "onLevelChange"> & {
1045
+ type TileScene = Omit<TileProps, "loadMode" | "visible" | "onReady" | "onPreviewError" | "onLoadProgress" | "onTileError" | "onLevelChange"> & {
628
1046
  id: string;
629
1047
  type: "tile";
630
1048
  };
631
- type PanoramaScene = SpherePanoramaScene | TilePanoramaScene;
632
- type PanoramaTransitionEndEvent = {
1049
+ type Scene = SphereScene | TileScene;
1050
+ type SceneTransitionEndEvent = {
633
1051
  previousSceneId: string;
634
1052
  sceneId: string;
635
- preset: PanoramaTransitionPreset;
1053
+ preset: SceneTransitionPreset;
636
1054
  };
637
- type PanoramaTransitionErrorEvent = {
1055
+ type SceneTransitionErrorEvent = {
638
1056
  sceneId: string;
639
1057
  error: unknown;
640
1058
  };
641
- type PanoramaScenesProps = {
642
- scenes: readonly PanoramaScene[];
1059
+ type ScenesProps = {
1060
+ scenes: readonly Scene[];
643
1061
  activeSceneId: string;
644
- transition?: PanoramaTransition;
1062
+ transition?: SceneTransition;
645
1063
  /** Rendered only after a scene has finished transitioning in. */
646
- renderHotspots?: (scene: PanoramaScene) => ReactNode;
647
- onTransitionEnd?: (event: PanoramaTransitionEndEvent) => void;
648
- onTransitionError?: (event: PanoramaTransitionErrorEvent) => void;
1064
+ renderHotspots?: (scene: Scene) => ReactNode;
1065
+ onTransitionEnd?: (event: SceneTransitionEndEvent) => void;
1066
+ onTransitionError?: (event: SceneTransitionErrorEvent) => void;
649
1067
  /** Viewer-wide budget shared by every tile scene. Defaults to 128 MiB. */
650
1068
  maxTextureMemoryMb?: number;
651
1069
  /** Viewer-wide tile request limit. Defaults to 4. */
@@ -653,7 +1071,7 @@ type PanoramaScenesProps = {
653
1071
  /** Maximum physical-pixel area of the outgoing GPU snapshot. */
654
1072
  snapshotMaxPixels?: number;
655
1073
  };
656
- declare function PanoramaScenes({ maxTextureMemoryMb, maxConcurrentTileLoads, ...props }: PanoramaScenesProps): react.JSX.Element;
1074
+ declare function Scenes({ maxTextureMemoryMb, maxConcurrentTileLoads, ...props }: ScenesProps): react.JSX.Element;
657
1075
 
658
1076
  type ImageHotspotProps = HotspotCommonProps & {
659
1077
  src: string;
@@ -683,6 +1101,10 @@ type PolygonHotspotProps = Omit<HotspotCommonProps, "position" | "width" | "heig
683
1101
  strokeWidth?: number;
684
1102
  /** Opacity of the polygon boundary, from 0 to 1. Defaults to 1. */
685
1103
  strokeOpacity?: number;
1104
+ /** Dash length in CSS pixels. Omit or 0 for a solid stroke. */
1105
+ strokeDashSize?: number;
1106
+ /** Gap length in CSS pixels. Defaults to `strokeDashSize` when dashed. */
1107
+ strokeGapSize?: number;
686
1108
  onVerticesChange?: (event: PolygonVerticesChangeEvent) => void;
687
1109
  onDragStart?: (event: PolygonVerticesChangeEvent) => void;
688
1110
  onDragEnd?: (event: PolygonVerticesChangeEvent) => void;
@@ -693,7 +1115,7 @@ type UnwrappedVertex = HotspotPosition & {
693
1115
  };
694
1116
  declare function unwrapPolygonVertices(vertices: HotspotPosition[]): UnwrappedVertex[];
695
1117
  declare function validatePolygonVertices(vertices: HotspotPosition[]): PolygonValidationIssue[];
696
- declare function PolygonHotspot({ id, vertices, fill, fillOpacity, stroke, strokeWidth, strokeOpacity, interactive, renderOrder, draggable, onVerticesChange, onDragStart, onDragEnd, onInvalid, ...anchorProps }: PolygonHotspotProps): react.JSX.Element | null;
1118
+ 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;
697
1119
 
698
1120
  type PolylineValidationIssue = {
699
1121
  code: "too_few_vertices";
@@ -712,13 +1134,17 @@ type PolylineHotspotProps = Omit<HotspotCommonProps, "position" | "width" | "hei
712
1134
  /** Screen-space line width in CSS pixels. Defaults to 2. */
713
1135
  strokeWidth?: number;
714
1136
  strokeOpacity?: number;
1137
+ /** Dash length in CSS pixels. Omit or 0 for a solid stroke. */
1138
+ strokeDashSize?: number;
1139
+ /** Gap length in CSS pixels. Defaults to `strokeDashSize` when dashed. */
1140
+ strokeGapSize?: number;
715
1141
  onVerticesChange?: (event: PolylineVerticesChangeEvent) => void;
716
1142
  onDragStart?: (event: PolylineVerticesChangeEvent) => void;
717
1143
  onDragEnd?: (event: PolylineVerticesChangeEvent) => void;
718
1144
  onInvalid?: (issues: PolylineValidationIssue[]) => void;
719
1145
  };
720
1146
  declare function validatePolylineVertices(vertices: HotspotPosition[]): PolylineValidationIssue[];
721
- declare function PolylineHotspot({ id, vertices, stroke, strokeWidth, strokeOpacity, renderOrder, draggable, onVerticesChange, onDragStart, onDragEnd, onInvalid, ...anchorProps }: PolylineHotspotProps): react.JSX.Element | null;
1147
+ declare function PolylineHotspot({ id, vertices, stroke, strokeWidth, strokeOpacity, strokeDashSize, strokeGapSize, renderOrder, draggable, onVerticesChange, onDragStart, onDragEnd, onInvalid, ...anchorProps }: PolylineHotspotProps): react.JSX.Element | null;
722
1148
 
723
1149
  type GraphicPaint = {
724
1150
  fill?: string;
@@ -801,28 +1227,60 @@ type SequenceHotspotProps = HotspotCommonProps & {
801
1227
  };
802
1228
  declare function SequenceHotspot({ id, src, frameCount: requestedFrameCount, frameDirection, playing, fps, loop, width, height, opacity, onFrameChange, onLoadProgress, onPlaybackStateChange, onEnded, onError, ...anchorProps }: SequenceHotspotProps): react.JSX.Element;
803
1229
 
804
- type VideoPlaybackState = "playing" | "paused" | "ended" | "blocked";
805
- type VideoHotspotErrorEvent = {
806
- id: string;
807
- source: "poster" | "video";
808
- error: unknown;
1230
+ type TextHotspotAlign = "left" | "center" | "right";
1231
+ type TextHotspotVerticalAlign = "top" | "middle" | "bottom";
1232
+ type TextHotspotWhiteSpace = "normal" | "nowrap";
1233
+ type TextHotspotFontStyle = "normal" | "italic";
1234
+ /** Serializable typography and panel paint for a text hotspot. */
1235
+ type TextHotspotStyle = {
1236
+ fontFamily?: string;
1237
+ /** Canvas pixels. Defaults to 96. */
1238
+ fontSize?: number;
1239
+ /** CSS font-weight. Defaults to 600. */
1240
+ fontWeight?: number | string;
1241
+ /** CSS font-style. Defaults to `"normal"`. */
1242
+ fontStyle?: TextHotspotFontStyle;
1243
+ color?: string;
1244
+ /** CSS color. An empty string skips the panel fill. */
1245
+ background?: string;
1246
+ backgroundOpacity?: number;
1247
+ /** Fraction of the texture's shorter side. */
1248
+ padding?: number;
1249
+ align?: TextHotspotAlign;
1250
+ verticalAlign?: TextHotspotVerticalAlign;
1251
+ lineHeight?: number;
1252
+ whiteSpace?: TextHotspotWhiteSpace;
1253
+ /** Fraction of the texture's shorter side, from 0 to 0.5. */
1254
+ borderRadius?: number;
1255
+ stroke?: string;
1256
+ strokeWidth?: number;
809
1257
  };
810
- type VideoHotspotProps = HotspotCommonProps & {
1258
+ type TextHotspotProps = HotspotCommonProps & TextHotspotStyle & {
1259
+ text: string;
1260
+ onLoad?: (texture: Texture) => void;
1261
+ onError?: (error: unknown) => void;
1262
+ };
1263
+ declare function TextHotspot({ text, width, height, opacity, fontFamily, fontSize, fontWeight, fontStyle, color, background, backgroundOpacity, padding, align, verticalAlign, lineHeight, whiteSpace, borderRadius, stroke, strokeWidth, onLoad, onError, ...anchorProps }: TextHotspotProps): react.JSX.Element;
1264
+
1265
+ type IframePointerPolicy = "hotspot" | "content";
1266
+ type IframeHotspotProps = HotspotCommonProps & {
811
1267
  src: string;
812
- playing: boolean;
813
- poster?: string;
814
- loop?: boolean;
815
- muted?: boolean;
816
- volume?: number;
817
- playsInline?: boolean;
818
- preload?: "none" | "metadata" | "auto";
819
- crossOrigin?: "" | "anonymous" | "use-credentials";
820
- onPlaybackStateChange?: (state: VideoPlaybackState) => void;
821
- onPlaybackError?: (error: unknown) => void;
822
- onEnded?: () => void;
823
- onError?: (event: VideoHotspotErrorEvent) => void;
1268
+ /** Accessible iframe title. Falls back to ariaLabel. */
1269
+ title?: string;
1270
+ sandbox?: string;
1271
+ allow?: string;
1272
+ referrerPolicy?: IframeHTMLAttributes<HTMLIFrameElement>["referrerPolicy"];
1273
+ loading?: "eager" | "lazy";
1274
+ /**
1275
+ * `hotspot` lets panorama pointer events hit the WebGL plane.
1276
+ * `content` makes the embedded page interactive.
1277
+ */
1278
+ pointerPolicy?: IframePointerPolicy;
1279
+ background?: string;
1280
+ onLoad?: () => void;
1281
+ onError?: (error: unknown) => void;
824
1282
  };
825
- 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;
1283
+ declare function IframeHotspot({ src, title, sandbox, allow, referrerPolicy, loading, pointerPolicy, background, opacity, width, height, onLoad, onError, interactive, pointerEvents, ...anchorProps }: IframeHotspotProps): react.JSX.Element;
826
1284
 
827
1285
  declare function Tile({ baseUrl, multires, previewUrl, previewFaceOrder, urlTemplate, resolveTileUrl, maxTextureMemoryMb, maxConcurrentLoads, retryCount, loadMode, visible, onReady, onPreviewError, onLoadProgress, onTileError, onLevelChange, }: TileProps): react.JSX.Element;
828
1286
 
@@ -832,6 +1290,9 @@ declare function normalizePanoPosition(position: HotspotPosition): HotspotPositi
832
1290
  declare function panoPositionToVector3(position: HotspotPosition, radius?: number): Vector3;
833
1291
  declare function vector3ToPanoPosition(vector: Pick<Vector3, "x" | "y" | "z">): HotspotPosition;
834
1292
 
1293
+ declare const DEFAULT_HOTSPOT_TOOLTIP_OFFSET = 12;
1294
+ declare const DEFAULT_HOTSPOT_TOOLTIP_APPEARANCE: Required<HotspotTooltipAppearance>;
1295
+
835
1296
  /** Shared serializable fields for every saved hotspot definition. */
836
1297
  type HotspotDefinitionBase = {
837
1298
  id: string;
@@ -839,7 +1300,16 @@ type HotspotDefinitionBase = {
839
1300
  label?: string;
840
1301
  visible?: boolean;
841
1302
  interactive?: boolean;
1303
+ /** Pointer hit-testing. `"none"` ignores mouse, touch, and pen. */
1304
+ pointerEvents?: HotspotPointerEvents;
1305
+ /** Canvas cursor while this hotspot is hovered. */
1306
+ cursor?: CSSProperties["cursor"];
842
1307
  renderOrder?: number;
1308
+ tooltip?: string | HotspotTooltipContent;
1309
+ tooltipTrigger?: HotspotTooltipTrigger;
1310
+ tooltipPlacement?: HotspotTooltipPlacement;
1311
+ tooltipOffset?: number;
1312
+ tooltipAppearance?: HotspotTooltipAppearance;
843
1313
  };
844
1314
  /** Shared serializable fields for a hotspot anchored at one yaw/pitch point. */
845
1315
  type PointHotspotDefinitionBase = HotspotDefinitionBase & {
@@ -883,6 +1353,21 @@ type VideoHotspotDefinition = PointHotspotDefinitionBase & {
883
1353
  preload?: "none" | "metadata" | "auto";
884
1354
  crossOrigin?: "" | "anonymous" | "use-credentials";
885
1355
  };
1356
+ type TextHotspotDefinition = PointHotspotDefinitionBase & TextHotspotStyle & {
1357
+ type: "text";
1358
+ text: string;
1359
+ };
1360
+ type IframeHotspotDefinition = PointHotspotDefinitionBase & {
1361
+ type: "iframe";
1362
+ src: string;
1363
+ title?: string;
1364
+ sandbox?: string;
1365
+ allow?: string;
1366
+ referrerPolicy?: string;
1367
+ loading?: "eager" | "lazy";
1368
+ pointerPolicy?: IframePointerPolicy;
1369
+ background?: string;
1370
+ };
886
1371
  type PolygonHotspotDefinition = HotspotDefinitionBase & {
887
1372
  type: "polygon";
888
1373
  vertices: HotspotPosition[];
@@ -891,17 +1376,21 @@ type PolygonHotspotDefinition = HotspotDefinitionBase & {
891
1376
  stroke?: string;
892
1377
  strokeWidth?: number;
893
1378
  strokeOpacity?: number;
1379
+ strokeDashSize?: number;
1380
+ strokeGapSize?: number;
894
1381
  };
895
- /** An open path. This extends the original five hotspot categories. */
1382
+ /** An open path. This extends the original point and polygon hotspot categories. */
896
1383
  type PolylineHotspotDefinition = HotspotDefinitionBase & {
897
1384
  type: "polyline";
898
1385
  vertices: HotspotPosition[];
899
1386
  stroke?: string;
900
1387
  strokeWidth?: number;
901
1388
  strokeOpacity?: number;
1389
+ strokeDashSize?: number;
1390
+ strokeGapSize?: number;
902
1391
  };
903
- type PointHotspotDefinition = ImageHotspotDefinition | GraphicHotspotDefinition | SequenceHotspotDefinition | VideoHotspotDefinition;
1392
+ type PointHotspotDefinition = ImageHotspotDefinition | GraphicHotspotDefinition | SequenceHotspotDefinition | VideoHotspotDefinition | TextHotspotDefinition | IframeHotspotDefinition;
904
1393
  /** A serializable, discriminated hotspot collection item. */
905
1394
  type HotspotDefinition = PointHotspotDefinition | PolygonHotspotDefinition | PolylineHotspotDefinition;
906
1395
 
907
- export { type ArrowGraphic, AutoRotate, type AutoRotateProps, type CircleGraphic, type CubeFaceCode, 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, 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 PanoEventBus, type PanoEventListener, type PanoEventMap, type PanoEventType, PanoEvents, type PanoEventsProps, type PanoResizeEvent, PanoView, type PanoViewHandle, type PanoViewProps, type PanoViewState, type PanoWheelEvent, type PanoramaControlsOptions, type PanoramaPointerEvent, type PanoramaScene, PanoramaScenes, type PanoramaScenesProps, type PanoramaTransition, type PanoramaTransitionEndEvent, type PanoramaTransitionErrorEvent, type PanoramaTransitionPreset, 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 SequenceFrameDirection, type SequenceFrameEvent, SequenceHotspot, type SequenceHotspotDefinition, type SequenceHotspotErrorEvent, type SequenceHotspotProps, type SequenceLoadProgress, type SequencePlaybackState, type SetPanoViewOptions, Sphere, type SpherePanoramaScene, type SphereProps, type StarGraphic, type SvgGraphic, type SvgPathGraphic, Tile, type TileAddress, type TileLoadError, type TileLoadProgress, type TileMultiresConfig, type TilePanoramaScene, type TileProps, 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 };
1396
+ 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 };