@ericchen1990/pano-view 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,519 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, ComponentPropsWithoutRef } from 'react';
3
+ import { Texture, ColorRepresentation, Vector3 } from 'three';
4
+
5
+ declare const MAX_HOTSPOT_PITCH = 89.9;
6
+ type HotspotPosition = {
7
+ /** Horizontal panorama angle in degrees. Positive values look right. */
8
+ yaw: number;
9
+ /** Vertical panorama angle in degrees. Positive values look up. */
10
+ pitch: number;
11
+ };
12
+ /**
13
+ * A safe point-hotspot rendering mode.
14
+ *
15
+ * `surface` attaches the visual to the panorama shell. `billboard` floats it
16
+ * in front of the shell and keeps it facing the camera.
17
+ */
18
+ type HotspotMode = "surface" | "billboard";
19
+ /** Whether a hotspot grows with panorama zoom or preserves its screen size. */
20
+ type HotspotScaleMode = "fov" | "fixed";
21
+ type HotspotInputSource = "pointer" | "keyboard";
22
+ type HotspotInteractionEvent = {
23
+ id: string;
24
+ position: HotspotPosition;
25
+ source: HotspotInputSource;
26
+ nativeEvent: MouseEvent | PointerEvent | KeyboardEvent;
27
+ };
28
+ type HotspotDragEvent = HotspotInteractionEvent & {
29
+ source: "pointer";
30
+ startPosition: HotspotPosition;
31
+ };
32
+ type HotspotCommonProps = {
33
+ id: string;
34
+ position: HotspotPosition;
35
+ /** Angular width in degrees. Defaults to 12. */
36
+ width?: number;
37
+ /** Angular height in degrees. Defaults to 8. */
38
+ height?: number;
39
+ /** Defaults to "billboard". */
40
+ mode?: HotspotMode;
41
+ /**
42
+ * World-space distance for `mode="billboard"`. Defaults to 10 and is capped
43
+ * when needed so the full hotspot remains inside the panorama shell.
44
+ */
45
+ distance?: number;
46
+ /** FOV grows/shrinks with zoom; fixed preserves the reference screen size. */
47
+ scaleMode?: HotspotScaleMode;
48
+ /** Reference FOV in degrees used when scaleMode is "fixed". Defaults to 75. */
49
+ referenceFov?: number;
50
+ /** Clockwise rotation around the hotspot normal in degrees. */
51
+ rotation?: number;
52
+ opacity?: number;
53
+ renderOrder?: number;
54
+ visible?: boolean;
55
+ /** Whether the hotspot accepts pointer and keyboard interaction. Defaults to true. */
56
+ interactive?: boolean;
57
+ draggable?: boolean;
58
+ /** Required for keyboard-accessible clickable hotspots. */
59
+ ariaLabel?: string;
60
+ onClick?: (event: HotspotInteractionEvent) => void;
61
+ onHoverChange?: (hovered: boolean, event: HotspotInteractionEvent) => void;
62
+ onDragStart?: (event: HotspotDragEvent) => void;
63
+ onPositionChange?: (event: HotspotDragEvent) => void;
64
+ onDragEnd?: (event: HotspotDragEvent) => void;
65
+ };
66
+ type PanoramaPointerEvent = {
67
+ position: HotspotPosition;
68
+ nativeEvent: MouseEvent | PointerEvent;
69
+ pointerId?: number;
70
+ button: number;
71
+ buttons: number;
72
+ clientX: number;
73
+ clientY: number;
74
+ };
75
+
76
+ type PanoViewState = {
77
+ /** Horizontal look angle in degrees. Positive values look right. */
78
+ yaw: number;
79
+ /** Vertical look angle in degrees. Positive values look up. */
80
+ pitch: number;
81
+ /** Vertical perspective field of view in degrees. */
82
+ fov: number;
83
+ };
84
+ type SetPanoViewOptions = {
85
+ /** Apply the new view immediately instead of preserving current inertia. */
86
+ immediate?: boolean;
87
+ };
88
+ type PanoViewHandle = {
89
+ getView: () => PanoViewState;
90
+ setView: (view: Partial<PanoViewState>, options?: SetPanoViewOptions) => void;
91
+ reset: () => void;
92
+ /** @deprecated Control an AutoRotate component's enabled prop instead. */
93
+ startAutoRotate: () => void;
94
+ /** @deprecated Control an AutoRotate component's enabled prop instead. */
95
+ stopAutoRotate: () => void;
96
+ toggleFullscreen: () => Promise<void>;
97
+ };
98
+ type PanoramaControlsOptions = {
99
+ /** Enables drag and zoom inertia. Defaults to true. */
100
+ inertia?: boolean;
101
+ /** @deprecated Render <AutoRotate enabled /> inside PanoView instead. */
102
+ autoRotate?: boolean;
103
+ /** @deprecated Use AutoRotate's speed prop instead. */
104
+ autoRotateSpeed?: number;
105
+ /** Pointer drag multiplier. Defaults to 0.35. */
106
+ rotateSpeed?: number;
107
+ /** Wheel zoom multiplier. Defaults to 0.08. */
108
+ zoomSpeed?: number;
109
+ /**
110
+ * Rotation target-following speed in seconds^-1. Defaults to 14; use 0 for
111
+ * immediate response. Must be a non-negative finite number.
112
+ */
113
+ rotateDamping?: number;
114
+ /**
115
+ * FOV target-following speed in seconds^-1. Defaults to 16; use 0 for
116
+ * immediate response. Must be a non-negative finite number.
117
+ */
118
+ zoomDamping?: number;
119
+ /** Enables focusable keyboard controls. Defaults to true. */
120
+ keyboard?: boolean;
121
+ };
122
+
123
+ type PanoViewProps = Omit<ComponentPropsWithoutRef<"div">, "children" | "onChange"> & {
124
+ children?: ReactNode;
125
+ initialView?: Partial<PanoViewState>;
126
+ minFov?: number;
127
+ maxFov?: number;
128
+ controls?: boolean | PanoramaControlsOptions;
129
+ onViewChange?: (view: PanoViewState) => void;
130
+ onPanoramaClick?: (event: PanoramaPointerEvent) => void;
131
+ onPanoramaDoubleClick?: (event: PanoramaPointerEvent) => void;
132
+ onPanoramaPointerMove?: (event: PanoramaPointerEvent) => void;
133
+ /** Canvas pixel ratio. Defaults to a capped range of 1–2. */
134
+ dpr?: number | [number, number];
135
+ };
136
+ declare const PanoView: react.ForwardRefExoticComponent<Omit<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "children" | "onChange"> & {
137
+ children?: ReactNode;
138
+ initialView?: Partial<PanoViewState>;
139
+ minFov?: number;
140
+ maxFov?: number;
141
+ controls?: boolean | PanoramaControlsOptions;
142
+ onViewChange?: (view: PanoViewState) => void;
143
+ onPanoramaClick?: (event: PanoramaPointerEvent) => void;
144
+ onPanoramaDoubleClick?: (event: PanoramaPointerEvent) => void;
145
+ onPanoramaPointerMove?: (event: PanoramaPointerEvent) => void;
146
+ /** Canvas pixel ratio. Defaults to a capped range of 1–2. */
147
+ dpr?: number | [number, number];
148
+ } & react.RefAttributes<PanoViewHandle>>;
149
+
150
+ /** Options for automatic horizontal panorama rotation. */
151
+ type AutoRotateProps = {
152
+ /** Whether automatic rotation is active. Defaults to true. */
153
+ enabled?: boolean;
154
+ /** Rotation speed in degrees per second. Negative values rotate left. */
155
+ speed?: number;
156
+ /**
157
+ * Rate at which rotation reaches its target speed, in degrees per second
158
+ * squared. Use 0 to disable the speed ramp. Defaults to 18.
159
+ */
160
+ acceleration?: number;
161
+ /** Milliseconds to wait after enabling before rotation begins. */
162
+ startDelay?: number;
163
+ };
164
+ /**
165
+ * Adds automatic rotation to the nearest PanoView. Render one instance as a
166
+ * child of PanoView, alongside its panorama source.
167
+ */
168
+ declare function AutoRotate({ enabled, speed, acceleration, startDelay, }: AutoRotateProps): null;
169
+
170
+ type SphereProps = {
171
+ src: string;
172
+ /** Horizontal image offset in degrees. */
173
+ yawOffset?: number;
174
+ onLoad?: (texture: Texture) => void;
175
+ onError?: (error: unknown) => void;
176
+ /** Keeps the source mounted for preloading without drawing it. */
177
+ visible?: boolean;
178
+ };
179
+ declare function Sphere({ src, yawOffset, onLoad, onError, visible, }: SphereProps): react.JSX.Element | null;
180
+
181
+ type CubeFaceCode = "f" | "r" | "b" | "l" | "u" | "d";
182
+ type TileAddress = {
183
+ face: CubeFaceCode;
184
+ level: number;
185
+ row: number;
186
+ col: number;
187
+ faceSize: number;
188
+ tileSize: number;
189
+ width: number;
190
+ height: number;
191
+ };
192
+ type TileMultiresConfig = {
193
+ tileSize: number;
194
+ /** Ascending face sizes. The first value maps to l1. */
195
+ levels: number[];
196
+ };
197
+ type TileLoadProgress = {
198
+ requested: number;
199
+ loaded: number;
200
+ failed: number;
201
+ active: number;
202
+ queued: number;
203
+ };
204
+ type TileLoadError = {
205
+ address: TileAddress;
206
+ url: string;
207
+ error: unknown;
208
+ };
209
+ type TileProps = {
210
+ baseUrl: string;
211
+ multires: string | TileMultiresConfig;
212
+ /** Defaults to `${baseUrl}/previews/cube-vertical.webp`. */
213
+ previewUrl?: string | null;
214
+ /**
215
+ * Relative to `baseUrl`; supports krpano cube-tile `%s` and `%l` placeholders,
216
+ * horizontal `%h`/`%x`/`%u`/`%c`, vertical `%v`/`%y`/`%w`/`%r`, and index padding
217
+ * such as `%0h` or `%00v`.
218
+ */
219
+ urlTemplate?: string;
220
+ /** Returns a path relative to `baseUrl`; takes precedence over `urlTemplate`. */
221
+ resolveTileUrl?: (address: TileAddress) => string;
222
+ maxTextureMemoryMb?: number;
223
+ maxConcurrentLoads?: number;
224
+ retryCount?: number;
225
+ /**
226
+ * `preview` loads only the preview atlas; `base` also preloads the visible
227
+ * lowest-resolution tiles before full-resolution loading begins.
228
+ */
229
+ loadMode?: "full" | "preview" | "base";
230
+ /** Keeps the source mounted for preloading without drawing it. */
231
+ visible?: boolean;
232
+ /** Called when the preview atlas is ready for display. */
233
+ onReady?: () => void;
234
+ /** Called when the preview atlas cannot be loaded. */
235
+ onPreviewError?: (error: unknown) => void;
236
+ onLoadProgress?: (progress: TileLoadProgress) => void;
237
+ onTileError?: (event: TileLoadError) => void;
238
+ onLevelChange?: (level: number) => void;
239
+ };
240
+
241
+ type PanoramaTransitionPreset = "none" | "crossfade" | "zoom" | "blackout" | "whiteFlash" | "slideRightToLeft" | "slideTopToBottom" | "slideDiagonal" | "circleOpen" | "verticalOpen" | "horizontalOpen" | "ellipticZoomOpen";
242
+ type PanoramaTransition = PanoramaTransitionPreset | {
243
+ preset: PanoramaTransitionPreset;
244
+ /** Overrides the KRpano-compatible default duration in seconds. */
245
+ duration?: number;
246
+ };
247
+ type SpherePanoramaScene = {
248
+ id: string;
249
+ type: "sphere";
250
+ src: string;
251
+ yawOffset?: number;
252
+ };
253
+ type TilePanoramaScene = Omit<TileProps, "loadMode" | "visible" | "onReady" | "onPreviewError" | "onLoadProgress" | "onTileError" | "onLevelChange"> & {
254
+ id: string;
255
+ type: "tile";
256
+ };
257
+ type PanoramaScene = SpherePanoramaScene | TilePanoramaScene;
258
+ type PanoramaTransitionEndEvent = {
259
+ previousSceneId: string;
260
+ sceneId: string;
261
+ preset: PanoramaTransitionPreset;
262
+ };
263
+ type PanoramaTransitionErrorEvent = {
264
+ sceneId: string;
265
+ error: unknown;
266
+ };
267
+ type PanoramaScenesProps = {
268
+ scenes: readonly PanoramaScene[];
269
+ activeSceneId: string;
270
+ transition?: PanoramaTransition;
271
+ /** Rendered only after a scene has finished transitioning in. */
272
+ renderHotspots?: (scene: PanoramaScene) => ReactNode;
273
+ onTransitionEnd?: (event: PanoramaTransitionEndEvent) => void;
274
+ onTransitionError?: (event: PanoramaTransitionErrorEvent) => void;
275
+ /** Viewer-wide budget shared by every tile scene. Defaults to 128 MiB. */
276
+ maxTextureMemoryMb?: number;
277
+ /** Viewer-wide tile request limit. Defaults to 4. */
278
+ maxConcurrentTileLoads?: number;
279
+ /** Maximum physical-pixel area of the outgoing GPU snapshot. */
280
+ snapshotMaxPixels?: number;
281
+ };
282
+ declare function PanoramaScenes({ maxTextureMemoryMb, maxConcurrentTileLoads, ...props }: PanoramaScenesProps): react.JSX.Element;
283
+
284
+ type ImageHotspotProps = HotspotCommonProps & {
285
+ src: string;
286
+ onLoad?: (texture: Texture) => void;
287
+ onError?: (error: unknown) => void;
288
+ };
289
+ declare function ImageHotspot({ src, width, height, opacity, onLoad, onError, ...anchorProps }: ImageHotspotProps): react.JSX.Element;
290
+
291
+ type PolygonValidationCode = "too_few_vertices" | "self_intersection" | "contains_pole" | "outside_hemisphere";
292
+ type PolygonValidationIssue = {
293
+ code: PolygonValidationCode;
294
+ message: string;
295
+ };
296
+ type PolygonVerticesChangeEvent = {
297
+ id: string;
298
+ vertices: HotspotPosition[];
299
+ startVertices: HotspotPosition[];
300
+ position: HotspotPosition;
301
+ startPosition: HotspotPosition;
302
+ };
303
+ type PolygonHotspotProps = Omit<HotspotCommonProps, "position" | "width" | "height" | "mode" | "distance" | "scaleMode" | "onDragStart" | "onPositionChange" | "onDragEnd"> & {
304
+ vertices: HotspotPosition[];
305
+ fill?: ColorRepresentation;
306
+ fillOpacity?: number;
307
+ stroke?: ColorRepresentation;
308
+ /** Screen-space border width in CSS pixels. Defaults to 2. */
309
+ strokeWidth?: number;
310
+ /** Opacity of the polygon boundary, from 0 to 1. Defaults to 1. */
311
+ strokeOpacity?: number;
312
+ onVerticesChange?: (event: PolygonVerticesChangeEvent) => void;
313
+ onDragStart?: (event: PolygonVerticesChangeEvent) => void;
314
+ onDragEnd?: (event: PolygonVerticesChangeEvent) => void;
315
+ onInvalid?: (issues: PolygonValidationIssue[]) => void;
316
+ };
317
+ type UnwrappedVertex = HotspotPosition & {
318
+ unwrappedYaw: number;
319
+ };
320
+ declare function unwrapPolygonVertices(vertices: HotspotPosition[]): UnwrappedVertex[];
321
+ declare function validatePolygonVertices(vertices: HotspotPosition[]): PolygonValidationIssue[];
322
+ declare function PolygonHotspot({ id, vertices, fill, fillOpacity, stroke, strokeWidth, strokeOpacity, interactive, renderOrder, draggable, onVerticesChange, onDragStart, onDragEnd, onInvalid, ...anchorProps }: PolygonHotspotProps): react.JSX.Element | null;
323
+
324
+ type PolylineValidationIssue = {
325
+ code: "too_few_vertices";
326
+ message: string;
327
+ };
328
+ type PolylineVerticesChangeEvent = {
329
+ id: string;
330
+ vertices: HotspotPosition[];
331
+ startVertices: HotspotPosition[];
332
+ position: HotspotPosition;
333
+ startPosition: HotspotPosition;
334
+ };
335
+ type PolylineHotspotProps = Omit<HotspotCommonProps, "position" | "width" | "height" | "mode" | "distance" | "scaleMode" | "onDragStart" | "onPositionChange" | "onDragEnd"> & {
336
+ vertices: HotspotPosition[];
337
+ stroke?: ColorRepresentation;
338
+ /** Screen-space line width in CSS pixels. Defaults to 2. */
339
+ strokeWidth?: number;
340
+ strokeOpacity?: number;
341
+ onVerticesChange?: (event: PolylineVerticesChangeEvent) => void;
342
+ onDragStart?: (event: PolylineVerticesChangeEvent) => void;
343
+ onDragEnd?: (event: PolylineVerticesChangeEvent) => void;
344
+ onInvalid?: (issues: PolylineValidationIssue[]) => void;
345
+ };
346
+ declare function validatePolylineVertices(vertices: HotspotPosition[]): PolylineValidationIssue[];
347
+ declare function PolylineHotspot({ id, vertices, stroke, strokeWidth, strokeOpacity, renderOrder, draggable, onVerticesChange, onDragStart, onDragEnd, onInvalid, ...anchorProps }: PolylineHotspotProps): react.JSX.Element | null;
348
+
349
+ type GraphicPaint = {
350
+ fill?: string;
351
+ stroke?: string;
352
+ strokeWidth?: number;
353
+ };
354
+ type CircleGraphic = GraphicPaint & {
355
+ kind: "circle";
356
+ };
357
+ type RectangleGraphic = GraphicPaint & {
358
+ kind: "rectangle";
359
+ cornerRadius?: number;
360
+ };
361
+ type RingGraphic = GraphicPaint & {
362
+ kind: "ring";
363
+ innerRadius?: number;
364
+ };
365
+ type SvgGraphic = {
366
+ kind: "svg";
367
+ src: string;
368
+ };
369
+ type SvgPathGraphic = GraphicPaint & {
370
+ kind: "path";
371
+ path: string;
372
+ viewBox: [x: number, y: number, width: number, height: number];
373
+ };
374
+ type GraphicDefinition = CircleGraphic | RectangleGraphic | RingGraphic | SvgGraphic | SvgPathGraphic;
375
+ type GraphicHotspotProps = HotspotCommonProps & {
376
+ graphic: GraphicDefinition;
377
+ onLoad?: (texture: Texture) => void;
378
+ onError?: (error: unknown) => void;
379
+ };
380
+ declare function GraphicHotspot(props: GraphicHotspotProps): react.JSX.Element;
381
+
382
+ type SequenceFrameDirection = "horizontal" | "vertical";
383
+ type SequenceLoadProgress = {
384
+ id: string;
385
+ total: number;
386
+ loaded: number;
387
+ failed: number;
388
+ };
389
+ type SequenceFrameEvent = {
390
+ id: string;
391
+ index: number;
392
+ src: string;
393
+ };
394
+ type SequencePlaybackState = "playing" | "paused" | "ended";
395
+ type SequenceHotspotErrorEvent = {
396
+ id: string;
397
+ src: string;
398
+ error: unknown;
399
+ };
400
+ type SequenceHotspotProps = HotspotCommonProps & {
401
+ /** A sprite sheet containing each frame in equally sized cells. */
402
+ src: string;
403
+ /** Number of cells in the sprite sheet, from left-to-right or top-to-bottom. */
404
+ frameCount: number;
405
+ frameDirection?: SequenceFrameDirection;
406
+ playing: boolean;
407
+ fps?: number;
408
+ loop?: boolean;
409
+ onFrameChange?: (event: SequenceFrameEvent) => void;
410
+ onLoadProgress?: (progress: SequenceLoadProgress) => void;
411
+ onPlaybackStateChange?: (state: SequencePlaybackState) => void;
412
+ onEnded?: () => void;
413
+ onError?: (event: SequenceHotspotErrorEvent) => void;
414
+ };
415
+ declare function SequenceHotspot({ id, src, frameCount: requestedFrameCount, frameDirection, playing, fps, loop, width, height, opacity, onFrameChange, onLoadProgress, onPlaybackStateChange, onEnded, onError, ...anchorProps }: SequenceHotspotProps): react.JSX.Element;
416
+
417
+ type VideoPlaybackState = "playing" | "paused" | "ended" | "blocked";
418
+ type VideoHotspotErrorEvent = {
419
+ id: string;
420
+ source: "poster" | "video";
421
+ error: unknown;
422
+ };
423
+ type VideoHotspotProps = HotspotCommonProps & {
424
+ src: string;
425
+ playing: boolean;
426
+ poster?: string;
427
+ loop?: boolean;
428
+ muted?: boolean;
429
+ volume?: number;
430
+ playsInline?: boolean;
431
+ preload?: "none" | "metadata" | "auto";
432
+ crossOrigin?: "" | "anonymous" | "use-credentials";
433
+ onPlaybackStateChange?: (state: VideoPlaybackState) => void;
434
+ onPlaybackError?: (error: unknown) => void;
435
+ onEnded?: () => void;
436
+ onError?: (event: VideoHotspotErrorEvent) => void;
437
+ };
438
+ 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;
439
+
440
+ declare function Tile({ baseUrl, multires, previewUrl, urlTemplate, resolveTileUrl, maxTextureMemoryMb, maxConcurrentLoads, retryCount, loadMode, visible, onReady, onPreviewError, onLoadProgress, onTileError, onLevelChange, }: TileProps): react.JSX.Element;
441
+
442
+ declare function normalizePanoYaw(yaw: number): number;
443
+ declare function clampPanoPitch(pitch: number): number;
444
+ declare function normalizePanoPosition(position: HotspotPosition): HotspotPosition;
445
+ declare function panoPositionToVector3(position: HotspotPosition, radius?: number): Vector3;
446
+ declare function vector3ToPanoPosition(vector: Pick<Vector3, "x" | "y" | "z">): HotspotPosition;
447
+
448
+ /** Shared serializable fields for every saved hotspot definition. */
449
+ type HotspotDefinitionBase = {
450
+ id: string;
451
+ /** Human-readable label; use it as the source for the rendered ariaLabel. */
452
+ label?: string;
453
+ visible?: boolean;
454
+ interactive?: boolean;
455
+ renderOrder?: number;
456
+ };
457
+ /** Shared serializable fields for a hotspot anchored at one yaw/pitch point. */
458
+ type PointHotspotDefinitionBase = HotspotDefinitionBase & {
459
+ position: HotspotPosition;
460
+ width?: number;
461
+ height?: number;
462
+ mode?: HotspotMode;
463
+ distance?: number;
464
+ scaleMode?: HotspotScaleMode;
465
+ referenceFov?: number;
466
+ rotation?: number;
467
+ opacity?: number;
468
+ };
469
+ type ImageHotspotDefinition = PointHotspotDefinitionBase & {
470
+ type: "image";
471
+ src: string;
472
+ };
473
+ type GraphicHotspotDefinition = PointHotspotDefinitionBase & {
474
+ type: "graphic";
475
+ graphic: GraphicDefinition;
476
+ };
477
+ type SequenceHotspotDefinition = PointHotspotDefinitionBase & {
478
+ type: "sequence";
479
+ src: string;
480
+ frameCount: number;
481
+ frameDirection?: "horizontal" | "vertical";
482
+ playing?: boolean;
483
+ fps?: number;
484
+ loop?: boolean;
485
+ };
486
+ type VideoHotspotDefinition = PointHotspotDefinitionBase & {
487
+ type: "video";
488
+ src: string;
489
+ poster?: string;
490
+ playing?: boolean;
491
+ loop?: boolean;
492
+ muted?: boolean;
493
+ volume?: number;
494
+ playsInline?: boolean;
495
+ preload?: "none" | "metadata" | "auto";
496
+ crossOrigin?: "" | "anonymous" | "use-credentials";
497
+ };
498
+ type PolygonHotspotDefinition = HotspotDefinitionBase & {
499
+ type: "polygon";
500
+ vertices: HotspotPosition[];
501
+ fill?: string;
502
+ fillOpacity?: number;
503
+ stroke?: string;
504
+ strokeWidth?: number;
505
+ strokeOpacity?: number;
506
+ };
507
+ /** An open path. This extends the original five hotspot categories. */
508
+ type PolylineHotspotDefinition = HotspotDefinitionBase & {
509
+ type: "polyline";
510
+ vertices: HotspotPosition[];
511
+ stroke?: string;
512
+ strokeWidth?: number;
513
+ strokeOpacity?: number;
514
+ };
515
+ type PointHotspotDefinition = ImageHotspotDefinition | GraphicHotspotDefinition | SequenceHotspotDefinition | VideoHotspotDefinition;
516
+ /** A serializable, discriminated hotspot collection item. */
517
+ type HotspotDefinition = PointHotspotDefinition | PolygonHotspotDefinition | PolylineHotspotDefinition;
518
+
519
+ export { AutoRotate, type AutoRotateProps, type CircleGraphic, type CubeFaceCode, 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, MAX_HOTSPOT_PITCH, PanoView, type PanoViewHandle, type PanoViewProps, type PanoViewState, 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 SvgGraphic, type SvgPathGraphic, Tile, type TileAddress, type TileLoadError, type TileLoadProgress, type TileMultiresConfig, type TilePanoramaScene, type TileProps, VideoHotspot, type VideoHotspotDefinition, type VideoHotspotErrorEvent, type VideoHotspotProps, type VideoPlaybackState, clampPanoPitch, normalizePanoPosition, normalizePanoYaw, panoPositionToVector3, unwrapPolygonVertices, validatePolygonVertices, validatePolylineVertices, vector3ToPanoPosition };