@ericchen1990/pano-view 3.5.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -0
- package/README.zh-CN.md +93 -0
- package/dist/data.cjs +202 -25
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.mts +90 -8
- package/dist/data.d.ts +90 -8
- package/dist/data.mjs +202 -25
- package/dist/data.mjs.map +1 -1
- package/dist/index.cjs +1638 -1281
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +148 -11
- package/dist/index.d.ts +148 -11
- package/dist/index.mjs +1244 -883
- package/dist/index.mjs.map +1 -1
- package/dist/ui/styles.css +70 -0
- package/dist/ui.cjs +195 -0
- package/dist/ui.cjs.map +1 -0
- package/dist/ui.d.mts +63 -0
- package/dist/ui.d.ts +63 -0
- package/dist/ui.mjs +152 -0
- package/dist/ui.mjs.map +1 -0
- package/docs/dialogs.md +606 -0
- package/docs/dialogs.zh-CN.md +606 -0
- package/package.json +11 -3
package/dist/index.mjs
CHANGED
|
@@ -2238,18 +2238,83 @@ var require_howler = __commonJS({
|
|
|
2238
2238
|
}
|
|
2239
2239
|
});
|
|
2240
2240
|
|
|
2241
|
+
// src/view-limits.ts
|
|
2242
|
+
function parseViewLimits(value) {
|
|
2243
|
+
if (value === void 0) return void 0;
|
|
2244
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
2245
|
+
throw new Error("viewLimits: expected an object");
|
|
2246
|
+
const result = {};
|
|
2247
|
+
for (const axis of ["yaw", "pitch", "fov"]) {
|
|
2248
|
+
const input = value[axis];
|
|
2249
|
+
if (input === void 0) continue;
|
|
2250
|
+
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
2251
|
+
throw new Error(`viewLimits.${axis}: expected min and max`);
|
|
2252
|
+
const { min, max } = input;
|
|
2253
|
+
const lower = axis === "yaw" ? -180 : axis === "pitch" ? -90 : 1;
|
|
2254
|
+
const upper = axis === "yaw" ? 180 : axis === "pitch" ? 90 : 179;
|
|
2255
|
+
if (typeof min !== "number" || typeof max !== "number" || !Number.isFinite(min) || !Number.isFinite(max) || min < lower || min > upper || max < lower || max > upper)
|
|
2256
|
+
throw new Error(`viewLimits.${axis}: expected finite min and max from ${lower} to ${upper}`);
|
|
2257
|
+
if (axis !== "yaw" && min > max)
|
|
2258
|
+
throw new Error(`viewLimits.${axis}: min must not exceed max`);
|
|
2259
|
+
result[axis] = { min, max };
|
|
2260
|
+
}
|
|
2261
|
+
return result;
|
|
2262
|
+
}
|
|
2263
|
+
function resolveViewLimits(base, scene, minFov = 30, maxFov = 100) {
|
|
2264
|
+
const pitch = scene?.pitch ?? base?.pitch;
|
|
2265
|
+
const fov = scene?.fov ?? base?.fov;
|
|
2266
|
+
return {
|
|
2267
|
+
yaw: scene?.yaw ?? base?.yaw,
|
|
2268
|
+
pitch: pitch ?? { min: -90, max: 90 },
|
|
2269
|
+
fov: fov ?? { min: minFov, max: maxFov },
|
|
2270
|
+
hardPitch: pitch !== void 0,
|
|
2271
|
+
hardFov: fov !== void 0
|
|
2272
|
+
};
|
|
2273
|
+
}
|
|
2274
|
+
function clampViewAxis(value, range) {
|
|
2275
|
+
return Math.max(range.min, Math.min(range.max, value));
|
|
2276
|
+
}
|
|
2277
|
+
function normalizeViewYaw(yaw) {
|
|
2278
|
+
return ((yaw + 180) % 360 + 360) % 360 - 180;
|
|
2279
|
+
}
|
|
2280
|
+
function yawWidth(range) {
|
|
2281
|
+
if (!range || range.min === -180 && range.max === 180) return 360;
|
|
2282
|
+
return ((range.max - range.min) % 360 + 360) % 360;
|
|
2283
|
+
}
|
|
2284
|
+
function yawOffset(yaw, range) {
|
|
2285
|
+
const width = yawWidth(range);
|
|
2286
|
+
const offset = ((yaw - range.min) % 360 + 360) % 360;
|
|
2287
|
+
if (offset <= width) return offset;
|
|
2288
|
+
return offset - width < 360 - offset ? width : 0;
|
|
2289
|
+
}
|
|
2290
|
+
function constrainViewYaw(yaw, range) {
|
|
2291
|
+
if (yawWidth(range) === 360) return normalizeViewYaw(yaw);
|
|
2292
|
+
return normalizeViewYaw(range.min + yawOffset(yaw, range));
|
|
2293
|
+
}
|
|
2294
|
+
function applyLimitedYawDelta(yaw, delta, range) {
|
|
2295
|
+
const width = yawWidth(range);
|
|
2296
|
+
if (width === 360) return normalizeViewYaw(yaw + delta);
|
|
2297
|
+
const offset = clampViewAxis(yawOffset(yaw, range) + delta, { min: 0, max: width });
|
|
2298
|
+
return normalizeViewYaw(range.min + offset);
|
|
2299
|
+
}
|
|
2300
|
+
function limitedYawDelta(from, to, range, shortestPath = true) {
|
|
2301
|
+
if (yawWidth(range) === 360)
|
|
2302
|
+
return shortestPath ? normalizeViewYaw(to - from) : to - from;
|
|
2303
|
+
return yawOffset(to, range) - yawOffset(from, range);
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2241
2306
|
// src/pano-viewer.tsx
|
|
2242
2307
|
import { Canvas } from "@react-three/fiber";
|
|
2243
2308
|
import { createXRStore, XR } from "@react-three/xr";
|
|
2244
2309
|
import {
|
|
2245
2310
|
forwardRef as forwardRef2,
|
|
2246
2311
|
useCallback as useCallback6,
|
|
2247
|
-
useContext as
|
|
2312
|
+
useContext as useContext16,
|
|
2248
2313
|
useEffect as useEffect13,
|
|
2249
2314
|
useImperativeHandle as useImperativeHandle2,
|
|
2250
|
-
useMemo as
|
|
2315
|
+
useMemo as useMemo8,
|
|
2251
2316
|
useRef as useRef13,
|
|
2252
|
-
useState as
|
|
2317
|
+
useState as useState6,
|
|
2253
2318
|
useSyncExternalStore as useSyncExternalStore6
|
|
2254
2319
|
} from "react";
|
|
2255
2320
|
|
|
@@ -2337,6 +2402,7 @@ function sourceList(src) {
|
|
|
2337
2402
|
}
|
|
2338
2403
|
function createUnlockingHowl({
|
|
2339
2404
|
src,
|
|
2405
|
+
format,
|
|
2340
2406
|
loop,
|
|
2341
2407
|
crossOrigin,
|
|
2342
2408
|
isActive,
|
|
@@ -2358,6 +2424,7 @@ function createUnlockingHowl({
|
|
|
2358
2424
|
};
|
|
2359
2425
|
const instance = new import_howler.Howl({
|
|
2360
2426
|
src: [...src],
|
|
2427
|
+
format: format ? [...format] : void 0,
|
|
2361
2428
|
html5: false,
|
|
2362
2429
|
preload: true,
|
|
2363
2430
|
loop,
|
|
@@ -2467,6 +2534,7 @@ import {
|
|
|
2467
2534
|
forwardRef,
|
|
2468
2535
|
useEffect,
|
|
2469
2536
|
useImperativeHandle,
|
|
2537
|
+
useLayoutEffect,
|
|
2470
2538
|
useRef
|
|
2471
2539
|
} from "react";
|
|
2472
2540
|
import { Euler, MathUtils, PerspectiveCamera } from "three";
|
|
@@ -2480,6 +2548,7 @@ var DEFAULT_ZOOM_DAMPING = 16;
|
|
|
2480
2548
|
var DEFAULT_FRICTION_STOP = 0.01;
|
|
2481
2549
|
var VIEW_SETTLE_EPSILON = 1e-3;
|
|
2482
2550
|
var DEFAULT_NAVIGATION_DURATION = 700;
|
|
2551
|
+
var POINTER_VELOCITY_MAX_AGE_MS = 100;
|
|
2483
2552
|
var PanoramaViewContext = createContext3(null);
|
|
2484
2553
|
function clamp(value, min, max) {
|
|
2485
2554
|
return Math.max(min, Math.min(max, value));
|
|
@@ -2499,6 +2568,9 @@ function resolveDamping(value, fallback) {
|
|
|
2499
2568
|
function resolveFrictionStop(value) {
|
|
2500
2569
|
return Number.isFinite(value) && value >= 0 ? value : DEFAULT_FRICTION_STOP;
|
|
2501
2570
|
}
|
|
2571
|
+
function shouldKeepPointerInertia(sampledAt, releasedAt, cancelled = false) {
|
|
2572
|
+
return !cancelled && sampledAt !== null && releasedAt >= sampledAt && releasedAt - sampledAt <= POINTER_VELOCITY_MAX_AGE_MS;
|
|
2573
|
+
}
|
|
2502
2574
|
function resolveNavigationDuration(value) {
|
|
2503
2575
|
return Number.isFinite(value) && value >= 0 ? value : DEFAULT_NAVIGATION_DURATION;
|
|
2504
2576
|
}
|
|
@@ -2511,7 +2583,7 @@ function applyNavigationEasing(progress, easing) {
|
|
|
2511
2583
|
function viewsEqual(a, b) {
|
|
2512
2584
|
return a.yaw === b.yaw && a.pitch === b.pitch && a.fov === b.fov;
|
|
2513
2585
|
}
|
|
2514
|
-
var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView, minFov, maxFov, options, eventBus }, ref) {
|
|
2586
|
+
var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView, viewLimits, minFov, maxFov, options, eventBus }, ref) {
|
|
2515
2587
|
const { camera, gl } = useThree();
|
|
2516
2588
|
const xrSession = useXR((state) => state.session);
|
|
2517
2589
|
const xrSessionRef = useRef(xrSession);
|
|
@@ -2539,48 +2611,46 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2539
2611
|
const lastEmittedViewRef = useRef(null);
|
|
2540
2612
|
const eulerRef = useRef(new Euler(0, 0, 0, "YXZ"));
|
|
2541
2613
|
const xrEulerRef = useRef(new Euler(0, 0, 0, "YXZ"));
|
|
2542
|
-
const
|
|
2543
|
-
const
|
|
2614
|
+
const baseLimitsRef = useRef(viewLimits);
|
|
2615
|
+
const sceneLimitsRef = useRef(void 0);
|
|
2616
|
+
const legacyFovRef = useRef({ minFov, maxFov });
|
|
2617
|
+
const limitsRef = useRef(resolveViewLimits(viewLimits, void 0, minFov, maxFov));
|
|
2544
2618
|
const activeNavigationRef = useRef(null);
|
|
2545
2619
|
optionsRef.current = options;
|
|
2546
2620
|
eventBusRef.current = eventBus;
|
|
2547
2621
|
xrSessionRef.current = xrSession;
|
|
2548
|
-
|
|
2549
|
-
|
|
2622
|
+
baseLimitsRef.current = viewLimits;
|
|
2623
|
+
legacyFovRef.current = { minFov, maxFov };
|
|
2550
2624
|
const hasInertia = () => yawVelocityRef.current !== 0 || pitchVelocityRef.current !== 0 || zoomVelocityRef.current !== 0;
|
|
2551
2625
|
const isUserInteracting = () => mouseActiveRef.current || touchActiveRef.current || keyboardActiveRef.current || gyroActiveRef.current || interactionLockCountRef.current > 0 || xrSessionRef.current != null || activeNavigationRef.current != null || hasInertia();
|
|
2552
2626
|
const syncInteracting = () => {
|
|
2553
2627
|
interactingRef.current = mouseActiveRef.current || touchActiveRef.current;
|
|
2554
2628
|
};
|
|
2555
2629
|
const hardConstrainView = (view, current = targetViewRef.current) => {
|
|
2630
|
+
const limits = limitsRef.current;
|
|
2556
2631
|
return {
|
|
2557
|
-
yaw:
|
|
2558
|
-
pitch:
|
|
2559
|
-
fov:
|
|
2560
|
-
view.fov ?? current.fov,
|
|
2561
|
-
minFovRef.current,
|
|
2562
|
-
maxFovRef.current
|
|
2563
|
-
)
|
|
2632
|
+
yaw: constrainViewYaw(Number.isFinite(view.yaw) ? view.yaw : current.yaw, limits.yaw),
|
|
2633
|
+
pitch: clampViewAxis(Number.isFinite(view.pitch) ? view.pitch : current.pitch, limits.pitch),
|
|
2634
|
+
fov: clampViewAxis(Number.isFinite(view.fov) ? view.fov : current.fov, limits.fov)
|
|
2564
2635
|
};
|
|
2565
2636
|
};
|
|
2566
2637
|
const softConstrainView = (view, current = targetViewRef.current) => {
|
|
2567
|
-
const
|
|
2568
|
-
if (
|
|
2569
|
-
return
|
|
2570
|
-
|
|
2571
|
-
const
|
|
2572
|
-
const fovOvershoot = fovRange * BOUNCE_OVERSHOOT_FOV_RATIO;
|
|
2638
|
+
const constrained = hardConstrainView(view, current);
|
|
2639
|
+
if (optionsRef.current.bouncingLimits !== true || !interactingRef.current)
|
|
2640
|
+
return constrained;
|
|
2641
|
+
const limits = limitsRef.current;
|
|
2642
|
+
const fovOvershoot = Math.max(limits.fov.max - limits.fov.min, 1) * BOUNCE_OVERSHOOT_FOV_RATIO;
|
|
2573
2643
|
return {
|
|
2574
|
-
yaw:
|
|
2575
|
-
pitch: clamp(
|
|
2644
|
+
yaw: constrained.yaw,
|
|
2645
|
+
pitch: limits.hardPitch ? constrained.pitch : clamp(
|
|
2576
2646
|
view.pitch ?? current.pitch,
|
|
2577
2647
|
-MAX_PITCH - BOUNCE_OVERSHOOT_PITCH,
|
|
2578
2648
|
MAX_PITCH + BOUNCE_OVERSHOOT_PITCH
|
|
2579
2649
|
),
|
|
2580
|
-
fov: clamp(
|
|
2650
|
+
fov: limits.hardFov ? constrained.fov : clamp(
|
|
2581
2651
|
view.fov ?? current.fov,
|
|
2582
|
-
|
|
2583
|
-
|
|
2652
|
+
limits.fov.min - fovOvershoot,
|
|
2653
|
+
limits.fov.max + fovOvershoot
|
|
2584
2654
|
)
|
|
2585
2655
|
};
|
|
2586
2656
|
};
|
|
@@ -2634,6 +2704,27 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2634
2704
|
);
|
|
2635
2705
|
};
|
|
2636
2706
|
};
|
|
2707
|
+
const refreshLimits = () => {
|
|
2708
|
+
const next = resolveViewLimits(
|
|
2709
|
+
baseLimitsRef.current,
|
|
2710
|
+
sceneLimitsRef.current,
|
|
2711
|
+
legacyFovRef.current.minFov,
|
|
2712
|
+
legacyFovRef.current.maxFov
|
|
2713
|
+
);
|
|
2714
|
+
if (JSON.stringify(next) === JSON.stringify(limitsRef.current)) return;
|
|
2715
|
+
limitsRef.current = next;
|
|
2716
|
+
cancelNavigation();
|
|
2717
|
+
stopVelocity();
|
|
2718
|
+
viewRef.current = hardConstrainView(viewRef.current);
|
|
2719
|
+
targetViewRef.current = hardConstrainView(targetViewRef.current);
|
|
2720
|
+
if (gyroActiveRef.current) {
|
|
2721
|
+
gyroOffsetRef.current = {
|
|
2722
|
+
yaw: shortestYawDelta(gyroPoseRef.current.yaw, viewRef.current.yaw),
|
|
2723
|
+
pitch: viewRef.current.pitch - gyroPoseRef.current.pitch
|
|
2724
|
+
};
|
|
2725
|
+
}
|
|
2726
|
+
markDirty();
|
|
2727
|
+
};
|
|
2637
2728
|
const setView = (view, setOptions) => {
|
|
2638
2729
|
cancelNavigation();
|
|
2639
2730
|
const nextView = hardConstrainView(view);
|
|
@@ -2664,7 +2755,12 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2664
2755
|
const target = hardConstrainView(safeTargetInput, from);
|
|
2665
2756
|
const duration = resolveNavigationDuration(options2?.duration);
|
|
2666
2757
|
const rawYawDelta = targetInput.yaw !== void 0 && Number.isFinite(targetInput.yaw) ? safeTargetInput.yaw - from.yaw : 0;
|
|
2667
|
-
const yawDelta =
|
|
2758
|
+
const yawDelta = limitedYawDelta(
|
|
2759
|
+
from.yaw,
|
|
2760
|
+
options2?.shortestPath === false ? from.yaw + rawYawDelta : target.yaw,
|
|
2761
|
+
limitsRef.current.yaw,
|
|
2762
|
+
options2?.shortestPath !== false
|
|
2763
|
+
);
|
|
2668
2764
|
stopVelocity();
|
|
2669
2765
|
targetViewRef.current = target;
|
|
2670
2766
|
markDirty();
|
|
@@ -2719,7 +2815,7 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2719
2815
|
const appliesTouchMode = gyroControlsView && applyOptions?.source === "touch";
|
|
2720
2816
|
const acceptsYaw = !appliesTouchMode || gyroMode === "horizontaloffset" || gyroMode === "full";
|
|
2721
2817
|
const acceptsPitch = !appliesTouchMode || gyroMode === "full";
|
|
2722
|
-
const nextYaw = acceptsYaw && delta.yaw !== void 0 && Number.isFinite(delta.yaw) ? current.yaw
|
|
2818
|
+
const nextYaw = acceptsYaw && delta.yaw !== void 0 && Number.isFinite(delta.yaw) ? applyLimitedYawDelta(current.yaw, delta.yaw, limitsRef.current.yaw) : current.yaw;
|
|
2723
2819
|
const nextPitch = acceptsPitch && delta.pitch !== void 0 && Number.isFinite(delta.pitch) ? current.pitch + delta.pitch : current.pitch;
|
|
2724
2820
|
const nextFov = delta.fov !== void 0 && Number.isFinite(delta.fov) ? current.fov + delta.fov : current.fov;
|
|
2725
2821
|
targetViewRef.current = softConstrainView({
|
|
@@ -2729,10 +2825,10 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2729
2825
|
});
|
|
2730
2826
|
if (gyroControlsView) {
|
|
2731
2827
|
if (acceptsYaw && delta.yaw !== void 0 && Number.isFinite(delta.yaw)) {
|
|
2732
|
-
gyroOffsetRef.current.yaw
|
|
2828
|
+
gyroOffsetRef.current.yaw = shortestYawDelta(gyroPoseRef.current.yaw, targetViewRef.current.yaw);
|
|
2733
2829
|
}
|
|
2734
2830
|
if (acceptsPitch && delta.pitch !== void 0 && Number.isFinite(delta.pitch)) {
|
|
2735
|
-
gyroOffsetRef.current.pitch
|
|
2831
|
+
gyroOffsetRef.current.pitch = targetViewRef.current.pitch - gyroPoseRef.current.pitch;
|
|
2736
2832
|
}
|
|
2737
2833
|
}
|
|
2738
2834
|
markDirty();
|
|
@@ -2750,6 +2846,8 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2750
2846
|
if (delta.fov !== void 0 && Number.isFinite(delta.fov)) {
|
|
2751
2847
|
zoomVelocityRef.current = clamp(delta.fov / elapsed, -180, 180);
|
|
2752
2848
|
}
|
|
2849
|
+
} else if (delta.fov !== void 0 && Number.isFinite(delta.fov)) {
|
|
2850
|
+
zoomVelocityRef.current = 0;
|
|
2753
2851
|
}
|
|
2754
2852
|
return true;
|
|
2755
2853
|
};
|
|
@@ -2757,6 +2855,10 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2757
2855
|
ref,
|
|
2758
2856
|
() => ({
|
|
2759
2857
|
getView: () => ({ ...viewRef.current }),
|
|
2858
|
+
setSceneViewLimits: (limits) => {
|
|
2859
|
+
sceneLimitsRef.current = parseViewLimits(limits);
|
|
2860
|
+
refreshLimits();
|
|
2861
|
+
},
|
|
2760
2862
|
getTargetView: () => ({ ...targetViewRef.current }),
|
|
2761
2863
|
setView,
|
|
2762
2864
|
reset: () => setView(initialViewRef.current),
|
|
@@ -2780,7 +2882,7 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2780
2882
|
});
|
|
2781
2883
|
}
|
|
2782
2884
|
},
|
|
2783
|
-
setPointerActive: (source, active) => {
|
|
2885
|
+
setPointerActive: (source, active, releaseOptions) => {
|
|
2784
2886
|
const wasActive = source === "mouse" ? mouseActiveRef.current : touchActiveRef.current;
|
|
2785
2887
|
if (source === "mouse") {
|
|
2786
2888
|
mouseActiveRef.current = active;
|
|
@@ -2796,9 +2898,14 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2796
2898
|
} else if (!active && wasActive) {
|
|
2797
2899
|
eventBusRef.current.emit("viewinteractionend", { source });
|
|
2798
2900
|
}
|
|
2799
|
-
if (active
|
|
2901
|
+
if (active || !shouldKeepPointerInertia(
|
|
2902
|
+
lastVelocitySampleAtRef.current,
|
|
2903
|
+
performance.now(),
|
|
2904
|
+
releaseOptions?.cancelled
|
|
2905
|
+
)) {
|
|
2800
2906
|
stopVelocity();
|
|
2801
|
-
}
|
|
2907
|
+
}
|
|
2908
|
+
if (!active && !mouseActiveRef.current && !touchActiveRef.current) {
|
|
2802
2909
|
lastVelocitySampleAtRef.current = null;
|
|
2803
2910
|
snapTargetToHardLimits();
|
|
2804
2911
|
}
|
|
@@ -2848,7 +2955,9 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2848
2955
|
if (!Number.isFinite(yawDelta) || xrSessionRef.current != null || activeNavigationRef.current != null || gyroActiveRef.current || interactionLockCountRef.current > 0 || interactingRef.current || keyboardActiveRef.current || !inertiaFinished) {
|
|
2849
2956
|
return false;
|
|
2850
2957
|
}
|
|
2851
|
-
targetViewRef.current.yaw
|
|
2958
|
+
const nextYaw = applyLimitedYawDelta(targetViewRef.current.yaw, yawDelta, limitsRef.current.yaw);
|
|
2959
|
+
if (nextYaw === targetViewRef.current.yaw) return false;
|
|
2960
|
+
targetViewRef.current.yaw = nextYaw;
|
|
2852
2961
|
markDirty();
|
|
2853
2962
|
return true;
|
|
2854
2963
|
}
|
|
@@ -2861,6 +2970,9 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2861
2970
|
},
|
|
2862
2971
|
[]
|
|
2863
2972
|
);
|
|
2973
|
+
useLayoutEffect(() => {
|
|
2974
|
+
refreshLimits();
|
|
2975
|
+
}, [viewLimits, minFov, maxFov]);
|
|
2864
2976
|
useEffect(() => {
|
|
2865
2977
|
initialViewRef.current = { ...initialView };
|
|
2866
2978
|
setView(initialView);
|
|
@@ -2941,8 +3053,9 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2941
3053
|
);
|
|
2942
3054
|
const zoomDamping2 = Math.exp(-INERTIA_ZOOM_DAMPING * deltaSeconds);
|
|
2943
3055
|
if (Math.abs(yawVelocityRef.current) >= frictionStop) {
|
|
2944
|
-
targetViewRef.current.yaw
|
|
2945
|
-
yawVelocityRef.current
|
|
3056
|
+
const previousYaw = targetViewRef.current.yaw;
|
|
3057
|
+
targetViewRef.current.yaw = applyLimitedYawDelta(previousYaw, yawVelocityRef.current * deltaSeconds, limitsRef.current.yaw);
|
|
3058
|
+
yawVelocityRef.current = targetViewRef.current.yaw === previousYaw ? 0 : yawVelocityRef.current * rotationDamping;
|
|
2946
3059
|
markDirty();
|
|
2947
3060
|
} else {
|
|
2948
3061
|
yawVelocityRef.current = 0;
|
|
@@ -2983,7 +3096,7 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2983
3096
|
);
|
|
2984
3097
|
const rotationFactor = dampingFactor(rotateDamping, deltaSeconds);
|
|
2985
3098
|
const zoomFactor = dampingFactor(zoomDamping, deltaSeconds);
|
|
2986
|
-
const yawDelta =
|
|
3099
|
+
const yawDelta = limitedYawDelta(viewRef.current.yaw, targetView.yaw, limitsRef.current.yaw);
|
|
2987
3100
|
const smoothedView = {
|
|
2988
3101
|
yaw: normalizeYaw(viewRef.current.yaw + yawDelta * rotationFactor),
|
|
2989
3102
|
pitch: viewRef.current.pitch + (targetView.pitch - viewRef.current.pitch) * rotationFactor,
|
|
@@ -3613,17 +3726,18 @@ function MouseControls({
|
|
|
3613
3726
|
}
|
|
3614
3727
|
}
|
|
3615
3728
|
pointersRef.current.clear();
|
|
3616
|
-
controlsRef.current?.setPointerActive("mouse", false);
|
|
3729
|
+
controlsRef.current?.setPointerActive("mouse", false, { cancelled: true });
|
|
3617
3730
|
};
|
|
3618
3731
|
if (!enabled) {
|
|
3619
3732
|
clearPointers();
|
|
3620
3733
|
return;
|
|
3621
3734
|
}
|
|
3622
3735
|
const isMouseLike = (event) => event.pointerType === "mouse" || event.pointerType === "pen";
|
|
3623
|
-
const syncActive = () => {
|
|
3736
|
+
const syncActive = (cancelled = false) => {
|
|
3624
3737
|
controlsRef.current?.setPointerActive(
|
|
3625
3738
|
"mouse",
|
|
3626
|
-
pointersRef.current.size > 0
|
|
3739
|
+
pointersRef.current.size > 0,
|
|
3740
|
+
{ cancelled }
|
|
3627
3741
|
);
|
|
3628
3742
|
};
|
|
3629
3743
|
const onPointerDown = (event) => {
|
|
@@ -3684,7 +3798,7 @@ function MouseControls({
|
|
|
3684
3798
|
if (element.hasPointerCapture?.(event.pointerId)) {
|
|
3685
3799
|
element.releasePointerCapture?.(event.pointerId);
|
|
3686
3800
|
}
|
|
3687
|
-
syncActive();
|
|
3801
|
+
syncActive(event.type !== "pointerup");
|
|
3688
3802
|
};
|
|
3689
3803
|
const onWheel = (event) => {
|
|
3690
3804
|
if (!optionsRef.current.wheel) {
|
|
@@ -3706,19 +3820,21 @@ function MouseControls({
|
|
|
3706
3820
|
}
|
|
3707
3821
|
controlsRef.current?.applyViewDelta(
|
|
3708
3822
|
{ fov: delta },
|
|
3709
|
-
{
|
|
3823
|
+
{ source: "mouse" }
|
|
3710
3824
|
);
|
|
3711
3825
|
};
|
|
3712
3826
|
element.addEventListener("pointerdown", onPointerDown);
|
|
3713
3827
|
element.addEventListener("pointermove", onPointerMove);
|
|
3714
3828
|
element.addEventListener("pointerup", releasePointer);
|
|
3715
3829
|
element.addEventListener("pointercancel", releasePointer);
|
|
3830
|
+
element.addEventListener("lostpointercapture", releasePointer);
|
|
3716
3831
|
element.addEventListener("wheel", onWheel, { passive: false });
|
|
3717
3832
|
return () => {
|
|
3718
3833
|
element.removeEventListener("pointerdown", onPointerDown);
|
|
3719
3834
|
element.removeEventListener("pointermove", onPointerMove);
|
|
3720
3835
|
element.removeEventListener("pointerup", releasePointer);
|
|
3721
3836
|
element.removeEventListener("pointercancel", releasePointer);
|
|
3837
|
+
element.removeEventListener("lostpointercapture", releasePointer);
|
|
3722
3838
|
element.removeEventListener("wheel", onWheel);
|
|
3723
3839
|
clearPointers();
|
|
3724
3840
|
};
|
|
@@ -3901,7 +4017,7 @@ import {
|
|
|
3901
4017
|
useContext as useContext8,
|
|
3902
4018
|
useEffect as useEffect7,
|
|
3903
4019
|
useId,
|
|
3904
|
-
useLayoutEffect,
|
|
4020
|
+
useLayoutEffect as useLayoutEffect2,
|
|
3905
4021
|
useMemo as useMemo3,
|
|
3906
4022
|
useRef as useRef7,
|
|
3907
4023
|
useState as useState2
|
|
@@ -4204,7 +4320,7 @@ function PositionedMenuShell({
|
|
|
4204
4320
|
viewport?.removeEventListener("resize", refresh);
|
|
4205
4321
|
};
|
|
4206
4322
|
}, []);
|
|
4207
|
-
|
|
4323
|
+
useLayoutEffect2(() => {
|
|
4208
4324
|
const shell = shellRef.current;
|
|
4209
4325
|
if (!overlayElement || !shell) {
|
|
4210
4326
|
return;
|
|
@@ -4363,6 +4479,7 @@ function PanoContextMenu({
|
|
|
4363
4479
|
const openMenu = useCallback2(
|
|
4364
4480
|
(event) => {
|
|
4365
4481
|
event.nativeEvent.preventDefault();
|
|
4482
|
+
if (controlsRef.current?.isInteractionLocked()) return;
|
|
4366
4483
|
const view = controlsRef.current?.getView() ?? {
|
|
4367
4484
|
yaw: 0,
|
|
4368
4485
|
pitch: 0,
|
|
@@ -5023,9 +5140,142 @@ function PanoEvents(props) {
|
|
|
5023
5140
|
return null;
|
|
5024
5141
|
}
|
|
5025
5142
|
|
|
5143
|
+
// src/overlay/modal-host.ts
|
|
5144
|
+
function createPanoModalHost() {
|
|
5145
|
+
const leases = /* @__PURE__ */ new Set();
|
|
5146
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
5147
|
+
let runtime = null;
|
|
5148
|
+
let releaseRuntime;
|
|
5149
|
+
const syncRuntime = () => {
|
|
5150
|
+
if (leases.size > 0 && runtime) {
|
|
5151
|
+
releaseRuntime ?? (releaseRuntime = runtime.acquireInteractionLock());
|
|
5152
|
+
} else {
|
|
5153
|
+
releaseRuntime?.();
|
|
5154
|
+
releaseRuntime = void 0;
|
|
5155
|
+
}
|
|
5156
|
+
};
|
|
5157
|
+
const notify2 = () => {
|
|
5158
|
+
syncRuntime();
|
|
5159
|
+
for (const listener of listeners) listener();
|
|
5160
|
+
};
|
|
5161
|
+
return {
|
|
5162
|
+
getSnapshot: () => leases.size > 0,
|
|
5163
|
+
subscribe(listener) {
|
|
5164
|
+
listeners.add(listener);
|
|
5165
|
+
return () => {
|
|
5166
|
+
listeners.delete(listener);
|
|
5167
|
+
};
|
|
5168
|
+
},
|
|
5169
|
+
connect(next) {
|
|
5170
|
+
if (runtime === next) return;
|
|
5171
|
+
releaseRuntime?.();
|
|
5172
|
+
releaseRuntime = void 0;
|
|
5173
|
+
runtime = next;
|
|
5174
|
+
syncRuntime();
|
|
5175
|
+
},
|
|
5176
|
+
acquire() {
|
|
5177
|
+
const token = /* @__PURE__ */ Symbol();
|
|
5178
|
+
leases.add(token);
|
|
5179
|
+
notify2();
|
|
5180
|
+
return () => {
|
|
5181
|
+
if (leases.delete(token)) notify2();
|
|
5182
|
+
};
|
|
5183
|
+
}
|
|
5184
|
+
};
|
|
5185
|
+
}
|
|
5186
|
+
|
|
5187
|
+
// src/overlay/pano-overlay.tsx
|
|
5188
|
+
import {
|
|
5189
|
+
createContext as createContext11,
|
|
5190
|
+
useContext as useContext11,
|
|
5191
|
+
useLayoutEffect as useLayoutEffect3,
|
|
5192
|
+
useMemo as useMemo5,
|
|
5193
|
+
useState as useState3
|
|
5194
|
+
} from "react";
|
|
5195
|
+
|
|
5196
|
+
// src/overlay/visible-rect.ts
|
|
5197
|
+
function getOverlayVisibleRect(rect, viewport) {
|
|
5198
|
+
const left = Math.min(rect.width, Math.max(0, viewport.left - rect.left));
|
|
5199
|
+
const top = Math.min(rect.height, Math.max(0, viewport.top - rect.top));
|
|
5200
|
+
const right = Math.min(rect.width, Math.max(0, viewport.left + viewport.width - rect.left));
|
|
5201
|
+
const bottom = Math.min(rect.height, Math.max(0, viewport.top + viewport.height - rect.top));
|
|
5202
|
+
return { left, top, width: Math.max(0, right - left), height: Math.max(0, bottom - top) };
|
|
5203
|
+
}
|
|
5204
|
+
|
|
5205
|
+
// src/overlay/pano-overlay.tsx
|
|
5206
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
5207
|
+
var PanoOverlayContext = createContext11(null);
|
|
5208
|
+
var PanoModalHostContext = createContext11(null);
|
|
5209
|
+
function usePanoOverlay() {
|
|
5210
|
+
const context = useContext11(PanoOverlayContext);
|
|
5211
|
+
if (!context) throw new Error("usePanoOverlay must be used inside PanoViewer.renderOverlay.");
|
|
5212
|
+
return context;
|
|
5213
|
+
}
|
|
5214
|
+
function usePanoModal(open) {
|
|
5215
|
+
const host = useContext11(PanoModalHostContext);
|
|
5216
|
+
if (!host) throw new Error("usePanoModal must be used inside PanoViewer.renderOverlay.");
|
|
5217
|
+
useLayoutEffect3(() => open ? host.acquire() : void 0, [host, open]);
|
|
5218
|
+
}
|
|
5219
|
+
function PanoOverlayPortalProvider({
|
|
5220
|
+
container,
|
|
5221
|
+
children
|
|
5222
|
+
}) {
|
|
5223
|
+
const context = usePanoOverlay();
|
|
5224
|
+
const value = useMemo5(() => ({ ...context, portalContainer: container }), [context, container]);
|
|
5225
|
+
return /* @__PURE__ */ jsx4(PanoOverlayContext.Provider, { value, children });
|
|
5226
|
+
}
|
|
5227
|
+
function usePanoOverlayHost(isFullscreen) {
|
|
5228
|
+
const [portalContainer, setPortalContainer] = useState3(null);
|
|
5229
|
+
const [geometry, setGeometry] = useState3({
|
|
5230
|
+
size: { width: 0, height: 0 },
|
|
5231
|
+
visibleRect: { left: 0, top: 0, width: 0, height: 0 }
|
|
5232
|
+
});
|
|
5233
|
+
useLayoutEffect3(() => {
|
|
5234
|
+
if (!portalContainer) return;
|
|
5235
|
+
const win = portalContainer.ownerDocument.defaultView;
|
|
5236
|
+
if (!win) return;
|
|
5237
|
+
const measure = () => {
|
|
5238
|
+
const width = portalContainer.clientWidth;
|
|
5239
|
+
const height = portalContainer.clientHeight;
|
|
5240
|
+
const visual = win.visualViewport;
|
|
5241
|
+
const visibleRect = getOverlayVisibleRect(portalContainer.getBoundingClientRect(), {
|
|
5242
|
+
left: visual?.offsetLeft ?? 0,
|
|
5243
|
+
top: visual?.offsetTop ?? 0,
|
|
5244
|
+
width: visual?.width ?? win.innerWidth,
|
|
5245
|
+
height: visual?.height ?? win.innerHeight
|
|
5246
|
+
});
|
|
5247
|
+
setGeometry((previous) => previous.size.width === width && previous.size.height === height && visibleRect.left === previous.visibleRect.left && visibleRect.top === previous.visibleRect.top && visibleRect.width === previous.visibleRect.width && visibleRect.height === previous.visibleRect.height ? previous : { size: { width, height }, visibleRect });
|
|
5248
|
+
};
|
|
5249
|
+
let frame = 0;
|
|
5250
|
+
const scheduleMeasure = () => {
|
|
5251
|
+
if (!frame) frame = win.requestAnimationFrame(() => {
|
|
5252
|
+
frame = 0;
|
|
5253
|
+
measure();
|
|
5254
|
+
});
|
|
5255
|
+
};
|
|
5256
|
+
measure();
|
|
5257
|
+
const observer = new ResizeObserver(scheduleMeasure);
|
|
5258
|
+
observer.observe(portalContainer);
|
|
5259
|
+
win.addEventListener("scroll", scheduleMeasure, true);
|
|
5260
|
+
win.addEventListener("resize", scheduleMeasure);
|
|
5261
|
+
win.visualViewport?.addEventListener("resize", scheduleMeasure);
|
|
5262
|
+
win.visualViewport?.addEventListener("scroll", scheduleMeasure);
|
|
5263
|
+
return () => {
|
|
5264
|
+
observer.disconnect();
|
|
5265
|
+
win.cancelAnimationFrame(frame);
|
|
5266
|
+
win.removeEventListener("scroll", scheduleMeasure, true);
|
|
5267
|
+
win.removeEventListener("resize", scheduleMeasure);
|
|
5268
|
+
win.visualViewport?.removeEventListener("resize", scheduleMeasure);
|
|
5269
|
+
win.visualViewport?.removeEventListener("scroll", scheduleMeasure);
|
|
5270
|
+
};
|
|
5271
|
+
}, [portalContainer]);
|
|
5272
|
+
const context = useMemo5(() => ({ portalContainer, ...geometry, isFullscreen }), [portalContainer, geometry, isFullscreen]);
|
|
5273
|
+
return { context, setPortalContainer };
|
|
5274
|
+
}
|
|
5275
|
+
|
|
5026
5276
|
// src/panorama-event-surface.tsx
|
|
5027
5277
|
import { useThree as useThree6 } from "@react-three/fiber";
|
|
5028
|
-
import { useContext as
|
|
5278
|
+
import { useContext as useContext12, useEffect as useEffect10 } from "react";
|
|
5029
5279
|
import { BackSide, Raycaster, Vector2, Vector3 as Vector32 } from "three";
|
|
5030
5280
|
|
|
5031
5281
|
// src/hotspot/coordinates.ts
|
|
@@ -5103,7 +5353,7 @@ var DEFAULT_PANORAMA_CAMERA_NEAR = 0.1;
|
|
|
5103
5353
|
var DEFAULT_PANORAMA_CAMERA_FAR = DEFAULT_PANORAMA_RADIUS * 2;
|
|
5104
5354
|
|
|
5105
5355
|
// src/panorama-event-surface.tsx
|
|
5106
|
-
import { jsx as
|
|
5356
|
+
import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
5107
5357
|
var EVENT_SURFACE_RADIUS = DEFAULT_PANORAMA_RADIUS - 1;
|
|
5108
5358
|
function makePanoramaPointerEvent(event) {
|
|
5109
5359
|
const nativeEvent = event.nativeEvent;
|
|
@@ -5118,7 +5368,7 @@ function makePanoramaPointerEvent(event) {
|
|
|
5118
5368
|
};
|
|
5119
5369
|
}
|
|
5120
5370
|
function PanoramaEventSurface() {
|
|
5121
|
-
const eventBus =
|
|
5371
|
+
const eventBus = useContext12(PanoEventBusContext);
|
|
5122
5372
|
const { camera, gl } = useThree6();
|
|
5123
5373
|
useEffect10(() => {
|
|
5124
5374
|
if (!eventBus) {
|
|
@@ -5171,8 +5421,8 @@ function PanoramaEventSurface() {
|
|
|
5171
5421
|
onPointerUp: (event) => emit("pointerup", event),
|
|
5172
5422
|
onPointerMove: (event) => emit("pointermove", event),
|
|
5173
5423
|
children: [
|
|
5174
|
-
/* @__PURE__ */
|
|
5175
|
-
/* @__PURE__ */
|
|
5424
|
+
/* @__PURE__ */ jsx5("sphereGeometry", { args: [EVENT_SURFACE_RADIUS, 64, 32] }),
|
|
5425
|
+
/* @__PURE__ */ jsx5(
|
|
5176
5426
|
"meshBasicMaterial",
|
|
5177
5427
|
{
|
|
5178
5428
|
colorWrite: false,
|
|
@@ -5189,8 +5439,8 @@ function PanoramaEventSurface() {
|
|
|
5189
5439
|
}
|
|
5190
5440
|
|
|
5191
5441
|
// src/scenes-host.ts
|
|
5192
|
-
import { createContext as
|
|
5193
|
-
var ScenesHostContext =
|
|
5442
|
+
import { createContext as createContext12 } from "react";
|
|
5443
|
+
var ScenesHostContext = createContext12(null);
|
|
5194
5444
|
function createScenesHost() {
|
|
5195
5445
|
return {
|
|
5196
5446
|
controller: null,
|
|
@@ -5207,7 +5457,7 @@ function notifyScenesHost(host) {
|
|
|
5207
5457
|
|
|
5208
5458
|
// src/touch-controls.tsx
|
|
5209
5459
|
import { useThree as useThree7 } from "@react-three/fiber";
|
|
5210
|
-
import { useContext as
|
|
5460
|
+
import { useContext as useContext13, useEffect as useEffect11, useRef as useRef10 } from "react";
|
|
5211
5461
|
var DEFAULT_ROTATE_SPEED3 = 0.35;
|
|
5212
5462
|
function resolveSpeed3(value, fallback) {
|
|
5213
5463
|
return Number.isFinite(value) && value >= 0 ? value : fallback;
|
|
@@ -5222,7 +5472,7 @@ function TouchControls({
|
|
|
5222
5472
|
pinchZoom = true
|
|
5223
5473
|
}) {
|
|
5224
5474
|
useClaimControlChannel("touch");
|
|
5225
|
-
const controlsRef =
|
|
5475
|
+
const controlsRef = useContext13(PanoramaViewContext);
|
|
5226
5476
|
const { gl } = useThree7();
|
|
5227
5477
|
const pointersRef = useRef10(/* @__PURE__ */ new Map());
|
|
5228
5478
|
const pinchDistanceRef = useRef10(null);
|
|
@@ -5241,16 +5491,17 @@ function TouchControls({
|
|
|
5241
5491
|
}
|
|
5242
5492
|
pointersRef.current.clear();
|
|
5243
5493
|
pinchDistanceRef.current = null;
|
|
5244
|
-
controlsRef.current?.setPointerActive("touch", false);
|
|
5494
|
+
controlsRef.current?.setPointerActive("touch", false, { cancelled: true });
|
|
5245
5495
|
};
|
|
5246
5496
|
if (!enabled) {
|
|
5247
5497
|
clearPointers();
|
|
5248
5498
|
return;
|
|
5249
5499
|
}
|
|
5250
|
-
const syncActive = () => {
|
|
5500
|
+
const syncActive = (cancelled = false) => {
|
|
5251
5501
|
controlsRef.current?.setPointerActive(
|
|
5252
5502
|
"touch",
|
|
5253
|
-
pointersRef.current.size > 0
|
|
5503
|
+
pointersRef.current.size > 0,
|
|
5504
|
+
{ cancelled }
|
|
5254
5505
|
);
|
|
5255
5506
|
};
|
|
5256
5507
|
const onPointerDown = (event) => {
|
|
@@ -5335,17 +5586,19 @@ function TouchControls({
|
|
|
5335
5586
|
if (pointersRef.current.size < 2) {
|
|
5336
5587
|
pinchDistanceRef.current = null;
|
|
5337
5588
|
}
|
|
5338
|
-
syncActive();
|
|
5589
|
+
syncActive(event.type !== "pointerup");
|
|
5339
5590
|
};
|
|
5340
5591
|
element.addEventListener("pointerdown", onPointerDown);
|
|
5341
5592
|
element.addEventListener("pointermove", onPointerMove);
|
|
5342
5593
|
element.addEventListener("pointerup", releasePointer);
|
|
5343
5594
|
element.addEventListener("pointercancel", releasePointer);
|
|
5595
|
+
element.addEventListener("lostpointercapture", releasePointer);
|
|
5344
5596
|
return () => {
|
|
5345
5597
|
element.removeEventListener("pointerdown", onPointerDown);
|
|
5346
5598
|
element.removeEventListener("pointermove", onPointerMove);
|
|
5347
5599
|
element.removeEventListener("pointerup", releasePointer);
|
|
5348
5600
|
element.removeEventListener("pointercancel", releasePointer);
|
|
5601
|
+
element.removeEventListener("lostpointercapture", releasePointer);
|
|
5349
5602
|
clearPointers();
|
|
5350
5603
|
};
|
|
5351
5604
|
}, [controlsRef, enabled, gl]);
|
|
@@ -5353,21 +5606,21 @@ function TouchControls({
|
|
|
5353
5606
|
}
|
|
5354
5607
|
|
|
5355
5608
|
// src/video/chrome-overlay.tsx
|
|
5356
|
-
import { createContext as
|
|
5357
|
-
import { jsx as
|
|
5358
|
-
var PanoChromeOverlayContext =
|
|
5609
|
+
import { createContext as createContext13, useCallback as useCallback4, useMemo as useMemo6, useState as useState4 } from "react";
|
|
5610
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
5611
|
+
var PanoChromeOverlayContext = createContext13(null);
|
|
5359
5612
|
function usePanoChromeOverlay() {
|
|
5360
|
-
const [overlayElement, setOverlayElement] =
|
|
5613
|
+
const [overlayElement, setOverlayElement] = useState4(
|
|
5361
5614
|
null
|
|
5362
5615
|
);
|
|
5363
5616
|
const setOverlayNode = useCallback4((node) => {
|
|
5364
5617
|
setOverlayElement(node);
|
|
5365
5618
|
}, []);
|
|
5366
|
-
const api =
|
|
5619
|
+
const api = useMemo6(
|
|
5367
5620
|
() => ({ overlayElement }),
|
|
5368
5621
|
[overlayElement]
|
|
5369
5622
|
);
|
|
5370
|
-
const overlay = /* @__PURE__ */
|
|
5623
|
+
const overlay = /* @__PURE__ */ jsx6(
|
|
5371
5624
|
"div",
|
|
5372
5625
|
{
|
|
5373
5626
|
className: "pano-chrome-overlay",
|
|
@@ -5379,9 +5632,9 @@ function usePanoChromeOverlay() {
|
|
|
5379
5632
|
}
|
|
5380
5633
|
|
|
5381
5634
|
// src/video/host.ts
|
|
5382
|
-
import { createContext as
|
|
5383
|
-
var PanoVideoHostContext =
|
|
5384
|
-
var DefaultPanoVideoControlsContext =
|
|
5635
|
+
import { createContext as createContext14, useContext as useContext14 } from "react";
|
|
5636
|
+
var PanoVideoHostContext = createContext14(null);
|
|
5637
|
+
var DefaultPanoVideoControlsContext = createContext14(false);
|
|
5385
5638
|
function createPanoVideoHost() {
|
|
5386
5639
|
return {
|
|
5387
5640
|
controller: null,
|
|
@@ -5426,8 +5679,8 @@ function isProduction3() {
|
|
|
5426
5679
|
return nodeEnv === "production";
|
|
5427
5680
|
}
|
|
5428
5681
|
function useClaimPanoVideoControls() {
|
|
5429
|
-
const host =
|
|
5430
|
-
const isDefault =
|
|
5682
|
+
const host = useContext14(PanoVideoHostContext);
|
|
5683
|
+
const isDefault = useContext14(DefaultPanoVideoControlsContext);
|
|
5431
5684
|
if (!host || isDefault) {
|
|
5432
5685
|
return;
|
|
5433
5686
|
}
|
|
@@ -5444,7 +5697,7 @@ import { useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
|
5444
5697
|
|
|
5445
5698
|
// src/video/pano-video-captions.tsx
|
|
5446
5699
|
import { useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
5447
|
-
import { jsx as
|
|
5700
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
5448
5701
|
var DEFAULT_PANO_VIDEO_CAPTION_APPEARANCE = {
|
|
5449
5702
|
color: "#ffffff",
|
|
5450
5703
|
background: "rgba(0, 0, 0, 0.55)",
|
|
@@ -5492,13 +5745,13 @@ function PanoVideoCaptionsOverlay({
|
|
|
5492
5745
|
textShadow: snapshot.captionAppearance.textShadow,
|
|
5493
5746
|
whiteSpace: "pre-wrap"
|
|
5494
5747
|
};
|
|
5495
|
-
return /* @__PURE__ */
|
|
5748
|
+
return /* @__PURE__ */ jsx7(
|
|
5496
5749
|
"div",
|
|
5497
5750
|
{
|
|
5498
5751
|
className: "pano-video-captions",
|
|
5499
5752
|
"data-pano-video-captions": "",
|
|
5500
5753
|
style: wrapperStyle,
|
|
5501
|
-
children: /* @__PURE__ */
|
|
5754
|
+
children: /* @__PURE__ */ jsx7("div", { style: textStyle, children: snapshot.captionText })
|
|
5502
5755
|
}
|
|
5503
5756
|
);
|
|
5504
5757
|
}
|
|
@@ -5511,12 +5764,12 @@ function PanoVideoCaptions({
|
|
|
5511
5764
|
// src/video/pano-video-controls.tsx
|
|
5512
5765
|
import {
|
|
5513
5766
|
useCallback as useCallback5,
|
|
5514
|
-
useContext as
|
|
5767
|
+
useContext as useContext15,
|
|
5515
5768
|
useEffect as useEffect12,
|
|
5516
5769
|
useId as useId2,
|
|
5517
|
-
useMemo as
|
|
5770
|
+
useMemo as useMemo7,
|
|
5518
5771
|
useRef as useRef11,
|
|
5519
|
-
useState as
|
|
5772
|
+
useState as useState5,
|
|
5520
5773
|
useSyncExternalStore as useSyncExternalStore3
|
|
5521
5774
|
} from "react";
|
|
5522
5775
|
|
|
@@ -5650,7 +5903,7 @@ function cueText(cue) {
|
|
|
5650
5903
|
}
|
|
5651
5904
|
|
|
5652
5905
|
// src/video/pano-video-controls.tsx
|
|
5653
|
-
import { Fragment, jsx as
|
|
5906
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
5654
5907
|
var DEFAULT_PANO_VIDEO_CONTROLS_APPEARANCE = {
|
|
5655
5908
|
background: "rgba(16, 16, 16, 0.88)",
|
|
5656
5909
|
color: "#f4f4f4",
|
|
@@ -5711,7 +5964,7 @@ function volumeFromClientY(clientY, track) {
|
|
|
5711
5964
|
return Math.max(0, Math.min(1, (rect.bottom - clientY) / rect.height));
|
|
5712
5965
|
}
|
|
5713
5966
|
function Icon({ path }) {
|
|
5714
|
-
return /* @__PURE__ */
|
|
5967
|
+
return /* @__PURE__ */ jsx8(
|
|
5715
5968
|
"svg",
|
|
5716
5969
|
{
|
|
5717
5970
|
"aria-hidden": true,
|
|
@@ -5723,7 +5976,7 @@ function Icon({ path }) {
|
|
|
5723
5976
|
strokeWidth: "1.75",
|
|
5724
5977
|
viewBox: "0 0 16 16",
|
|
5725
5978
|
width: "16",
|
|
5726
|
-
children: /* @__PURE__ */
|
|
5979
|
+
children: /* @__PURE__ */ jsx8("path", { d: path })
|
|
5727
5980
|
}
|
|
5728
5981
|
);
|
|
5729
5982
|
}
|
|
@@ -5735,7 +5988,7 @@ function ChromeButton({
|
|
|
5735
5988
|
label,
|
|
5736
5989
|
onClick
|
|
5737
5990
|
}) {
|
|
5738
|
-
return /* @__PURE__ */
|
|
5991
|
+
return /* @__PURE__ */ jsx8(
|
|
5739
5992
|
"button",
|
|
5740
5993
|
{
|
|
5741
5994
|
"aria-label": label,
|
|
@@ -5761,14 +6014,14 @@ function ChromeMenu({
|
|
|
5761
6014
|
labelledBy,
|
|
5762
6015
|
items
|
|
5763
6016
|
}) {
|
|
5764
|
-
return /* @__PURE__ */
|
|
6017
|
+
return /* @__PURE__ */ jsx8(
|
|
5765
6018
|
ChromeMenuSurface,
|
|
5766
6019
|
{
|
|
5767
6020
|
appearance,
|
|
5768
6021
|
id,
|
|
5769
6022
|
labelledBy,
|
|
5770
6023
|
role: "menu",
|
|
5771
|
-
children: items.map((item) => /* @__PURE__ */
|
|
6024
|
+
children: items.map((item) => /* @__PURE__ */ jsx8(
|
|
5772
6025
|
ChromeMenuRadioItem,
|
|
5773
6026
|
{
|
|
5774
6027
|
active: item.active,
|
|
@@ -5788,7 +6041,7 @@ function ChromeMenuSurface({
|
|
|
5788
6041
|
labelledBy,
|
|
5789
6042
|
role
|
|
5790
6043
|
}) {
|
|
5791
|
-
return /* @__PURE__ */
|
|
6044
|
+
return /* @__PURE__ */ jsx8(
|
|
5792
6045
|
"div",
|
|
5793
6046
|
{
|
|
5794
6047
|
"aria-labelledby": labelledBy,
|
|
@@ -5812,7 +6065,7 @@ function ChromeMenuRadioItem({
|
|
|
5812
6065
|
label,
|
|
5813
6066
|
onClick
|
|
5814
6067
|
}) {
|
|
5815
|
-
return /* @__PURE__ */
|
|
6068
|
+
return /* @__PURE__ */ jsx8(
|
|
5816
6069
|
"button",
|
|
5817
6070
|
{
|
|
5818
6071
|
"aria-checked": active,
|
|
@@ -5852,7 +6105,7 @@ function ChromeMenuActionItem({
|
|
|
5852
6105
|
},
|
|
5853
6106
|
type: "button",
|
|
5854
6107
|
children: [
|
|
5855
|
-
/* @__PURE__ */
|
|
6108
|
+
/* @__PURE__ */ jsx8("span", { children: label }),
|
|
5856
6109
|
secondary
|
|
5857
6110
|
]
|
|
5858
6111
|
}
|
|
@@ -5861,10 +6114,10 @@ function ChromeMenuActionItem({
|
|
|
5861
6114
|
function ChromeMenuSectionLabel({
|
|
5862
6115
|
children
|
|
5863
6116
|
}) {
|
|
5864
|
-
return /* @__PURE__ */
|
|
6117
|
+
return /* @__PURE__ */ jsx8("div", { className: "pano-video-chrome-menu-label", children });
|
|
5865
6118
|
}
|
|
5866
6119
|
function ChromeMenuDivider() {
|
|
5867
|
-
return /* @__PURE__ */
|
|
6120
|
+
return /* @__PURE__ */ jsx8("div", { className: "pano-video-chrome-menu-divider" });
|
|
5868
6121
|
}
|
|
5869
6122
|
function CaptionsMenu({
|
|
5870
6123
|
appearance,
|
|
@@ -5877,7 +6130,7 @@ function CaptionsMenu({
|
|
|
5877
6130
|
panel,
|
|
5878
6131
|
snapshot
|
|
5879
6132
|
}) {
|
|
5880
|
-
return /* @__PURE__ */
|
|
6133
|
+
return /* @__PURE__ */ jsx8(
|
|
5881
6134
|
ChromeMenuSurface,
|
|
5882
6135
|
{
|
|
5883
6136
|
appearance,
|
|
@@ -5886,7 +6139,7 @@ function CaptionsMenu({
|
|
|
5886
6139
|
role: "menu",
|
|
5887
6140
|
children: panel === "tracks" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
5888
6141
|
/* @__PURE__ */ jsxs3("div", { className: "pano-video-chrome-menu-list", children: [
|
|
5889
|
-
/* @__PURE__ */
|
|
6142
|
+
/* @__PURE__ */ jsx8(
|
|
5890
6143
|
ChromeMenuRadioItem,
|
|
5891
6144
|
{
|
|
5892
6145
|
active: snapshot.trackId === null,
|
|
@@ -5899,7 +6152,7 @@ function CaptionsMenu({
|
|
|
5899
6152
|
),
|
|
5900
6153
|
snapshot.tracks.map((track) => {
|
|
5901
6154
|
const trackItemId = panoVideoTrackId(track);
|
|
5902
|
-
return /* @__PURE__ */
|
|
6155
|
+
return /* @__PURE__ */ jsx8(
|
|
5903
6156
|
ChromeMenuRadioItem,
|
|
5904
6157
|
{
|
|
5905
6158
|
active: snapshot.trackId === trackItemId,
|
|
@@ -5913,29 +6166,29 @@ function CaptionsMenu({
|
|
|
5913
6166
|
);
|
|
5914
6167
|
})
|
|
5915
6168
|
] }),
|
|
5916
|
-
/* @__PURE__ */
|
|
5917
|
-
/* @__PURE__ */
|
|
6169
|
+
/* @__PURE__ */ jsx8(ChromeMenuDivider, {}),
|
|
6170
|
+
/* @__PURE__ */ jsx8(
|
|
5918
6171
|
ChromeMenuActionItem,
|
|
5919
6172
|
{
|
|
5920
6173
|
appearance,
|
|
5921
6174
|
label: "Settings",
|
|
5922
6175
|
onClick: onOpenSettings,
|
|
5923
|
-
secondary: /* @__PURE__ */
|
|
6176
|
+
secondary: /* @__PURE__ */ jsx8("span", { "aria-hidden": true, children: "\u203A" })
|
|
5924
6177
|
}
|
|
5925
6178
|
)
|
|
5926
6179
|
] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
5927
|
-
/* @__PURE__ */
|
|
6180
|
+
/* @__PURE__ */ jsx8(
|
|
5928
6181
|
ChromeMenuActionItem,
|
|
5929
6182
|
{
|
|
5930
6183
|
appearance,
|
|
5931
6184
|
label: "Back",
|
|
5932
6185
|
onClick: onShowTracks,
|
|
5933
|
-
secondary: /* @__PURE__ */
|
|
6186
|
+
secondary: /* @__PURE__ */ jsx8("span", { "aria-hidden": true, children: "\u2039" })
|
|
5934
6187
|
}
|
|
5935
6188
|
),
|
|
5936
|
-
/* @__PURE__ */
|
|
5937
|
-
/* @__PURE__ */
|
|
5938
|
-
CAPTION_SIZE_OPTIONS.map((option) => /* @__PURE__ */
|
|
6189
|
+
/* @__PURE__ */ jsx8(ChromeMenuDivider, {}),
|
|
6190
|
+
/* @__PURE__ */ jsx8(ChromeMenuSectionLabel, { children: "Font size" }),
|
|
6191
|
+
CAPTION_SIZE_OPTIONS.map((option) => /* @__PURE__ */ jsx8(
|
|
5939
6192
|
ChromeMenuRadioItem,
|
|
5940
6193
|
{
|
|
5941
6194
|
active: Number(snapshot.captionAppearance.fontSize) === option.value,
|
|
@@ -5947,9 +6200,9 @@ function CaptionsMenu({
|
|
|
5947
6200
|
},
|
|
5948
6201
|
option.id
|
|
5949
6202
|
)),
|
|
5950
|
-
/* @__PURE__ */
|
|
5951
|
-
/* @__PURE__ */
|
|
5952
|
-
CAPTION_BACKGROUND_OPTIONS.map((option) => /* @__PURE__ */
|
|
6203
|
+
/* @__PURE__ */ jsx8(ChromeMenuDivider, {}),
|
|
6204
|
+
/* @__PURE__ */ jsx8(ChromeMenuSectionLabel, { children: "Background" }),
|
|
6205
|
+
CAPTION_BACKGROUND_OPTIONS.map((option) => /* @__PURE__ */ jsx8(
|
|
5953
6206
|
ChromeMenuRadioItem,
|
|
5954
6207
|
{
|
|
5955
6208
|
active: snapshot.captionAppearance.background === option.value,
|
|
@@ -6004,7 +6257,7 @@ function VerticalVolumeSlider({
|
|
|
6004
6257
|
pointerEvents: "auto"
|
|
6005
6258
|
},
|
|
6006
6259
|
children: [
|
|
6007
|
-
/* @__PURE__ */
|
|
6260
|
+
/* @__PURE__ */ jsx8(
|
|
6008
6261
|
"span",
|
|
6009
6262
|
{
|
|
6010
6263
|
"aria-hidden": true,
|
|
@@ -6016,7 +6269,7 @@ function VerticalVolumeSlider({
|
|
|
6016
6269
|
children: percentLabel
|
|
6017
6270
|
}
|
|
6018
6271
|
),
|
|
6019
|
-
/* @__PURE__ */
|
|
6272
|
+
/* @__PURE__ */ jsx8(
|
|
6020
6273
|
"div",
|
|
6021
6274
|
{
|
|
6022
6275
|
style: {
|
|
@@ -6056,7 +6309,7 @@ function VerticalVolumeSlider({
|
|
|
6056
6309
|
},
|
|
6057
6310
|
tabIndex: 0,
|
|
6058
6311
|
children: [
|
|
6059
|
-
/* @__PURE__ */
|
|
6312
|
+
/* @__PURE__ */ jsx8(
|
|
6060
6313
|
"div",
|
|
6061
6314
|
{
|
|
6062
6315
|
style: {
|
|
@@ -6071,7 +6324,7 @@ function VerticalVolumeSlider({
|
|
|
6071
6324
|
}
|
|
6072
6325
|
}
|
|
6073
6326
|
),
|
|
6074
|
-
/* @__PURE__ */
|
|
6327
|
+
/* @__PURE__ */ jsx8(
|
|
6075
6328
|
"div",
|
|
6076
6329
|
{
|
|
6077
6330
|
style: {
|
|
@@ -6107,7 +6360,7 @@ function VolumeControl({
|
|
|
6107
6360
|
volumeAdjustable
|
|
6108
6361
|
}) {
|
|
6109
6362
|
const rootRef = useRef11(null);
|
|
6110
|
-
const [open, setOpen] =
|
|
6363
|
+
const [open, setOpen] = useState5(false);
|
|
6111
6364
|
const displayVolume = muted ? 0 : volume;
|
|
6112
6365
|
const mutedOrSilent = muted || volume === 0;
|
|
6113
6366
|
useEffect12(() => {
|
|
@@ -6130,13 +6383,13 @@ function VolumeControl({
|
|
|
6130
6383
|
};
|
|
6131
6384
|
}, [open, volumeAdjustable]);
|
|
6132
6385
|
if (!volumeAdjustable) {
|
|
6133
|
-
return /* @__PURE__ */
|
|
6386
|
+
return /* @__PURE__ */ jsx8(
|
|
6134
6387
|
ChromeButton,
|
|
6135
6388
|
{
|
|
6136
6389
|
appearance,
|
|
6137
6390
|
label: mutedOrSilent ? "Unmute" : "Mute",
|
|
6138
6391
|
onClick: onToggleMuted,
|
|
6139
|
-
children: mutedOrSilent ? /* @__PURE__ */
|
|
6392
|
+
children: mutedOrSilent ? /* @__PURE__ */ jsx8(Icon, { path: "M3 6.5h2.2L8.5 4v8L5.2 9.5H3zM10.2 6.2l3.2 3.6M13.4 6.2l-3.2 3.6" }) : /* @__PURE__ */ jsx8(Icon, { path: "M3 6.5h2.2L8.5 4v8L5.2 9.5H3zM10.5 5.5a3 3 0 0 1 0 5" })
|
|
6140
6393
|
}
|
|
6141
6394
|
);
|
|
6142
6395
|
}
|
|
@@ -6168,7 +6421,7 @@ function VolumeControl({
|
|
|
6168
6421
|
},
|
|
6169
6422
|
ref: rootRef,
|
|
6170
6423
|
children: [
|
|
6171
|
-
open ? /* @__PURE__ */
|
|
6424
|
+
open ? /* @__PURE__ */ jsx8(
|
|
6172
6425
|
VerticalVolumeSlider,
|
|
6173
6426
|
{
|
|
6174
6427
|
appearance,
|
|
@@ -6176,7 +6429,7 @@ function VolumeControl({
|
|
|
6176
6429
|
volume: displayVolume
|
|
6177
6430
|
}
|
|
6178
6431
|
) : null,
|
|
6179
|
-
/* @__PURE__ */
|
|
6432
|
+
/* @__PURE__ */ jsx8(
|
|
6180
6433
|
ChromeButton,
|
|
6181
6434
|
{
|
|
6182
6435
|
appearance,
|
|
@@ -6187,7 +6440,7 @@ function VolumeControl({
|
|
|
6187
6440
|
}
|
|
6188
6441
|
onToggleMuted();
|
|
6189
6442
|
},
|
|
6190
|
-
children: mutedOrSilent ? /* @__PURE__ */
|
|
6443
|
+
children: mutedOrSilent ? /* @__PURE__ */ jsx8(Icon, { path: "M3 6.5h2.2L8.5 4v8L5.2 9.5H3zM10.2 6.2l3.2 3.6M13.4 6.2l-3.2 3.6" }) : /* @__PURE__ */ jsx8(Icon, { path: "M3 6.5h2.2L8.5 4v8L5.2 9.5H3zM10.5 5.5a3 3 0 0 1 0 5" })
|
|
6191
6444
|
}
|
|
6192
6445
|
)
|
|
6193
6446
|
]
|
|
@@ -6200,7 +6453,7 @@ function PanoVideoControlsHud({
|
|
|
6200
6453
|
fullscreen,
|
|
6201
6454
|
overlayElement
|
|
6202
6455
|
}) {
|
|
6203
|
-
const resolved =
|
|
6456
|
+
const resolved = useMemo7(
|
|
6204
6457
|
() => resolveControlsAppearance(appearance),
|
|
6205
6458
|
[appearance]
|
|
6206
6459
|
);
|
|
@@ -6209,11 +6462,11 @@ function PanoVideoControlsHud({
|
|
|
6209
6462
|
controller.getSnapshot,
|
|
6210
6463
|
controller.getSnapshot
|
|
6211
6464
|
);
|
|
6212
|
-
const [menu, setMenu] =
|
|
6213
|
-
const [captionsPanel, setCaptionsPanel] =
|
|
6214
|
-
const [visible, setVisible] =
|
|
6215
|
-
const [volumeOpen, setVolumeOpen] =
|
|
6216
|
-
const [overlayWidth, setOverlayWidth] =
|
|
6465
|
+
const [menu, setMenu] = useState5(null);
|
|
6466
|
+
const [captionsPanel, setCaptionsPanel] = useState5("tracks");
|
|
6467
|
+
const [visible, setVisible] = useState5(true);
|
|
6468
|
+
const [volumeOpen, setVolumeOpen] = useState5(false);
|
|
6469
|
+
const [overlayWidth, setOverlayWidth] = useState5(
|
|
6217
6470
|
() => overlayElement.clientWidth
|
|
6218
6471
|
);
|
|
6219
6472
|
const idleTimerRef = useRef11(0);
|
|
@@ -6347,7 +6600,7 @@ function PanoVideoControlsHud({
|
|
|
6347
6600
|
let menuNode = null;
|
|
6348
6601
|
switch (menu) {
|
|
6349
6602
|
case "rate":
|
|
6350
|
-
menuNode = /* @__PURE__ */
|
|
6603
|
+
menuNode = /* @__PURE__ */ jsx8(
|
|
6351
6604
|
ChromeMenu,
|
|
6352
6605
|
{
|
|
6353
6606
|
appearance: resolved,
|
|
@@ -6366,7 +6619,7 @@ function PanoVideoControlsHud({
|
|
|
6366
6619
|
);
|
|
6367
6620
|
break;
|
|
6368
6621
|
case "variant":
|
|
6369
|
-
menuNode = /* @__PURE__ */
|
|
6622
|
+
menuNode = /* @__PURE__ */ jsx8(
|
|
6370
6623
|
ChromeMenu,
|
|
6371
6624
|
{
|
|
6372
6625
|
appearance: resolved,
|
|
@@ -6385,7 +6638,7 @@ function PanoVideoControlsHud({
|
|
|
6385
6638
|
);
|
|
6386
6639
|
break;
|
|
6387
6640
|
case "captions":
|
|
6388
|
-
menuNode = /* @__PURE__ */
|
|
6641
|
+
menuNode = /* @__PURE__ */ jsx8(
|
|
6389
6642
|
CaptionsMenu,
|
|
6390
6643
|
{
|
|
6391
6644
|
appearance: resolved,
|
|
@@ -6409,7 +6662,7 @@ function PanoVideoControlsHud({
|
|
|
6409
6662
|
);
|
|
6410
6663
|
break;
|
|
6411
6664
|
case "more":
|
|
6412
|
-
menuNode = /* @__PURE__ */
|
|
6665
|
+
menuNode = /* @__PURE__ */ jsx8(
|
|
6413
6666
|
ChromeMenu,
|
|
6414
6667
|
{
|
|
6415
6668
|
appearance: resolved,
|
|
@@ -6477,7 +6730,7 @@ function PanoVideoControlsHud({
|
|
|
6477
6730
|
};
|
|
6478
6731
|
const rateButton = /* @__PURE__ */ jsxs3("div", { className: "pano-video-menu", "data-pano-video-menu": "rate", children: [
|
|
6479
6732
|
!compact && menu === "rate" ? menuNode : null,
|
|
6480
|
-
/* @__PURE__ */
|
|
6733
|
+
/* @__PURE__ */ jsx8(
|
|
6481
6734
|
ChromeButton,
|
|
6482
6735
|
{
|
|
6483
6736
|
appearance: resolved,
|
|
@@ -6485,13 +6738,13 @@ function PanoVideoControlsHud({
|
|
|
6485
6738
|
onClick: () => {
|
|
6486
6739
|
toggleMenu("rate");
|
|
6487
6740
|
},
|
|
6488
|
-
children: /* @__PURE__ */
|
|
6741
|
+
children: /* @__PURE__ */ jsx8("span", { className: "pano-video-chrome-label", id: `${barId}-rate-btn`, children: snapshot.playbackRate === 1 ? "1x" : `${snapshot.playbackRate}x` })
|
|
6489
6742
|
}
|
|
6490
6743
|
)
|
|
6491
6744
|
] });
|
|
6492
6745
|
const variantButton = canSwitchVariant ? /* @__PURE__ */ jsxs3("div", { className: "pano-video-menu", "data-pano-video-menu": "variant", children: [
|
|
6493
6746
|
!compact && menu === "variant" ? menuNode : null,
|
|
6494
|
-
/* @__PURE__ */
|
|
6747
|
+
/* @__PURE__ */ jsx8(
|
|
6495
6748
|
ChromeButton,
|
|
6496
6749
|
{
|
|
6497
6750
|
appearance: resolved,
|
|
@@ -6499,13 +6752,13 @@ function PanoVideoControlsHud({
|
|
|
6499
6752
|
onClick: () => {
|
|
6500
6753
|
toggleMenu("variant");
|
|
6501
6754
|
},
|
|
6502
|
-
children: /* @__PURE__ */
|
|
6755
|
+
children: /* @__PURE__ */ jsx8("span", { className: "pano-video-chrome-label", id: `${barId}-variant-btn`, children: snapshot.variants.find((variant) => variant.id === snapshot.variantId)?.label ?? "Quality" })
|
|
6503
6756
|
}
|
|
6504
6757
|
)
|
|
6505
6758
|
] }) : null;
|
|
6506
6759
|
const captionsButton = showCaptionsMenu ? /* @__PURE__ */ jsxs3("div", { className: "pano-video-menu", "data-pano-video-menu": "captions", children: [
|
|
6507
6760
|
!compact && menu === "captions" ? menuNode : null,
|
|
6508
|
-
/* @__PURE__ */
|
|
6761
|
+
/* @__PURE__ */ jsx8(
|
|
6509
6762
|
ChromeButton,
|
|
6510
6763
|
{
|
|
6511
6764
|
appearance: resolved,
|
|
@@ -6513,7 +6766,7 @@ function PanoVideoControlsHud({
|
|
|
6513
6766
|
onClick: () => {
|
|
6514
6767
|
toggleMenu("captions");
|
|
6515
6768
|
},
|
|
6516
|
-
children: /* @__PURE__ */
|
|
6769
|
+
children: /* @__PURE__ */ jsx8("span", { id: `${barId}-captions-btn`, children: /* @__PURE__ */ jsx8(Icon, { path: "M2.5 4.5h11v7h-11zM5 7.2h2.4M5 9.2h5.5" }) })
|
|
6517
6770
|
}
|
|
6518
6771
|
)
|
|
6519
6772
|
] }) : null;
|
|
@@ -6524,7 +6777,7 @@ function PanoVideoControlsHud({
|
|
|
6524
6777
|
"data-pano-video-controls": "",
|
|
6525
6778
|
style: barStyle,
|
|
6526
6779
|
children: [
|
|
6527
|
-
/* @__PURE__ */
|
|
6780
|
+
/* @__PURE__ */ jsx8(
|
|
6528
6781
|
ChromeButton,
|
|
6529
6782
|
{
|
|
6530
6783
|
appearance: resolved,
|
|
@@ -6532,11 +6785,11 @@ function PanoVideoControlsHud({
|
|
|
6532
6785
|
onClick: () => {
|
|
6533
6786
|
controller.togglePlay();
|
|
6534
6787
|
},
|
|
6535
|
-
children: snapshot.playing ? /* @__PURE__ */
|
|
6788
|
+
children: snapshot.playing ? /* @__PURE__ */ jsx8(Icon, { path: "M5 3.5h2.2v9H5zM8.8 3.5H11v9H8.8z" }) : /* @__PURE__ */ jsx8(Icon, { path: "M5 3.2v9.6L13 8z" })
|
|
6536
6789
|
}
|
|
6537
6790
|
),
|
|
6538
|
-
hideTime ? null : /* @__PURE__ */
|
|
6539
|
-
/* @__PURE__ */
|
|
6791
|
+
hideTime ? null : /* @__PURE__ */ jsx8("span", { className: "pano-video-time", children: formatMediaTime(snapshot.currentTime) }),
|
|
6792
|
+
/* @__PURE__ */ jsx8(
|
|
6540
6793
|
"input",
|
|
6541
6794
|
{
|
|
6542
6795
|
"aria-label": "Seek",
|
|
@@ -6558,8 +6811,8 @@ function PanoVideoControlsHud({
|
|
|
6558
6811
|
value: duration > 0 ? snapshot.currentTime : 0
|
|
6559
6812
|
}
|
|
6560
6813
|
),
|
|
6561
|
-
hideTime ? null : /* @__PURE__ */
|
|
6562
|
-
/* @__PURE__ */
|
|
6814
|
+
hideTime ? null : /* @__PURE__ */ jsx8("span", { className: "pano-video-time", children: formatMediaTime(duration) }),
|
|
6815
|
+
/* @__PURE__ */ jsx8(
|
|
6563
6816
|
VolumeControl,
|
|
6564
6817
|
{
|
|
6565
6818
|
appearance: resolved,
|
|
@@ -6577,7 +6830,7 @@ function PanoVideoControlsHud({
|
|
|
6577
6830
|
),
|
|
6578
6831
|
compact ? /* @__PURE__ */ jsxs3("div", { className: "pano-video-menu", "data-pano-video-menu": "more", children: [
|
|
6579
6832
|
menu !== null ? menuNode : null,
|
|
6580
|
-
/* @__PURE__ */
|
|
6833
|
+
/* @__PURE__ */ jsx8(
|
|
6581
6834
|
ChromeButton,
|
|
6582
6835
|
{
|
|
6583
6836
|
appearance: resolved,
|
|
@@ -6586,7 +6839,7 @@ function PanoVideoControlsHud({
|
|
|
6586
6839
|
onClick: () => {
|
|
6587
6840
|
toggleMenu("more");
|
|
6588
6841
|
},
|
|
6589
|
-
children: /* @__PURE__ */
|
|
6842
|
+
children: /* @__PURE__ */ jsx8(Icon, { path: "M3 8a1 1 0 1 0 2 0 1 1 0 1 0-2 0M7 8a1 1 0 1 0 2 0 1 1 0 1 0-2 0M11 8a1 1 0 1 0 2 0 1 1 0 1 0-2 0" })
|
|
6590
6843
|
}
|
|
6591
6844
|
)
|
|
6592
6845
|
] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
@@ -6594,7 +6847,7 @@ function PanoVideoControlsHud({
|
|
|
6594
6847
|
variantButton,
|
|
6595
6848
|
captionsButton
|
|
6596
6849
|
] }),
|
|
6597
|
-
showFullscreen ? /* @__PURE__ */
|
|
6850
|
+
showFullscreen ? /* @__PURE__ */ jsx8(
|
|
6598
6851
|
ChromeButton,
|
|
6599
6852
|
{
|
|
6600
6853
|
appearance: resolved,
|
|
@@ -6602,7 +6855,7 @@ function PanoVideoControlsHud({
|
|
|
6602
6855
|
onClick: () => {
|
|
6603
6856
|
fullscreen?.toggleFullscreen();
|
|
6604
6857
|
},
|
|
6605
|
-
children: fullscreen?.isFullscreen ? /* @__PURE__ */
|
|
6858
|
+
children: fullscreen?.isFullscreen ? /* @__PURE__ */ jsx8(Icon, { path: "M6 3.5H3.5V6M10 3.5h2.5V6M6 12.5H3.5V10M10 12.5h2.5V10" }) : /* @__PURE__ */ jsx8(Icon, { path: "M3.5 6V3.5H6M10 3.5h2.5V6M3.5 10v2.5H6M10 12.5h2.5V10" })
|
|
6606
6859
|
}
|
|
6607
6860
|
) : null
|
|
6608
6861
|
]
|
|
@@ -6611,7 +6864,7 @@ function PanoVideoControlsHud({
|
|
|
6611
6864
|
}
|
|
6612
6865
|
function PanoVideoControls({ appearance }) {
|
|
6613
6866
|
useClaimPanoVideoControls();
|
|
6614
|
-
const host =
|
|
6867
|
+
const host = useContext15(PanoVideoHostContext);
|
|
6615
6868
|
if (host && appearance) {
|
|
6616
6869
|
host.controls = appearance;
|
|
6617
6870
|
}
|
|
@@ -6619,7 +6872,7 @@ function PanoVideoControls({ appearance }) {
|
|
|
6619
6872
|
}
|
|
6620
6873
|
|
|
6621
6874
|
// src/video/pano-video-chrome-bridge.tsx
|
|
6622
|
-
import { Fragment as Fragment2, jsx as
|
|
6875
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
6623
6876
|
function PanoVideoChromeBridge({
|
|
6624
6877
|
fullscreen,
|
|
6625
6878
|
host,
|
|
@@ -6635,7 +6888,7 @@ function PanoVideoChromeBridge({
|
|
|
6635
6888
|
}
|
|
6636
6889
|
const showDefaultControls = host.controller !== null && host.controls !== false && host.controlClaims === 0;
|
|
6637
6890
|
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
6638
|
-
showDefaultControls ? /* @__PURE__ */
|
|
6891
|
+
showDefaultControls ? /* @__PURE__ */ jsx9(
|
|
6639
6892
|
PanoVideoControlsHud,
|
|
6640
6893
|
{
|
|
6641
6894
|
appearance: typeof host.controls === "object" ? host.controls : void 0,
|
|
@@ -6644,7 +6897,7 @@ function PanoVideoChromeBridge({
|
|
|
6644
6897
|
overlayElement
|
|
6645
6898
|
}
|
|
6646
6899
|
) : null,
|
|
6647
|
-
host.captions !== false && host.controller ? /* @__PURE__ */
|
|
6900
|
+
host.captions !== false && host.controller ? /* @__PURE__ */ jsx9(PanoVideoCaptionsOverlay, { controller: host.controller }) : null
|
|
6648
6901
|
] });
|
|
6649
6902
|
}
|
|
6650
6903
|
|
|
@@ -6652,8 +6905,8 @@ function PanoVideoChromeBridge({
|
|
|
6652
6905
|
import { useSyncExternalStore as useSyncExternalStore5 } from "react";
|
|
6653
6906
|
|
|
6654
6907
|
// src/webvr/host.ts
|
|
6655
|
-
import { createContext as
|
|
6656
|
-
var WebVRRuntimeContext =
|
|
6908
|
+
import { createContext as createContext15 } from "react";
|
|
6909
|
+
var WebVRRuntimeContext = createContext15(null);
|
|
6657
6910
|
function createWebVRHost() {
|
|
6658
6911
|
return {
|
|
6659
6912
|
controller: null,
|
|
@@ -6797,7 +7050,7 @@ function clamp2(value, min, max) {
|
|
|
6797
7050
|
}
|
|
6798
7051
|
|
|
6799
7052
|
// src/webvr/chrome.tsx
|
|
6800
|
-
import { Fragment as Fragment3, jsx as
|
|
7053
|
+
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
6801
7054
|
function resolveAppearance(value) {
|
|
6802
7055
|
return {
|
|
6803
7056
|
...DEFAULT_WEBVR_CHROME_APPEARANCE,
|
|
@@ -6809,7 +7062,7 @@ function ChromeButton2({
|
|
|
6809
7062
|
children,
|
|
6810
7063
|
onClick
|
|
6811
7064
|
}) {
|
|
6812
|
-
return /* @__PURE__ */
|
|
7065
|
+
return /* @__PURE__ */ jsx10(
|
|
6813
7066
|
"button",
|
|
6814
7067
|
{
|
|
6815
7068
|
className: "pano-webvr-button",
|
|
@@ -6854,11 +7107,11 @@ function SetupPanel({
|
|
|
6854
7107
|
role: "dialog",
|
|
6855
7108
|
style: panelStyle,
|
|
6856
7109
|
children: [
|
|
6857
|
-
/* @__PURE__ */
|
|
7110
|
+
/* @__PURE__ */ jsx10("h2", { className: "pano-webvr-setup-title", children: appearance.setupTitle ?? "MobileVR Setup" }),
|
|
6858
7111
|
/* @__PURE__ */ jsxs5("label", { className: "pano-webvr-setup-field", children: [
|
|
6859
7112
|
"Screen size (inch)",
|
|
6860
7113
|
/* @__PURE__ */ jsxs5("div", { className: "pano-webvr-setup-row", children: [
|
|
6861
|
-
/* @__PURE__ */
|
|
7114
|
+
/* @__PURE__ */ jsx10(
|
|
6862
7115
|
"button",
|
|
6863
7116
|
{
|
|
6864
7117
|
"aria-label": "Decrease screen size",
|
|
@@ -6870,8 +7123,8 @@ function SetupPanel({
|
|
|
6870
7123
|
children: "\u2039"
|
|
6871
7124
|
}
|
|
6872
7125
|
),
|
|
6873
|
-
/* @__PURE__ */
|
|
6874
|
-
/* @__PURE__ */
|
|
7126
|
+
/* @__PURE__ */ jsx10("strong", { className: "pano-webvr-setup-value", children: settings.screensize === "auto" ? "Auto" : settings.screensize.toFixed(1) }),
|
|
7127
|
+
/* @__PURE__ */ jsx10(
|
|
6875
7128
|
"button",
|
|
6876
7129
|
{
|
|
6877
7130
|
"aria-label": "Increase screen size",
|
|
@@ -6886,9 +7139,9 @@ function SetupPanel({
|
|
|
6886
7139
|
] })
|
|
6887
7140
|
] }),
|
|
6888
7141
|
/* @__PURE__ */ jsxs5("fieldset", { className: "pano-webvr-setup-fieldset", children: [
|
|
6889
|
-
/* @__PURE__ */
|
|
7142
|
+
/* @__PURE__ */ jsx10("legend", { className: "pano-webvr-setup-legend", children: "VR headset preset" }),
|
|
6890
7143
|
/* @__PURE__ */ jsxs5("div", { className: "pano-webvr-setup-row", children: [
|
|
6891
|
-
/* @__PURE__ */
|
|
7144
|
+
/* @__PURE__ */ jsx10(
|
|
6892
7145
|
"button",
|
|
6893
7146
|
{
|
|
6894
7147
|
"aria-label": "Previous headset preset",
|
|
@@ -6898,8 +7151,8 @@ function SetupPanel({
|
|
|
6898
7151
|
children: "\u2039"
|
|
6899
7152
|
}
|
|
6900
7153
|
),
|
|
6901
|
-
/* @__PURE__ */
|
|
6902
|
-
/* @__PURE__ */
|
|
7154
|
+
/* @__PURE__ */ jsx10("strong", { className: "pano-webvr-setup-value-wide", children: WEBVR_PROFILES[settings.profileId].label }),
|
|
7155
|
+
/* @__PURE__ */ jsx10(
|
|
6903
7156
|
"button",
|
|
6904
7157
|
{
|
|
6905
7158
|
"aria-label": "Next headset preset",
|
|
@@ -6911,7 +7164,7 @@ function SetupPanel({
|
|
|
6911
7164
|
)
|
|
6912
7165
|
] })
|
|
6913
7166
|
] }),
|
|
6914
|
-
/* @__PURE__ */
|
|
7167
|
+
/* @__PURE__ */ jsx10(
|
|
6915
7168
|
ChromeButton2,
|
|
6916
7169
|
{
|
|
6917
7170
|
appearance,
|
|
@@ -6935,8 +7188,8 @@ function WebVRChromeBridge({ host }) {
|
|
|
6935
7188
|
}
|
|
6936
7189
|
const appearance = resolveAppearance(chrome);
|
|
6937
7190
|
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
6938
|
-
/* @__PURE__ */
|
|
6939
|
-
mode !== "webxr" ? /* @__PURE__ */
|
|
7191
|
+
/* @__PURE__ */ jsx10("div", { className: "pano-webvr-toolbar", children: mode ? /* @__PURE__ */ jsxs5("div", { className: "pano-webvr-toolbar-actions", children: [
|
|
7192
|
+
mode !== "webxr" ? /* @__PURE__ */ jsx10(
|
|
6940
7193
|
ChromeButton2,
|
|
6941
7194
|
{
|
|
6942
7195
|
appearance,
|
|
@@ -6944,7 +7197,7 @@ function WebVRChromeBridge({ host }) {
|
|
|
6944
7197
|
children: "VR Setup"
|
|
6945
7198
|
}
|
|
6946
7199
|
) : null,
|
|
6947
|
-
/* @__PURE__ */
|
|
7200
|
+
/* @__PURE__ */ jsx10(
|
|
6948
7201
|
ChromeButton2,
|
|
6949
7202
|
{
|
|
6950
7203
|
appearance,
|
|
@@ -6952,7 +7205,7 @@ function WebVRChromeBridge({ host }) {
|
|
|
6952
7205
|
children: "Exit VR"
|
|
6953
7206
|
}
|
|
6954
7207
|
)
|
|
6955
|
-
] }) : /* @__PURE__ */
|
|
7208
|
+
] }) : /* @__PURE__ */ jsx10(
|
|
6956
7209
|
ChromeButton2,
|
|
6957
7210
|
{
|
|
6958
7211
|
appearance,
|
|
@@ -6960,7 +7213,7 @@ function WebVRChromeBridge({ host }) {
|
|
|
6960
7213
|
children: available ? "Enter VR" : "VR unavailable"
|
|
6961
7214
|
}
|
|
6962
7215
|
) }),
|
|
6963
|
-
mode === "fake" ? /* @__PURE__ */
|
|
7216
|
+
mode === "fake" ? /* @__PURE__ */ jsx10(
|
|
6964
7217
|
"p",
|
|
6965
7218
|
{
|
|
6966
7219
|
className: "pano-webvr-hint",
|
|
@@ -6968,7 +7221,7 @@ function WebVRChromeBridge({ host }) {
|
|
|
6968
7221
|
children: "Simulated VR Mode \xB7 Click the view to lock the mouse, then move to look around. Use a headset or phone for real VR."
|
|
6969
7222
|
}
|
|
6970
7223
|
) : null,
|
|
6971
|
-
setupOpen ? /* @__PURE__ */
|
|
7224
|
+
setupOpen ? /* @__PURE__ */ jsx10(
|
|
6972
7225
|
SetupPanel,
|
|
6973
7226
|
{
|
|
6974
7227
|
appearance,
|
|
@@ -7010,7 +7263,7 @@ import { useFrame as useFrame5, useThree as useThree8 } from "@react-three/fiber
|
|
|
7010
7263
|
import { useXR as useXR2, XROrigin } from "@react-three/xr";
|
|
7011
7264
|
import { useRef as useRef12 } from "react";
|
|
7012
7265
|
import { Vector3 as Vector34 } from "three";
|
|
7013
|
-
import { jsx as
|
|
7266
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
7014
7267
|
function PanoramaXROrigin() {
|
|
7015
7268
|
const originRef = useRef12(null);
|
|
7016
7269
|
const localHeadPositionRef = useRef12(new Vector34());
|
|
@@ -7026,11 +7279,11 @@ function PanoramaXROrigin() {
|
|
|
7026
7279
|
origin.position.copy(localHeadPositionRef.current).multiplyScalar(-1);
|
|
7027
7280
|
origin.updateMatrixWorld();
|
|
7028
7281
|
}, -100);
|
|
7029
|
-
return /* @__PURE__ */
|
|
7282
|
+
return /* @__PURE__ */ jsx11(XROrigin, { ref: originRef });
|
|
7030
7283
|
}
|
|
7031
7284
|
|
|
7032
7285
|
// src/pano-viewer.tsx
|
|
7033
|
-
import { jsx as
|
|
7286
|
+
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
7034
7287
|
var DEFAULT_VIEW = {
|
|
7035
7288
|
yaw: 0,
|
|
7036
7289
|
pitch: 0,
|
|
@@ -7075,10 +7328,10 @@ function PanoCursorTree({
|
|
|
7075
7328
|
if (!cursors) {
|
|
7076
7329
|
return children;
|
|
7077
7330
|
}
|
|
7078
|
-
return /* @__PURE__ */
|
|
7331
|
+
return /* @__PURE__ */ jsx12(PanoCursorController, { cursors, children });
|
|
7079
7332
|
}
|
|
7080
7333
|
function PanoVideoHostReset() {
|
|
7081
|
-
const host =
|
|
7334
|
+
const host = useContext16(PanoVideoHostContext);
|
|
7082
7335
|
if (host) {
|
|
7083
7336
|
host.controlClaims = 0;
|
|
7084
7337
|
}
|
|
@@ -7091,14 +7344,14 @@ function DefaultControlChannels({
|
|
|
7091
7344
|
keyboardChannel,
|
|
7092
7345
|
fovSpeed
|
|
7093
7346
|
}) {
|
|
7094
|
-
const claims =
|
|
7347
|
+
const claims = useContext16(ControlClaimsContext);
|
|
7095
7348
|
if (!claims) {
|
|
7096
7349
|
return null;
|
|
7097
7350
|
}
|
|
7098
7351
|
return /* @__PURE__ */ jsxs6(DefaultControlChannelContext.Provider, { value: true, children: [
|
|
7099
|
-
userControlsEnabled && mouseChannel.mount && claims.mouse === 0 ? /* @__PURE__ */
|
|
7100
|
-
userControlsEnabled && touchChannel.mount && claims.touch === 0 ? /* @__PURE__ */
|
|
7101
|
-
userControlsEnabled && keyboardChannel.mount && claims.keyboard === 0 ? /* @__PURE__ */
|
|
7352
|
+
userControlsEnabled && mouseChannel.mount && claims.mouse === 0 ? /* @__PURE__ */ jsx12(MouseControls, { ...mouseChannel.props, fovSpeed }) : null,
|
|
7353
|
+
userControlsEnabled && touchChannel.mount && claims.touch === 0 ? /* @__PURE__ */ jsx12(TouchControls, { ...touchChannel.props }) : null,
|
|
7354
|
+
userControlsEnabled && keyboardChannel.mount && claims.keyboard === 0 ? /* @__PURE__ */ jsx12(
|
|
7102
7355
|
KeyboardControls,
|
|
7103
7356
|
{
|
|
7104
7357
|
...keyboardChannel.props,
|
|
@@ -7110,7 +7363,9 @@ function DefaultControlChannels({
|
|
|
7110
7363
|
var PanoViewer = forwardRef2(
|
|
7111
7364
|
function PanoViewer2({
|
|
7112
7365
|
children,
|
|
7366
|
+
renderOverlay,
|
|
7113
7367
|
initialView,
|
|
7368
|
+
viewLimits,
|
|
7114
7369
|
minFov = 30,
|
|
7115
7370
|
maxFov = 100,
|
|
7116
7371
|
controls = true,
|
|
@@ -7128,18 +7383,24 @@ var PanoViewer = forwardRef2(
|
|
|
7128
7383
|
}, ref) {
|
|
7129
7384
|
const rootRef = useRef13(null);
|
|
7130
7385
|
const controlsRef = useRef13(null);
|
|
7131
|
-
const
|
|
7386
|
+
const modalHost = useMemo8(() => createPanoModalHost(), []);
|
|
7387
|
+
const modalOpen = useSyncExternalStore6(modalHost.subscribe, modalHost.getSnapshot, () => false);
|
|
7388
|
+
const setControlsRuntime = useCallback6((runtime) => {
|
|
7389
|
+
controlsRef.current = runtime;
|
|
7390
|
+
modalHost.connect(runtime);
|
|
7391
|
+
}, [modalHost]);
|
|
7392
|
+
const eventBus = useMemo8(() => createPanoEventBus(), []);
|
|
7132
7393
|
const { controls: hotspotAccessibilityControls, registry } = useHotspotAccessibilityLayer();
|
|
7133
|
-
const hotspotTargetRegistry =
|
|
7394
|
+
const hotspotTargetRegistry = useMemo8(() => createHotspotTargetRegistry(), []);
|
|
7134
7395
|
const { api: contextMenuOverlayApi, overlay: contextMenuOverlay } = usePanoContextMenuOverlay();
|
|
7135
7396
|
const { api: chromeOverlayApi, setOverlayNode, overlayElement } = usePanoChromeOverlay();
|
|
7136
|
-
const videoHost =
|
|
7137
|
-
const filterHost =
|
|
7138
|
-
const webVRHost =
|
|
7139
|
-
const scenesHost =
|
|
7140
|
-
const bgmHost =
|
|
7141
|
-
const mediaActivationHost =
|
|
7142
|
-
const mediaActivationOptions =
|
|
7397
|
+
const videoHost = useMemo8(() => createPanoVideoHost(), []);
|
|
7398
|
+
const filterHost = useMemo8(() => createPanoFilterHost(), []);
|
|
7399
|
+
const webVRHost = useMemo8(() => createWebVRHost(), []);
|
|
7400
|
+
const scenesHost = useMemo8(() => createScenesHost(), []);
|
|
7401
|
+
const bgmHost = useMemo8(() => createBackgroundAudioHost(), []);
|
|
7402
|
+
const mediaActivationHost = useMemo8(() => createPanoMediaActivationHost(), []);
|
|
7403
|
+
const mediaActivationOptions = useMemo8(
|
|
7143
7404
|
() => mediaActivation === false ? null : mediaActivation ?? {},
|
|
7144
7405
|
[mediaActivation]
|
|
7145
7406
|
);
|
|
@@ -7148,9 +7409,9 @@ var PanoViewer = forwardRef2(
|
|
|
7148
7409
|
() => getPanoMediaActivationRevision(mediaActivationHost),
|
|
7149
7410
|
() => getPanoMediaActivationRevision(mediaActivationHost)
|
|
7150
7411
|
);
|
|
7151
|
-
const [mediaActivated, setMediaActivated] =
|
|
7152
|
-
const stereoView =
|
|
7153
|
-
const xrStore =
|
|
7412
|
+
const [mediaActivated, setMediaActivated] = useState6(false);
|
|
7413
|
+
const stereoView = useMemo8(() => createWebVRStereoView(), []);
|
|
7414
|
+
const xrStore = useMemo8(
|
|
7154
7415
|
() => createXRStore({
|
|
7155
7416
|
anchors: false,
|
|
7156
7417
|
bodyTracking: false,
|
|
@@ -7166,7 +7427,7 @@ var PanoViewer = forwardRef2(
|
|
|
7166
7427
|
}),
|
|
7167
7428
|
[]
|
|
7168
7429
|
);
|
|
7169
|
-
const mediaActivationControls =
|
|
7430
|
+
const mediaActivationControls = useMemo8(
|
|
7170
7431
|
() => ({
|
|
7171
7432
|
resumeAudio: () => resumePanoAudio(),
|
|
7172
7433
|
playVideo: async ({ unmute = false } = {}) => {
|
|
@@ -7269,34 +7530,33 @@ var PanoViewer = forwardRef2(
|
|
|
7269
7530
|
shouldActivateMedia,
|
|
7270
7531
|
videoHost
|
|
7271
7532
|
]);
|
|
7533
|
+
const limitsKey = JSON.stringify(viewLimits);
|
|
7534
|
+
const parsedLimits = useMemo8(() => parseViewLimits(viewLimits), [limitsKey]);
|
|
7272
7535
|
const fallbackViewRef = useRef13(DEFAULT_VIEW);
|
|
7273
7536
|
const normalizedMinFov = Math.max(1, Math.min(minFov, maxFov - 1));
|
|
7274
7537
|
const normalizedMaxFov = Math.min(
|
|
7275
7538
|
179,
|
|
7276
7539
|
Math.max(maxFov, normalizedMinFov + 1)
|
|
7277
7540
|
);
|
|
7278
|
-
const normalizedInitialView =
|
|
7541
|
+
const normalizedInitialView = useMemo8(
|
|
7279
7542
|
() => ({
|
|
7280
7543
|
yaw: initialView?.yaw ?? DEFAULT_VIEW.yaw,
|
|
7281
7544
|
pitch: clampPanoPitch(initialView?.pitch ?? DEFAULT_VIEW.pitch),
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
)
|
|
7545
|
+
// The runtime applies the effective scene/viewer range, including FOVs
|
|
7546
|
+
// outside the legacy minFov/maxFov defaults.
|
|
7547
|
+
fov: initialView?.fov ?? DEFAULT_VIEW.fov
|
|
7286
7548
|
}),
|
|
7287
7549
|
[
|
|
7288
7550
|
initialView?.fov,
|
|
7289
7551
|
initialView?.pitch,
|
|
7290
|
-
initialView?.yaw
|
|
7291
|
-
normalizedMaxFov,
|
|
7292
|
-
normalizedMinFov
|
|
7552
|
+
initialView?.yaw
|
|
7293
7553
|
]
|
|
7294
7554
|
);
|
|
7295
7555
|
fallbackViewRef.current = normalizedInitialView;
|
|
7296
|
-
const controlClaims =
|
|
7556
|
+
const controlClaims = useMemo8(() => createControlClaims(), []);
|
|
7297
7557
|
resetControlClaims(controlClaims);
|
|
7298
7558
|
const controlsEnabled = controls !== false;
|
|
7299
|
-
const controlOptions =
|
|
7559
|
+
const controlOptions = useMemo8(
|
|
7300
7560
|
() => typeof controls === "object" ? controls : {},
|
|
7301
7561
|
[controls]
|
|
7302
7562
|
);
|
|
@@ -7304,7 +7564,7 @@ var PanoViewer = forwardRef2(
|
|
|
7304
7564
|
const allModeInvert = controlOptions.invert === true;
|
|
7305
7565
|
const topRotateSpeed = controlOptions.rotateSpeed ?? DEFAULT_POINTER_ROTATE_SPEED;
|
|
7306
7566
|
const topZoomSpeed = controlOptions.zoomSpeed ?? DEFAULT_MOUSE_ZOOM_SPEED;
|
|
7307
|
-
const mouseChannel =
|
|
7567
|
+
const mouseChannel = useMemo8(
|
|
7308
7568
|
() => resolveChannel(controlOptions.mouse, {
|
|
7309
7569
|
enabled: true,
|
|
7310
7570
|
rotateSpeed: topRotateSpeed,
|
|
@@ -7320,7 +7580,7 @@ var PanoViewer = forwardRef2(
|
|
|
7320
7580
|
topZoomSpeed
|
|
7321
7581
|
]
|
|
7322
7582
|
);
|
|
7323
|
-
const touchChannel =
|
|
7583
|
+
const touchChannel = useMemo8(
|
|
7324
7584
|
() => resolveChannel(controlOptions.touch, {
|
|
7325
7585
|
enabled: true,
|
|
7326
7586
|
rotateSpeed: topRotateSpeed,
|
|
@@ -7329,7 +7589,7 @@ var PanoViewer = forwardRef2(
|
|
|
7329
7589
|
}),
|
|
7330
7590
|
[allModeInvert, controlOptions.touch, topRotateSpeed]
|
|
7331
7591
|
);
|
|
7332
|
-
const keyboardChannel =
|
|
7592
|
+
const keyboardChannel = useMemo8(
|
|
7333
7593
|
() => resolveChannel(controlOptions.keyboard, {
|
|
7334
7594
|
enabled: true
|
|
7335
7595
|
}),
|
|
@@ -7371,7 +7631,11 @@ var PanoViewer = forwardRef2(
|
|
|
7371
7631
|
}
|
|
7372
7632
|
await requestElementFullscreen(root);
|
|
7373
7633
|
}, []);
|
|
7374
|
-
const [isViewerFullscreen, setIsViewerFullscreen] =
|
|
7634
|
+
const [isViewerFullscreen, setIsViewerFullscreen] = useState6(false);
|
|
7635
|
+
const { context: overlayContext, setPortalContainer } = usePanoOverlayHost(isViewerFullscreen);
|
|
7636
|
+
useEffect13(() => {
|
|
7637
|
+
if (modalOpen) contextMenuOverlayApi.setSession(null);
|
|
7638
|
+
}, [contextMenuOverlayApi, modalOpen]);
|
|
7375
7639
|
useEffect13(() => {
|
|
7376
7640
|
if (typeof document === "undefined") {
|
|
7377
7641
|
return;
|
|
@@ -7403,7 +7667,7 @@ var PanoViewer = forwardRef2(
|
|
|
7403
7667
|
root.removeEventListener("contextmenu", suppressNativeContextMenu, true);
|
|
7404
7668
|
};
|
|
7405
7669
|
}, []);
|
|
7406
|
-
const contextMenuActions =
|
|
7670
|
+
const contextMenuActions = useMemo8(
|
|
7407
7671
|
() => ({
|
|
7408
7672
|
reset: () => {
|
|
7409
7673
|
controlsRef.current?.reset();
|
|
@@ -7415,16 +7679,16 @@ var PanoViewer = forwardRef2(
|
|
|
7415
7679
|
}),
|
|
7416
7680
|
[isViewerFullscreen, toggleFullscreen]
|
|
7417
7681
|
);
|
|
7418
|
-
const contextMenuChannel =
|
|
7682
|
+
const contextMenuChannel = useMemo8(
|
|
7419
7683
|
() => resolveContextMenuChannel(contextMenu),
|
|
7420
7684
|
[contextMenu]
|
|
7421
7685
|
);
|
|
7422
|
-
const resolvedCursors =
|
|
7686
|
+
const resolvedCursors = useMemo8(
|
|
7423
7687
|
() => resolvePanoCursors(cursors),
|
|
7424
7688
|
[cursors]
|
|
7425
7689
|
);
|
|
7426
7690
|
const legacyAutoRotateOptions = controlOptions;
|
|
7427
|
-
const [legacyAutoRotate, setLegacyAutoRotate] =
|
|
7691
|
+
const [legacyAutoRotate, setLegacyAutoRotate] = useState6(
|
|
7428
7692
|
legacyAutoRotateOptions.autoRotate ?? false
|
|
7429
7693
|
);
|
|
7430
7694
|
useEffect13(() => {
|
|
@@ -7513,7 +7777,7 @@ var PanoViewer = forwardRef2(
|
|
|
7513
7777
|
webVRHost
|
|
7514
7778
|
]
|
|
7515
7779
|
);
|
|
7516
|
-
const rootStyle =
|
|
7780
|
+
const rootStyle = useMemo8(
|
|
7517
7781
|
() => ({
|
|
7518
7782
|
overflow: "hidden",
|
|
7519
7783
|
position: "relative",
|
|
@@ -7531,118 +7795,130 @@ var PanoViewer = forwardRef2(
|
|
|
7531
7795
|
"aria-label": ariaLabel,
|
|
7532
7796
|
style: rootStyle,
|
|
7533
7797
|
children: [
|
|
7534
|
-
/* @__PURE__ */
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
/* @__PURE__ */
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
ref: controlsRef,
|
|
7577
|
-
eventBus,
|
|
7578
|
-
initialView: normalizedInitialView,
|
|
7579
|
-
maxFov: normalizedMaxFov,
|
|
7580
|
-
minFov: normalizedMinFov,
|
|
7581
|
-
options: controlOptions
|
|
7582
|
-
}
|
|
7583
|
-
),
|
|
7584
|
-
(onViewChange || onPanoramaClick || onPanoramaDoubleClick || onPanoramaPointerMove) && /* @__PURE__ */ jsx11(
|
|
7585
|
-
PanoEvents,
|
|
7586
|
-
{
|
|
7587
|
-
onViewChange,
|
|
7588
|
-
onClick: onPanoramaClick,
|
|
7589
|
-
onDoubleClick: onPanoramaDoubleClick,
|
|
7590
|
-
onPointerMove: onPanoramaPointerMove
|
|
7591
|
-
}
|
|
7592
|
-
),
|
|
7593
|
-
/* @__PURE__ */ jsx11(
|
|
7594
|
-
AutoRotate,
|
|
7595
|
-
{
|
|
7596
|
-
enabled: legacyAutoRotate,
|
|
7597
|
-
speed: legacyAutoRotateOptions.autoRotateSpeed
|
|
7598
|
-
}
|
|
7599
|
-
),
|
|
7600
|
-
/* @__PURE__ */ jsx11(PanoramaEventSurface, {}),
|
|
7601
|
-
contextMenuChannel.mount ? /* @__PURE__ */ jsx11(PanoContextMenu, { ...contextMenuChannel.props }) : null,
|
|
7602
|
-
/* @__PURE__ */ jsxs6(ControlClaimsContext.Provider, { value: controlClaims, children: [
|
|
7603
|
-
children,
|
|
7604
|
-
/* @__PURE__ */ jsx11(
|
|
7605
|
-
DefaultControlChannels,
|
|
7798
|
+
/* @__PURE__ */ jsxs6("div", { "data-pano-background": "", inert: modalOpen, style: { position: "absolute", inset: 0 }, children: [
|
|
7799
|
+
/* @__PURE__ */ jsx12(
|
|
7800
|
+
Canvas,
|
|
7801
|
+
{
|
|
7802
|
+
"aria-label": `${ariaLabel} canvas`,
|
|
7803
|
+
resize: { debounce: 0 },
|
|
7804
|
+
camera: {
|
|
7805
|
+
far: DEFAULT_PANORAMA_CAMERA_FAR,
|
|
7806
|
+
fov: normalizedInitialView.fov,
|
|
7807
|
+
near: DEFAULT_PANORAMA_CAMERA_NEAR,
|
|
7808
|
+
position: [0, 0, 0.01]
|
|
7809
|
+
},
|
|
7810
|
+
dpr,
|
|
7811
|
+
gl: {
|
|
7812
|
+
// Hotspots contain transparent textures and curved outlines. Keep
|
|
7813
|
+
// the canvas multisampled so their visible edges are smoothed.
|
|
7814
|
+
antialias: true,
|
|
7815
|
+
powerPreference: "high-performance",
|
|
7816
|
+
stencil: false
|
|
7817
|
+
},
|
|
7818
|
+
style: {
|
|
7819
|
+
...DEFAULT_CANVAS_STYLE,
|
|
7820
|
+
touchAction: userControlsEnabled ? "none" : "auto"
|
|
7821
|
+
},
|
|
7822
|
+
children: /* @__PURE__ */ jsx12(XR, { store: xrStore, children: /* @__PURE__ */ jsxs6(
|
|
7823
|
+
WebVRRuntimeContext.Provider,
|
|
7824
|
+
{
|
|
7825
|
+
value: { host: webVRHost, xrStore, stereoView },
|
|
7826
|
+
children: [
|
|
7827
|
+
/* @__PURE__ */ jsx12(PanoramaXROrigin, {}),
|
|
7828
|
+
/* @__PURE__ */ jsx12(HotspotAccessibilityContext.Provider, { value: registry, children: /* @__PURE__ */ jsx12(HotspotTargetRegistryContext.Provider, { value: hotspotTargetRegistry, children: /* @__PURE__ */ jsx12(PanoEventBusContext.Provider, { value: eventBus, children: /* @__PURE__ */ jsx12(PanoCursorTree, { cursors: resolvedCursors, children: /* @__PURE__ */ jsx12(PanoramaViewContext.Provider, { value: controlsRef, children: /* @__PURE__ */ jsx12(
|
|
7829
|
+
PanoContextMenuOverlayContext.Provider,
|
|
7830
|
+
{
|
|
7831
|
+
value: contextMenuOverlayApi,
|
|
7832
|
+
children: /* @__PURE__ */ jsx12(PanoChromeOverlayContext.Provider, { value: chromeOverlayApi, children: /* @__PURE__ */ jsx12(PanoVideoHostContext.Provider, { value: videoHost, children: /* @__PURE__ */ jsx12(PanoFilterHostContext.Provider, { value: filterHost, children: /* @__PURE__ */ jsx12(
|
|
7833
|
+
PanoContextMenuActionsContext.Provider,
|
|
7834
|
+
{
|
|
7835
|
+
value: contextMenuActions,
|
|
7836
|
+
children: /* @__PURE__ */ jsx12(ScenesHostContext.Provider, { value: scenesHost, children: /* @__PURE__ */ jsx12(BackgroundAudioHostContext.Provider, { value: bgmHost, children: /* @__PURE__ */ jsxs6(PanoMediaActivationHostContext.Provider, { value: mediaActivationHost, children: [
|
|
7837
|
+
/* @__PURE__ */ jsx12(PanoVideoHostReset, {}),
|
|
7838
|
+
/* @__PURE__ */ jsx12(
|
|
7839
|
+
PanoramaViewRuntime,
|
|
7606
7840
|
{
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7841
|
+
ref: setControlsRuntime,
|
|
7842
|
+
eventBus,
|
|
7843
|
+
initialView: normalizedInitialView,
|
|
7844
|
+
viewLimits: parsedLimits,
|
|
7845
|
+
maxFov: normalizedMaxFov,
|
|
7846
|
+
minFov: normalizedMinFov,
|
|
7847
|
+
options: controlOptions
|
|
7612
7848
|
}
|
|
7613
|
-
)
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7849
|
+
),
|
|
7850
|
+
(onViewChange || onPanoramaClick || onPanoramaDoubleClick || onPanoramaPointerMove) && /* @__PURE__ */ jsx12(
|
|
7851
|
+
PanoEvents,
|
|
7852
|
+
{
|
|
7853
|
+
onViewChange,
|
|
7854
|
+
onClick: onPanoramaClick,
|
|
7855
|
+
onDoubleClick: onPanoramaDoubleClick,
|
|
7856
|
+
onPointerMove: onPanoramaPointerMove
|
|
7857
|
+
}
|
|
7858
|
+
),
|
|
7859
|
+
/* @__PURE__ */ jsx12(
|
|
7860
|
+
AutoRotate,
|
|
7861
|
+
{
|
|
7862
|
+
enabled: legacyAutoRotate,
|
|
7863
|
+
speed: legacyAutoRotateOptions.autoRotateSpeed
|
|
7864
|
+
}
|
|
7865
|
+
),
|
|
7866
|
+
/* @__PURE__ */ jsx12(PanoramaEventSurface, {}),
|
|
7867
|
+
contextMenuChannel.mount ? /* @__PURE__ */ jsx12(PanoContextMenu, { ...contextMenuChannel.props }) : null,
|
|
7868
|
+
/* @__PURE__ */ jsxs6(ControlClaimsContext.Provider, { value: controlClaims, children: [
|
|
7869
|
+
children,
|
|
7870
|
+
/* @__PURE__ */ jsx12(
|
|
7871
|
+
DefaultControlChannels,
|
|
7872
|
+
{
|
|
7873
|
+
fovSpeed: controlOptions.fovSpeed,
|
|
7874
|
+
keyboardChannel,
|
|
7875
|
+
mouseChannel,
|
|
7876
|
+
touchChannel,
|
|
7877
|
+
userControlsEnabled
|
|
7878
|
+
}
|
|
7879
|
+
)
|
|
7880
|
+
] })
|
|
7881
|
+
] }) }) })
|
|
7882
|
+
}
|
|
7883
|
+
) }) }) })
|
|
7884
|
+
}
|
|
7885
|
+
) }) }) }) }) })
|
|
7886
|
+
]
|
|
7887
|
+
}
|
|
7888
|
+
) })
|
|
7889
|
+
}
|
|
7890
|
+
),
|
|
7891
|
+
/* @__PURE__ */ jsxs6(
|
|
7892
|
+
"div",
|
|
7893
|
+
{
|
|
7894
|
+
className: "pano-chrome-overlay",
|
|
7895
|
+
"data-pano-chrome-overlay": "",
|
|
7896
|
+
ref: setOverlayNode,
|
|
7897
|
+
children: [
|
|
7898
|
+
/* @__PURE__ */ jsx12(
|
|
7899
|
+
PanoVideoChromeBridge,
|
|
7900
|
+
{
|
|
7901
|
+
fullscreen: contextMenuActions,
|
|
7902
|
+
host: videoHost,
|
|
7903
|
+
overlayElement
|
|
7904
|
+
}
|
|
7905
|
+
),
|
|
7906
|
+
/* @__PURE__ */ jsx12(WebVRChromeBridge, { host: webVRHost })
|
|
7907
|
+
]
|
|
7908
|
+
}
|
|
7909
|
+
),
|
|
7910
|
+
contextMenuOverlay,
|
|
7911
|
+
hotspotAccessibilityControls
|
|
7912
|
+
] }),
|
|
7913
|
+
/* @__PURE__ */ jsx12(PanoModalHostContext.Provider, { value: modalHost, children: /* @__PURE__ */ jsx12(PanoOverlayContext.Provider, { value: overlayContext, children: /* @__PURE__ */ jsx12(
|
|
7626
7914
|
"div",
|
|
7627
7915
|
{
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
children:
|
|
7632
|
-
/* @__PURE__ */ jsx11(
|
|
7633
|
-
PanoVideoChromeBridge,
|
|
7634
|
-
{
|
|
7635
|
-
fullscreen: contextMenuActions,
|
|
7636
|
-
host: videoHost,
|
|
7637
|
-
overlayElement
|
|
7638
|
-
}
|
|
7639
|
-
),
|
|
7640
|
-
/* @__PURE__ */ jsx11(WebVRChromeBridge, { host: webVRHost })
|
|
7641
|
-
]
|
|
7916
|
+
"data-pano-overlay": "",
|
|
7917
|
+
ref: setPortalContainer,
|
|
7918
|
+
style: { position: "absolute", inset: 0, zIndex: 30, pointerEvents: "none" },
|
|
7919
|
+
children: renderOverlay?.(overlayContext)
|
|
7642
7920
|
}
|
|
7643
|
-
)
|
|
7644
|
-
contextMenuOverlay,
|
|
7645
|
-
hotspotAccessibilityControls
|
|
7921
|
+
) }) })
|
|
7646
7922
|
]
|
|
7647
7923
|
}
|
|
7648
7924
|
);
|
|
@@ -7652,11 +7928,93 @@ var PanoViewer = forwardRef2(
|
|
|
7652
7928
|
// src/index.ts
|
|
7653
7929
|
export * from "./data.mjs";
|
|
7654
7930
|
|
|
7931
|
+
// src/asset-url.ts
|
|
7932
|
+
function isAbsoluteAssetUrl(url) {
|
|
7933
|
+
return url.startsWith("/") || url.startsWith("//") || /^[a-z][a-z0-9+.-]*:/i.test(url);
|
|
7934
|
+
}
|
|
7935
|
+
function resolveRelativeAssetUrl(baseUrl, relativePath) {
|
|
7936
|
+
const normalizedBaseUrl = baseUrl.replace(/\/+$/, "");
|
|
7937
|
+
const normalizedPath = relativePath.replace(/^\/+/, "");
|
|
7938
|
+
return normalizedBaseUrl ? `${normalizedBaseUrl}/${normalizedPath}` : normalizedPath;
|
|
7939
|
+
}
|
|
7940
|
+
function resolveAssetUrl(baseUrl, path) {
|
|
7941
|
+
return isAbsoluteAssetUrl(path) ? path : resolveRelativeAssetUrl(baseUrl, path);
|
|
7942
|
+
}
|
|
7943
|
+
function resolveUrlAgainstFile(fileUrl, path) {
|
|
7944
|
+
if (isAbsoluteAssetUrl(path)) {
|
|
7945
|
+
return path;
|
|
7946
|
+
}
|
|
7947
|
+
const slash = fileUrl.lastIndexOf("/");
|
|
7948
|
+
const directory = slash === -1 ? "" : fileUrl.slice(0, slash);
|
|
7949
|
+
return resolveRelativeAssetUrl(directory, path);
|
|
7950
|
+
}
|
|
7951
|
+
|
|
7952
|
+
// src/tile/multires.ts
|
|
7953
|
+
function positiveInteger(value, name) {
|
|
7954
|
+
if (!Number.isFinite(value) || value <= 0 || !Number.isInteger(value)) {
|
|
7955
|
+
throw new Error(`${name} must be a positive integer, received ${String(value)}`);
|
|
7956
|
+
}
|
|
7957
|
+
return value;
|
|
7958
|
+
}
|
|
7959
|
+
function ascendingLevels(levels) {
|
|
7960
|
+
for (let index = 1; index < levels.length; index += 1) {
|
|
7961
|
+
if (levels[index] <= levels[index - 1]) {
|
|
7962
|
+
throw new Error("multires face sizes must be strictly ascending");
|
|
7963
|
+
}
|
|
7964
|
+
}
|
|
7965
|
+
return levels;
|
|
7966
|
+
}
|
|
7967
|
+
function parseMultires(multires) {
|
|
7968
|
+
if (typeof multires !== "string") {
|
|
7969
|
+
const tileSize2 = positiveInteger(multires.tileSize, "multires.tileSize");
|
|
7970
|
+
if (multires.levels.length === 0) {
|
|
7971
|
+
throw new Error("multires.levels must contain at least one face size");
|
|
7972
|
+
}
|
|
7973
|
+
const levels2 = ascendingLevels(
|
|
7974
|
+
multires.levels.map(
|
|
7975
|
+
(level, index) => positiveInteger(level, `multires.levels[${index}]`)
|
|
7976
|
+
)
|
|
7977
|
+
);
|
|
7978
|
+
return { tileSize: tileSize2, levels: levels2 };
|
|
7979
|
+
}
|
|
7980
|
+
const values = multires.split(",").map((part) => Number(part.trim()));
|
|
7981
|
+
if (values.length < 2 || values.some((value) => !Number.isFinite(value))) {
|
|
7982
|
+
throw new Error(
|
|
7983
|
+
"multires must contain a tile size followed by at least one face size"
|
|
7984
|
+
);
|
|
7985
|
+
}
|
|
7986
|
+
const tileSize = positiveInteger(values[0], "multires tile size");
|
|
7987
|
+
const levels = ascendingLevels(
|
|
7988
|
+
values.slice(1).map(
|
|
7989
|
+
(level, index) => positiveInteger(level, `multires level ${index + 1}`)
|
|
7990
|
+
)
|
|
7991
|
+
);
|
|
7992
|
+
return { tileSize, levels };
|
|
7993
|
+
}
|
|
7994
|
+
var DEFAULT_TILE_URL_TEMPLATE = "tiles/%s/l%l/%v/l%l_%s_%h_%v.webp";
|
|
7995
|
+
function buildDefaultTileUrlTemplate() {
|
|
7996
|
+
return DEFAULT_TILE_URL_TEMPLATE;
|
|
7997
|
+
}
|
|
7998
|
+
function resolveRelativeTileUrl(baseUrl, relativePath) {
|
|
7999
|
+
return resolveAssetUrl(baseUrl, relativePath);
|
|
8000
|
+
}
|
|
8001
|
+
function resolveTemplateUrl(template, address) {
|
|
8002
|
+
return template.replace(/%s/g, address.face).replace(/%l/g, String(address.level)).replace(/%(0*)([hxucvywr])/g, (_match, zeroes, placeholder) => {
|
|
8003
|
+
const value = "hxuc".includes(placeholder) ? address.col : address.row;
|
|
8004
|
+
return String(value).padStart(zeroes.length + 1, "0");
|
|
8005
|
+
});
|
|
8006
|
+
}
|
|
8007
|
+
|
|
8008
|
+
// src/data/hotspots.ts
|
|
8009
|
+
function hotspotAction(hotspot, trigger) {
|
|
8010
|
+
return hotspot.events?.[trigger] ?? (trigger === "click" ? hotspot.action : void 0);
|
|
8011
|
+
}
|
|
8012
|
+
|
|
7655
8013
|
// src/project-scenes.tsx
|
|
7656
8014
|
import {
|
|
7657
|
-
useContext as
|
|
7658
|
-
useMemo as
|
|
7659
|
-
useState as
|
|
8015
|
+
useContext as useContext22,
|
|
8016
|
+
useMemo as useMemo22,
|
|
8017
|
+
useState as useState20
|
|
7660
8018
|
} from "react";
|
|
7661
8019
|
|
|
7662
8020
|
// src/scenes.tsx
|
|
@@ -7664,11 +8022,11 @@ import { useFrame as useFrame11, useThree as useThree16 } from "@react-three/fib
|
|
|
7664
8022
|
import {
|
|
7665
8023
|
Fragment as Fragment4,
|
|
7666
8024
|
useCallback as useCallback8,
|
|
7667
|
-
useContext as
|
|
8025
|
+
useContext as useContext19,
|
|
7668
8026
|
useEffect as useEffect22,
|
|
7669
|
-
useMemo as
|
|
8027
|
+
useMemo as useMemo17,
|
|
7670
8028
|
useRef as useRef22,
|
|
7671
|
-
useState as
|
|
8029
|
+
useState as useState11
|
|
7672
8030
|
} from "react";
|
|
7673
8031
|
import {
|
|
7674
8032
|
LinearSRGBColorSpace,
|
|
@@ -7677,10 +8035,10 @@ import {
|
|
|
7677
8035
|
} from "three";
|
|
7678
8036
|
|
|
7679
8037
|
// src/scene-detail.tsx
|
|
7680
|
-
import { createContext as
|
|
7681
|
-
var SceneDetailContext =
|
|
8038
|
+
import { createContext as createContext16, useContext as useContext17 } from "react";
|
|
8039
|
+
var SceneDetailContext = createContext16(null);
|
|
7682
8040
|
function useSceneDetailReporter() {
|
|
7683
|
-
return
|
|
8041
|
+
return useContext17(SceneDetailContext);
|
|
7684
8042
|
}
|
|
7685
8043
|
function viewTilesAreDrawable(textures) {
|
|
7686
8044
|
return textures.length > 0 && textures.every((texture) => texture != null);
|
|
@@ -7745,7 +8103,7 @@ function isSnapshotTransition(preset) {
|
|
|
7745
8103
|
|
|
7746
8104
|
// src/scene-transitions/snapshot-hold.tsx
|
|
7747
8105
|
import { useFrame as useFrame6, useThree as useThree9 } from "@react-three/fiber";
|
|
7748
|
-
import { useEffect as useEffect14, useMemo as
|
|
8106
|
+
import { useEffect as useEffect14, useMemo as useMemo9, useRef as useRef14 } from "react";
|
|
7749
8107
|
import { Vector3 as Vector36 } from "three";
|
|
7750
8108
|
|
|
7751
8109
|
// src/scene-transitions/overlay-utils.ts
|
|
@@ -8078,12 +8436,12 @@ function createSnapshotMaterial(preset, texture) {
|
|
|
8078
8436
|
}
|
|
8079
8437
|
|
|
8080
8438
|
// src/scene-transitions/snapshot-hold.tsx
|
|
8081
|
-
import { jsx as
|
|
8439
|
+
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
8082
8440
|
function SnapshotHold({ snapshot }) {
|
|
8083
8441
|
const { camera, gl } = useThree9();
|
|
8084
8442
|
const meshRef = useRef14(null);
|
|
8085
8443
|
const directionRef = useRef14(new Vector36());
|
|
8086
|
-
const material =
|
|
8444
|
+
const material = useMemo9(
|
|
8087
8445
|
() => createSnapshotMaterial("crossfade", snapshot.texture),
|
|
8088
8446
|
[snapshot.texture]
|
|
8089
8447
|
);
|
|
@@ -8102,8 +8460,8 @@ function SnapshotHold({ snapshot }) {
|
|
|
8102
8460
|
material.uniforms.progress.value = 0;
|
|
8103
8461
|
});
|
|
8104
8462
|
return /* @__PURE__ */ jsxs7("mesh", { frustumCulled: false, ref: meshRef, renderOrder: OVERLAY_RENDER_ORDER, children: [
|
|
8105
|
-
/* @__PURE__ */
|
|
8106
|
-
/* @__PURE__ */
|
|
8463
|
+
/* @__PURE__ */ jsx13("primitive", { attach: "geometry", object: FULLSCREEN_PLANE }),
|
|
8464
|
+
/* @__PURE__ */ jsx13("primitive", { attach: "material", object: material })
|
|
8107
8465
|
] });
|
|
8108
8466
|
}
|
|
8109
8467
|
|
|
@@ -8165,7 +8523,7 @@ function phaseAfterSnapshot(preset, hold) {
|
|
|
8165
8523
|
|
|
8166
8524
|
// src/scene-transitions/particle-overlay.tsx
|
|
8167
8525
|
import { useFrame as useFrame7, useThree as useThree10 } from "@react-three/fiber";
|
|
8168
|
-
import { useEffect as useEffect15, useMemo as
|
|
8526
|
+
import { useEffect as useEffect15, useMemo as useMemo10, useRef as useRef15 } from "react";
|
|
8169
8527
|
import {
|
|
8170
8528
|
DoubleSide as DoubleSide2,
|
|
8171
8529
|
InstancedBufferAttribute,
|
|
@@ -8175,7 +8533,7 @@ import {
|
|
|
8175
8533
|
Vector2 as Vector23,
|
|
8176
8534
|
Vector3 as Vector37
|
|
8177
8535
|
} from "three";
|
|
8178
|
-
import { jsx as
|
|
8536
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
8179
8537
|
var PARTICLE_GRID = 48;
|
|
8180
8538
|
var PARTICLE_COUNT = PARTICLE_GRID * PARTICLE_GRID;
|
|
8181
8539
|
var PARTICLE_VERTEX_SHADER = `
|
|
@@ -8256,8 +8614,8 @@ function ParticleOverlay({
|
|
|
8256
8614
|
const startRef = useRef15(null);
|
|
8257
8615
|
const finishedRef = useRef15(false);
|
|
8258
8616
|
const directionRef = useRef15(new Vector37());
|
|
8259
|
-
const geometry =
|
|
8260
|
-
const material =
|
|
8617
|
+
const geometry = useMemo10(() => createParticleGeometry(), []);
|
|
8618
|
+
const material = useMemo10(
|
|
8261
8619
|
() => new ShaderMaterial2({
|
|
8262
8620
|
transparent: true,
|
|
8263
8621
|
depthTest: false,
|
|
@@ -8297,7 +8655,7 @@ function ParticleOverlay({
|
|
|
8297
8655
|
onFinish();
|
|
8298
8656
|
}
|
|
8299
8657
|
});
|
|
8300
|
-
return /* @__PURE__ */
|
|
8658
|
+
return /* @__PURE__ */ jsx14(
|
|
8301
8659
|
"mesh",
|
|
8302
8660
|
{
|
|
8303
8661
|
ref: meshRef,
|
|
@@ -8311,9 +8669,9 @@ function ParticleOverlay({
|
|
|
8311
8669
|
|
|
8312
8670
|
// src/scene-transitions/snapshot-overlay.tsx
|
|
8313
8671
|
import { useFrame as useFrame8, useThree as useThree11 } from "@react-three/fiber";
|
|
8314
|
-
import { useEffect as useEffect16, useMemo as
|
|
8672
|
+
import { useEffect as useEffect16, useMemo as useMemo11, useRef as useRef16 } from "react";
|
|
8315
8673
|
import { Vector3 as Vector38 } from "three";
|
|
8316
|
-
import { jsx as
|
|
8674
|
+
import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
8317
8675
|
function SnapshotOverlay({
|
|
8318
8676
|
snapshot,
|
|
8319
8677
|
transition,
|
|
@@ -8326,7 +8684,7 @@ function SnapshotOverlay({
|
|
|
8326
8684
|
const startRef = useRef16(null);
|
|
8327
8685
|
const finishedRef = useRef16(false);
|
|
8328
8686
|
const directionRef = useRef16(new Vector38());
|
|
8329
|
-
const material =
|
|
8687
|
+
const material = useMemo11(() => {
|
|
8330
8688
|
if (!isSnapshotTransition(transition.preset)) {
|
|
8331
8689
|
return null;
|
|
8332
8690
|
}
|
|
@@ -8363,20 +8721,20 @@ function SnapshotOverlay({
|
|
|
8363
8721
|
return null;
|
|
8364
8722
|
}
|
|
8365
8723
|
return /* @__PURE__ */ jsxs8("mesh", { ref: meshRef, renderOrder: OVERLAY_RENDER_ORDER, frustumCulled: false, children: [
|
|
8366
|
-
/* @__PURE__ */
|
|
8367
|
-
/* @__PURE__ */
|
|
8724
|
+
/* @__PURE__ */ jsx15("primitive", { attach: "geometry", object: FULLSCREEN_PLANE }),
|
|
8725
|
+
/* @__PURE__ */ jsx15("primitive", { attach: "material", object: material })
|
|
8368
8726
|
] });
|
|
8369
8727
|
}
|
|
8370
8728
|
|
|
8371
8729
|
// src/scene-transitions/transition-overlay.tsx
|
|
8372
|
-
import { jsx as
|
|
8730
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
8373
8731
|
function TransitionOverlay(props) {
|
|
8374
8732
|
const { preset } = props.transition;
|
|
8375
8733
|
switch (preset) {
|
|
8376
8734
|
case "none":
|
|
8377
8735
|
return null;
|
|
8378
8736
|
case "particles":
|
|
8379
|
-
return /* @__PURE__ */
|
|
8737
|
+
return /* @__PURE__ */ jsx16(ParticleOverlay, { ...props });
|
|
8380
8738
|
case "crossfade":
|
|
8381
8739
|
case "zoom":
|
|
8382
8740
|
case "blackout":
|
|
@@ -8404,7 +8762,7 @@ function TransitionOverlay(props) {
|
|
|
8404
8762
|
case "zoomBlur":
|
|
8405
8763
|
case "hexDissolve":
|
|
8406
8764
|
case "filmBurn":
|
|
8407
|
-
return /* @__PURE__ */
|
|
8765
|
+
return /* @__PURE__ */ jsx16(SnapshotOverlay, { ...props });
|
|
8408
8766
|
default: {
|
|
8409
8767
|
const exhaustive = preset;
|
|
8410
8768
|
void exhaustive;
|
|
@@ -8415,7 +8773,7 @@ function TransitionOverlay(props) {
|
|
|
8415
8773
|
|
|
8416
8774
|
// src/sphere.tsx
|
|
8417
8775
|
import { useThree as useThree12 } from "@react-three/fiber";
|
|
8418
|
-
import { useEffect as useEffect17, useMemo as
|
|
8776
|
+
import { useEffect as useEffect17, useMemo as useMemo13, useRef as useRef18, useState as useState7 } from "react";
|
|
8419
8777
|
import {
|
|
8420
8778
|
BackSide as BackSide2,
|
|
8421
8779
|
LinearFilter,
|
|
@@ -8426,29 +8784,8 @@ import {
|
|
|
8426
8784
|
TextureLoader
|
|
8427
8785
|
} from "three";
|
|
8428
8786
|
|
|
8429
|
-
// src/asset-url.ts
|
|
8430
|
-
function isAbsoluteAssetUrl(url) {
|
|
8431
|
-
return url.startsWith("/") || url.startsWith("//") || /^[a-z][a-z0-9+.-]*:/i.test(url);
|
|
8432
|
-
}
|
|
8433
|
-
function resolveRelativeAssetUrl(baseUrl, relativePath) {
|
|
8434
|
-
const normalizedBaseUrl = baseUrl.replace(/\/+$/, "");
|
|
8435
|
-
const normalizedPath = relativePath.replace(/^\/+/, "");
|
|
8436
|
-
return normalizedBaseUrl ? `${normalizedBaseUrl}/${normalizedPath}` : normalizedPath;
|
|
8437
|
-
}
|
|
8438
|
-
function resolveAssetUrl(baseUrl, path) {
|
|
8439
|
-
return isAbsoluteAssetUrl(path) ? path : resolveRelativeAssetUrl(baseUrl, path);
|
|
8440
|
-
}
|
|
8441
|
-
function resolveUrlAgainstFile(fileUrl, path) {
|
|
8442
|
-
if (isAbsoluteAssetUrl(path)) {
|
|
8443
|
-
return path;
|
|
8444
|
-
}
|
|
8445
|
-
const slash = fileUrl.lastIndexOf("/");
|
|
8446
|
-
const directory = slash === -1 ? "" : fileUrl.slice(0, slash);
|
|
8447
|
-
return resolveRelativeAssetUrl(directory, path);
|
|
8448
|
-
}
|
|
8449
|
-
|
|
8450
8787
|
// src/pano-filter/pano-basic-material.tsx
|
|
8451
|
-
import { useLayoutEffect as
|
|
8788
|
+
import { useLayoutEffect as useLayoutEffect4, useMemo as useMemo12, useRef as useRef17 } from "react";
|
|
8452
8789
|
import {
|
|
8453
8790
|
Matrix4,
|
|
8454
8791
|
Vector4
|
|
@@ -8616,7 +8953,7 @@ function injectPanoColorMatrixShader(shader) {
|
|
|
8616
8953
|
}
|
|
8617
8954
|
|
|
8618
8955
|
// src/pano-filter/pano-basic-material.tsx
|
|
8619
|
-
import { jsx as
|
|
8956
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
8620
8957
|
function matrixUniforms(matrix) {
|
|
8621
8958
|
return {
|
|
8622
8959
|
matrix: new Matrix4().set(
|
|
@@ -8651,7 +8988,7 @@ function PanoBasicMaterial({
|
|
|
8651
8988
|
const currentRef = useRef17({ matrix, intensity: snapshot.intensity });
|
|
8652
8989
|
currentRef.current = { matrix, intensity: snapshot.intensity };
|
|
8653
8990
|
const shaderRef = useRef17(null);
|
|
8654
|
-
const onBeforeCompile =
|
|
8991
|
+
const onBeforeCompile = useMemo12(() => {
|
|
8655
8992
|
const compile = (shader) => {
|
|
8656
8993
|
shaderRef.current = shader;
|
|
8657
8994
|
if (preset !== "none") {
|
|
@@ -8671,7 +9008,7 @@ function PanoBasicMaterial({
|
|
|
8671
9008
|
compile.toString = () => `pano-filter:${preset}:matrix:${hasMatrix}`;
|
|
8672
9009
|
return compile;
|
|
8673
9010
|
}, [preset, hasMatrix]);
|
|
8674
|
-
|
|
9011
|
+
useLayoutEffect4(() => {
|
|
8675
9012
|
const shader = shaderRef.current;
|
|
8676
9013
|
if (!shader) return;
|
|
8677
9014
|
if (shader.uniforms.uPanoFilterIntensity)
|
|
@@ -8683,7 +9020,7 @@ function PanoBasicMaterial({
|
|
|
8683
9020
|
shader.uniforms.uPanoColorMatrixIntensity.value = snapshot.intensity;
|
|
8684
9021
|
}
|
|
8685
9022
|
}, [matrix, snapshot.intensity]);
|
|
8686
|
-
return /* @__PURE__ */
|
|
9023
|
+
return /* @__PURE__ */ jsx17(
|
|
8687
9024
|
"meshBasicMaterial",
|
|
8688
9025
|
{
|
|
8689
9026
|
toneMapped: false,
|
|
@@ -8695,9 +9032,9 @@ function PanoBasicMaterial({
|
|
|
8695
9032
|
}
|
|
8696
9033
|
|
|
8697
9034
|
// src/sphere.tsx
|
|
8698
|
-
import { jsx as
|
|
9035
|
+
import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
8699
9036
|
function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
8700
|
-
const [texture, setTexture] =
|
|
9037
|
+
const [texture, setTexture] = useState7(null);
|
|
8701
9038
|
const onLoadRef = useRef18(onLoad);
|
|
8702
9039
|
const onErrorRef = useRef18(onError);
|
|
8703
9040
|
onLoadRef.current = onLoad;
|
|
@@ -8752,7 +9089,7 @@ function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
|
8752
9089
|
function Sphere({
|
|
8753
9090
|
src,
|
|
8754
9091
|
previewUrl,
|
|
8755
|
-
yawOffset = 0,
|
|
9092
|
+
yawOffset: yawOffset2 = 0,
|
|
8756
9093
|
onReady,
|
|
8757
9094
|
onLoad,
|
|
8758
9095
|
onError,
|
|
@@ -8761,7 +9098,7 @@ function Sphere({
|
|
|
8761
9098
|
}) {
|
|
8762
9099
|
const gl = useThree12((state) => state.gl);
|
|
8763
9100
|
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
8764
|
-
const resolvedPreviewUrl =
|
|
9101
|
+
const resolvedPreviewUrl = useMemo13(
|
|
8765
9102
|
() => resolveUrlAgainstFile(src, previewUrl),
|
|
8766
9103
|
[previewUrl, src]
|
|
8767
9104
|
);
|
|
@@ -8807,11 +9144,11 @@ function Sphere({
|
|
|
8807
9144
|
return /* @__PURE__ */ jsxs9(
|
|
8808
9145
|
"mesh",
|
|
8809
9146
|
{
|
|
8810
|
-
rotation: [0, MathUtils3.degToRad(90 +
|
|
9147
|
+
rotation: [0, MathUtils3.degToRad(90 + yawOffset2), 0],
|
|
8811
9148
|
visible,
|
|
8812
9149
|
children: [
|
|
8813
|
-
/* @__PURE__ */
|
|
8814
|
-
/* @__PURE__ */
|
|
9150
|
+
/* @__PURE__ */ jsx18("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
|
|
9151
|
+
/* @__PURE__ */ jsx18(
|
|
8815
9152
|
PanoBasicMaterial,
|
|
8816
9153
|
{
|
|
8817
9154
|
map: displayTexture,
|
|
@@ -8826,7 +9163,7 @@ function Sphere({
|
|
|
8826
9163
|
|
|
8827
9164
|
// src/sphere-tile/sphere-tile.tsx
|
|
8828
9165
|
import { useFrame as useFrame9, useThree as useThree14 } from "@react-three/fiber";
|
|
8829
|
-
import { memo, useCallback as useCallback7, useEffect as useEffect20, useMemo as
|
|
9166
|
+
import { memo, useCallback as useCallback7, useEffect as useEffect20, useMemo as useMemo15, useRef as useRef20, useState as useState9 } from "react";
|
|
8830
9167
|
import { BackSide as BackSide3, Frustum, Matrix4 as Matrix42, PerspectiveCamera as PerspectiveCamera3 } from "three";
|
|
8831
9168
|
|
|
8832
9169
|
// src/tile/texture-manager.ts
|
|
@@ -9062,13 +9399,13 @@ var TileTextureManager = class {
|
|
|
9062
9399
|
// src/tile/texture-manager-context.tsx
|
|
9063
9400
|
import { useThree as useThree13 } from "@react-three/fiber";
|
|
9064
9401
|
import {
|
|
9065
|
-
createContext as
|
|
9066
|
-
useContext as
|
|
9402
|
+
createContext as createContext17,
|
|
9403
|
+
useContext as useContext18,
|
|
9067
9404
|
useEffect as useEffect18,
|
|
9068
|
-
useMemo as
|
|
9405
|
+
useMemo as useMemo14
|
|
9069
9406
|
} from "react";
|
|
9070
|
-
import { jsx as
|
|
9071
|
-
var TileTextureManagerContext =
|
|
9407
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
9408
|
+
var TileTextureManagerContext = createContext17(null);
|
|
9072
9409
|
function TileTextureManagerProvider({
|
|
9073
9410
|
children,
|
|
9074
9411
|
maxTextureMemoryMb = 128,
|
|
@@ -9076,7 +9413,7 @@ function TileTextureManagerProvider({
|
|
|
9076
9413
|
}) {
|
|
9077
9414
|
const gl = useThree13((state) => state.gl);
|
|
9078
9415
|
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
9079
|
-
const manager =
|
|
9416
|
+
const manager = useMemo14(
|
|
9080
9417
|
() => new TileTextureManager({
|
|
9081
9418
|
anisotropy,
|
|
9082
9419
|
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
@@ -9089,14 +9426,14 @@ function TileTextureManagerProvider({
|
|
|
9089
9426
|
manager.resume();
|
|
9090
9427
|
return () => manager.dispose();
|
|
9091
9428
|
}, [manager]);
|
|
9092
|
-
return /* @__PURE__ */
|
|
9429
|
+
return /* @__PURE__ */ jsx19(TileTextureManagerContext.Provider, { value: manager, children });
|
|
9093
9430
|
}
|
|
9094
9431
|
function useSharedTileTextureManager() {
|
|
9095
|
-
return
|
|
9432
|
+
return useContext18(TileTextureManagerContext);
|
|
9096
9433
|
}
|
|
9097
9434
|
|
|
9098
9435
|
// src/tile/texture-hooks.ts
|
|
9099
|
-
import { useEffect as useEffect19, useRef as useRef19, useState as
|
|
9436
|
+
import { useEffect as useEffect19, useRef as useRef19, useState as useState8 } from "react";
|
|
9100
9437
|
import {
|
|
9101
9438
|
ClampToEdgeWrapping as ClampToEdgeWrapping2,
|
|
9102
9439
|
LinearFilter as LinearFilter3,
|
|
@@ -9104,7 +9441,7 @@ import {
|
|
|
9104
9441
|
TextureLoader as TextureLoader3
|
|
9105
9442
|
} from "three";
|
|
9106
9443
|
function usePreviewTexture(url, anisotropy, onError) {
|
|
9107
|
-
const [texture, setTexture] =
|
|
9444
|
+
const [texture, setTexture] = useState8(null);
|
|
9108
9445
|
const onErrorRef = useRef19(onError);
|
|
9109
9446
|
onErrorRef.current = onError;
|
|
9110
9447
|
useEffect19(() => {
|
|
@@ -9153,7 +9490,7 @@ function usePreviewTexture(url, anisotropy, onError) {
|
|
|
9153
9490
|
return texture;
|
|
9154
9491
|
}
|
|
9155
9492
|
function useManagedTexture(manager, key, url, address) {
|
|
9156
|
-
const [managedState, setManagedState] =
|
|
9493
|
+
const [managedState, setManagedState] = useState8(() => ({
|
|
9157
9494
|
manager,
|
|
9158
9495
|
key,
|
|
9159
9496
|
url,
|
|
@@ -9182,7 +9519,7 @@ import {
|
|
|
9182
9519
|
MathUtils as MathUtils4,
|
|
9183
9520
|
Vector3 as Vector39
|
|
9184
9521
|
} from "three";
|
|
9185
|
-
function
|
|
9522
|
+
function positiveInteger2(value, name) {
|
|
9186
9523
|
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
9187
9524
|
throw new Error(`${name} must be a positive safe integer`);
|
|
9188
9525
|
}
|
|
@@ -9190,7 +9527,7 @@ function positiveInteger(value, name) {
|
|
|
9190
9527
|
}
|
|
9191
9528
|
function parseSphereMultires(input) {
|
|
9192
9529
|
const parts = typeof input === "string" ? input.split(",").map((part) => part.trim()) : null;
|
|
9193
|
-
const tileSize =
|
|
9530
|
+
const tileSize = positiveInteger2(
|
|
9194
9531
|
parts ? Number(parts[0]) : input.tileSize,
|
|
9195
9532
|
"tileSize"
|
|
9196
9533
|
);
|
|
@@ -9203,8 +9540,8 @@ function parseSphereMultires(input) {
|
|
|
9203
9540
|
if (levels.length === 0)
|
|
9204
9541
|
throw new Error("sphere multires needs at least one level");
|
|
9205
9542
|
levels.forEach((level, index) => {
|
|
9206
|
-
|
|
9207
|
-
|
|
9543
|
+
positiveInteger2(level.width, "level width");
|
|
9544
|
+
positiveInteger2(level.height, "level height");
|
|
9208
9545
|
if (Math.abs(level.width - level.height * 2) > 2)
|
|
9209
9546
|
throw new Error("sphere levels must be full 2:1 equirectangular images");
|
|
9210
9547
|
const previous = levels[index - 1];
|
|
@@ -9251,8 +9588,8 @@ function sphereTileRange(address) {
|
|
|
9251
9588
|
bottom: (address.row * address.tileSize + address.height) / address.imageHeight
|
|
9252
9589
|
};
|
|
9253
9590
|
}
|
|
9254
|
-
function spherePoint(u, v,
|
|
9255
|
-
const yaw = (u - 0.5) * Math.PI * 2 + MathUtils4.degToRad(
|
|
9591
|
+
function spherePoint(u, v, yawOffset2 = 0, radius = DEFAULT_PANORAMA_RADIUS) {
|
|
9592
|
+
const yaw = (u - 0.5) * Math.PI * 2 + MathUtils4.degToRad(yawOffset2);
|
|
9256
9593
|
const pitch = (0.5 - v) * Math.PI;
|
|
9257
9594
|
return new Vector39(
|
|
9258
9595
|
Math.sin(yaw) * Math.cos(pitch) * radius,
|
|
@@ -9260,19 +9597,19 @@ function spherePoint(u, v, yawOffset = 0, radius = DEFAULT_PANORAMA_RADIUS) {
|
|
|
9260
9597
|
-Math.cos(yaw) * Math.cos(pitch) * radius
|
|
9261
9598
|
);
|
|
9262
9599
|
}
|
|
9263
|
-
function sphereTileBounds(address,
|
|
9600
|
+
function sphereTileBounds(address, yawOffset2) {
|
|
9264
9601
|
const { left, right, top, bottom } = sphereTileRange(address);
|
|
9265
9602
|
const us = [left, right];
|
|
9266
9603
|
for (let i = -4; i <= 8; i++) {
|
|
9267
|
-
const u = 0.5 + (i * 90 -
|
|
9604
|
+
const u = 0.5 + (i * 90 - yawOffset2 % 360) / 360;
|
|
9268
9605
|
if (u > left && u < right) us.push(u);
|
|
9269
9606
|
}
|
|
9270
9607
|
const vs = top < 0.5 && bottom > 0.5 ? [top, 0.5, bottom] : [top, bottom];
|
|
9271
9608
|
return new Box3().setFromPoints(
|
|
9272
|
-
us.flatMap((u) => vs.map((v) => spherePoint(u, v,
|
|
9609
|
+
us.flatMap((u) => vs.map((v) => spherePoint(u, v, yawOffset2)))
|
|
9273
9610
|
);
|
|
9274
9611
|
}
|
|
9275
|
-
function sphereTileGeometry(address,
|
|
9612
|
+
function sphereTileGeometry(address, yawOffset2, radius = DEFAULT_PANORAMA_RADIUS) {
|
|
9276
9613
|
const { left, right, top, bottom } = sphereTileRange(address);
|
|
9277
9614
|
const columns = Math.max(2, Math.ceil((right - left) * 360 / 3));
|
|
9278
9615
|
const rows = Math.max(2, Math.ceil((bottom - top) * 180 / 3));
|
|
@@ -9283,7 +9620,7 @@ function sphereTileGeometry(address, yawOffset, radius = DEFAULT_PANORAMA_RADIUS
|
|
|
9283
9620
|
const point = spherePoint(
|
|
9284
9621
|
left + (right - left) * u,
|
|
9285
9622
|
top + (bottom - top) * v,
|
|
9286
|
-
|
|
9623
|
+
yawOffset2,
|
|
9287
9624
|
radius
|
|
9288
9625
|
);
|
|
9289
9626
|
positions.push(point.x, point.y, point.z);
|
|
@@ -9308,7 +9645,7 @@ function preferredSphereLevel(levels, height, dpr, verticalFov) {
|
|
|
9308
9645
|
}
|
|
9309
9646
|
|
|
9310
9647
|
// src/sphere-tile/sphere-tile.tsx
|
|
9311
|
-
import { jsx as
|
|
9648
|
+
import { jsx as jsx20, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
9312
9649
|
function sphereTileViewShouldRefresh(input) {
|
|
9313
9650
|
if (input.loadModeChanged || input.managerChanged) {
|
|
9314
9651
|
return true;
|
|
@@ -9321,24 +9658,24 @@ function sphereTileViewShouldRefresh(input) {
|
|
|
9321
9658
|
function SpherePatch({
|
|
9322
9659
|
address,
|
|
9323
9660
|
texture,
|
|
9324
|
-
yawOffset,
|
|
9661
|
+
yawOffset: yawOffset2,
|
|
9325
9662
|
preview = false
|
|
9326
9663
|
}) {
|
|
9327
|
-
const geometry =
|
|
9664
|
+
const geometry = useMemo15(
|
|
9328
9665
|
() => sphereTileGeometry(
|
|
9329
9666
|
address,
|
|
9330
|
-
|
|
9667
|
+
yawOffset2,
|
|
9331
9668
|
DEFAULT_PANORAMA_RADIUS + (preview ? 0.05 : 0)
|
|
9332
9669
|
),
|
|
9333
|
-
[address,
|
|
9670
|
+
[address, yawOffset2, preview]
|
|
9334
9671
|
);
|
|
9335
9672
|
useEffect20(() => () => geometry.dispose(), [geometry]);
|
|
9336
|
-
return /* @__PURE__ */
|
|
9673
|
+
return /* @__PURE__ */ jsx20(
|
|
9337
9674
|
"mesh",
|
|
9338
9675
|
{
|
|
9339
9676
|
geometry,
|
|
9340
9677
|
renderOrder: preview ? -1e3 : -900 + address.level,
|
|
9341
|
-
children: /* @__PURE__ */
|
|
9678
|
+
children: /* @__PURE__ */ jsx20(
|
|
9342
9679
|
PanoBasicMaterial,
|
|
9343
9680
|
{
|
|
9344
9681
|
map: texture,
|
|
@@ -9355,7 +9692,7 @@ var ManagedPatch = memo(function ManagedPatch2({
|
|
|
9355
9692
|
address,
|
|
9356
9693
|
manager,
|
|
9357
9694
|
resolveUrl,
|
|
9358
|
-
yawOffset,
|
|
9695
|
+
yawOffset: yawOffset2,
|
|
9359
9696
|
ready
|
|
9360
9697
|
}) {
|
|
9361
9698
|
const url = resolveUrl(address);
|
|
@@ -9368,12 +9705,12 @@ var ManagedPatch = memo(function ManagedPatch2({
|
|
|
9368
9705
|
useEffect20(() => {
|
|
9369
9706
|
if (snapshot.texture) ready();
|
|
9370
9707
|
}, [snapshot.texture, ready]);
|
|
9371
|
-
return snapshot.texture ? /* @__PURE__ */
|
|
9708
|
+
return snapshot.texture ? /* @__PURE__ */ jsx20(
|
|
9372
9709
|
SpherePatch,
|
|
9373
9710
|
{
|
|
9374
9711
|
address,
|
|
9375
9712
|
texture: snapshot.texture,
|
|
9376
|
-
yawOffset
|
|
9713
|
+
yawOffset: yawOffset2
|
|
9377
9714
|
}
|
|
9378
9715
|
) : null;
|
|
9379
9716
|
});
|
|
@@ -9384,7 +9721,7 @@ function SphereTileSource({
|
|
|
9384
9721
|
urlTemplate = "tiles/%l/%h_%v.webp",
|
|
9385
9722
|
indexBase = 1,
|
|
9386
9723
|
resolveTileUrl,
|
|
9387
|
-
yawOffset = 0,
|
|
9724
|
+
yawOffset: yawOffset2 = 0,
|
|
9388
9725
|
maxTextureMemoryMb = 128,
|
|
9389
9726
|
maxConcurrentLoads = 4,
|
|
9390
9727
|
retryCount = 1,
|
|
@@ -9415,7 +9752,7 @@ function SphereTileSource({
|
|
|
9415
9752
|
1,
|
|
9416
9753
|
Number.isFinite(maxTextureMemoryMb) ? maxTextureMemoryMb : 128
|
|
9417
9754
|
) * 1024 * 1024;
|
|
9418
|
-
const ownedManager =
|
|
9755
|
+
const ownedManager = useMemo15(
|
|
9419
9756
|
() => new TileTextureManager({
|
|
9420
9757
|
anisotropy,
|
|
9421
9758
|
maxBytes: ownedBudget,
|
|
@@ -9456,33 +9793,33 @@ function SphereTileSource({
|
|
|
9456
9793
|
queueMicrotask(() => manager.releaseUnused());
|
|
9457
9794
|
};
|
|
9458
9795
|
}, [manager, ownedManager]);
|
|
9459
|
-
const resolveUrl =
|
|
9796
|
+
const resolveUrl = useMemo15(
|
|
9460
9797
|
() => (address) => resolveAssetUrl(
|
|
9461
9798
|
baseUrl,
|
|
9462
9799
|
resolveTileUrl ? resolveTileUrl(address) : resolveSphereTemplateUrl(urlTemplate, address, indexBase)
|
|
9463
9800
|
),
|
|
9464
9801
|
[baseUrl, resolveTileUrl, urlTemplate, indexBase]
|
|
9465
9802
|
);
|
|
9466
|
-
const candidates =
|
|
9803
|
+
const candidates = useMemo15(
|
|
9467
9804
|
() => config.levels.map(
|
|
9468
9805
|
(level, index) => sphereTileAddresses(level, index, config.tileSize).map((address) => ({
|
|
9469
9806
|
address,
|
|
9470
|
-
bounds: sphereTileBounds(address,
|
|
9807
|
+
bounds: sphereTileBounds(address, yawOffset2)
|
|
9471
9808
|
}))
|
|
9472
9809
|
),
|
|
9473
|
-
[config,
|
|
9810
|
+
[config, yawOffset2]
|
|
9474
9811
|
);
|
|
9475
|
-
const previewAddress =
|
|
9812
|
+
const previewAddress = useMemo15(
|
|
9476
9813
|
() => sphereTileAddresses({ width: 2, height: 1 }, 0, 2)[0],
|
|
9477
9814
|
[]
|
|
9478
9815
|
);
|
|
9479
|
-
const [layers, setLayers] =
|
|
9816
|
+
const [layers, setLayers] = useState9([]);
|
|
9480
9817
|
const detailReporter = useSceneDetailReporter();
|
|
9481
9818
|
const detailReporterRef = useRef20(detailReporter);
|
|
9482
9819
|
detailReporterRef.current = detailReporter;
|
|
9483
9820
|
const detailTokenRef = useRef20("");
|
|
9484
9821
|
const targetKeysRef = useRef20([]);
|
|
9485
|
-
const scratch =
|
|
9822
|
+
const scratch = useMemo15(
|
|
9486
9823
|
() => ({
|
|
9487
9824
|
camera: new PerspectiveCamera3(),
|
|
9488
9825
|
frustum: new Frustum(),
|
|
@@ -9571,23 +9908,23 @@ function SphereTileSource({
|
|
|
9571
9908
|
);
|
|
9572
9909
|
});
|
|
9573
9910
|
return /* @__PURE__ */ jsxs10("group", { visible, children: [
|
|
9574
|
-
preview ? /* @__PURE__ */
|
|
9911
|
+
preview ? /* @__PURE__ */ jsx20(
|
|
9575
9912
|
SpherePatch,
|
|
9576
9913
|
{
|
|
9577
9914
|
address: previewAddress,
|
|
9578
9915
|
texture: preview,
|
|
9579
|
-
yawOffset,
|
|
9916
|
+
yawOffset: yawOffset2,
|
|
9580
9917
|
preview: true
|
|
9581
9918
|
}
|
|
9582
9919
|
) : null,
|
|
9583
9920
|
loadMode !== "preview" ? layers.flatMap(
|
|
9584
|
-
(layer) => layer.addresses.map((address) => /* @__PURE__ */
|
|
9921
|
+
(layer) => layer.addresses.map((address) => /* @__PURE__ */ jsx20(
|
|
9585
9922
|
ManagedPatch,
|
|
9586
9923
|
{
|
|
9587
9924
|
address,
|
|
9588
9925
|
manager,
|
|
9589
9926
|
resolveUrl,
|
|
9590
|
-
yawOffset,
|
|
9927
|
+
yawOffset: yawOffset2,
|
|
9591
9928
|
ready
|
|
9592
9929
|
},
|
|
9593
9930
|
sphereTileKey(address)
|
|
@@ -9597,14 +9934,14 @@ function SphereTileSource({
|
|
|
9597
9934
|
}
|
|
9598
9935
|
function SphereTile({ multires, ...props }) {
|
|
9599
9936
|
const token = typeof multires === "string" ? multires : JSON.stringify(multires);
|
|
9600
|
-
const config =
|
|
9937
|
+
const config = useMemo15(() => parseSphereMultires(multires), [token]);
|
|
9601
9938
|
const sourceKey = `${props.baseUrl}\0${token}\0${props.previewUrl}\0${props.urlTemplate ?? ""}\0${props.indexBase ?? 1}`;
|
|
9602
|
-
return /* @__PURE__ */
|
|
9939
|
+
return /* @__PURE__ */ jsx20(SphereTileSource, { ...props, config }, sourceKey);
|
|
9603
9940
|
}
|
|
9604
9941
|
|
|
9605
9942
|
// src/tile/tile.tsx
|
|
9606
9943
|
import { useFrame as useFrame10, useThree as useThree15 } from "@react-three/fiber";
|
|
9607
|
-
import { memo as memo2, useEffect as useEffect21, useMemo as
|
|
9944
|
+
import { memo as memo2, useEffect as useEffect21, useMemo as useMemo16, useRef as useRef21, useState as useState10 } from "react";
|
|
9608
9945
|
import {
|
|
9609
9946
|
Frustum as Frustum2,
|
|
9610
9947
|
Matrix4 as Matrix43,
|
|
@@ -9738,64 +10075,8 @@ function previewAtlasVRange(face, faceOrder = PREVIEW_FACE_ORDER) {
|
|
|
9738
10075
|
};
|
|
9739
10076
|
}
|
|
9740
10077
|
|
|
9741
|
-
// src/tile/multires.ts
|
|
9742
|
-
function positiveInteger2(value, name) {
|
|
9743
|
-
if (!Number.isFinite(value) || value <= 0 || !Number.isInteger(value)) {
|
|
9744
|
-
throw new Error(`${name} must be a positive integer, received ${String(value)}`);
|
|
9745
|
-
}
|
|
9746
|
-
return value;
|
|
9747
|
-
}
|
|
9748
|
-
function ascendingLevels(levels) {
|
|
9749
|
-
for (let index = 1; index < levels.length; index += 1) {
|
|
9750
|
-
if (levels[index] <= levels[index - 1]) {
|
|
9751
|
-
throw new Error("multires face sizes must be strictly ascending");
|
|
9752
|
-
}
|
|
9753
|
-
}
|
|
9754
|
-
return levels;
|
|
9755
|
-
}
|
|
9756
|
-
function parseMultires(multires) {
|
|
9757
|
-
if (typeof multires !== "string") {
|
|
9758
|
-
const tileSize2 = positiveInteger2(multires.tileSize, "multires.tileSize");
|
|
9759
|
-
if (multires.levels.length === 0) {
|
|
9760
|
-
throw new Error("multires.levels must contain at least one face size");
|
|
9761
|
-
}
|
|
9762
|
-
const levels2 = ascendingLevels(
|
|
9763
|
-
multires.levels.map(
|
|
9764
|
-
(level, index) => positiveInteger2(level, `multires.levels[${index}]`)
|
|
9765
|
-
)
|
|
9766
|
-
);
|
|
9767
|
-
return { tileSize: tileSize2, levels: levels2 };
|
|
9768
|
-
}
|
|
9769
|
-
const values = multires.split(",").map((part) => Number(part.trim()));
|
|
9770
|
-
if (values.length < 2 || values.some((value) => !Number.isFinite(value))) {
|
|
9771
|
-
throw new Error(
|
|
9772
|
-
"multires must contain a tile size followed by at least one face size"
|
|
9773
|
-
);
|
|
9774
|
-
}
|
|
9775
|
-
const tileSize = positiveInteger2(values[0], "multires tile size");
|
|
9776
|
-
const levels = ascendingLevels(
|
|
9777
|
-
values.slice(1).map(
|
|
9778
|
-
(level, index) => positiveInteger2(level, `multires level ${index + 1}`)
|
|
9779
|
-
)
|
|
9780
|
-
);
|
|
9781
|
-
return { tileSize, levels };
|
|
9782
|
-
}
|
|
9783
|
-
var DEFAULT_TILE_URL_TEMPLATE = "tiles/%s/l%l/%v/l%l_%s_%h_%v.webp";
|
|
9784
|
-
function buildDefaultTileUrlTemplate() {
|
|
9785
|
-
return DEFAULT_TILE_URL_TEMPLATE;
|
|
9786
|
-
}
|
|
9787
|
-
function resolveRelativeTileUrl(baseUrl, relativePath) {
|
|
9788
|
-
return resolveAssetUrl(baseUrl, relativePath);
|
|
9789
|
-
}
|
|
9790
|
-
function resolveTemplateUrl(template, address) {
|
|
9791
|
-
return template.replace(/%s/g, address.face).replace(/%l/g, String(address.level)).replace(/%(0*)([hxucvywr])/g, (_match, zeroes, placeholder) => {
|
|
9792
|
-
const value = "hxuc".includes(placeholder) ? address.col : address.row;
|
|
9793
|
-
return String(value).padStart(zeroes.length + 1, "0");
|
|
9794
|
-
});
|
|
9795
|
-
}
|
|
9796
|
-
|
|
9797
10078
|
// src/tile/tile.tsx
|
|
9798
|
-
import { jsx as
|
|
10079
|
+
import { jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
9799
10080
|
var MAX_LOD_UPDATE_INTERVAL_MS = 100;
|
|
9800
10081
|
var FAST_ROTATION_THRESHOLD_RADIANS = Math.PI / 180;
|
|
9801
10082
|
var FAST_FOV_THRESHOLD_DEGREES = 0.5;
|
|
@@ -9824,7 +10105,7 @@ function PreviewFace({
|
|
|
9824
10105
|
texture,
|
|
9825
10106
|
faceOrder
|
|
9826
10107
|
}) {
|
|
9827
|
-
const geometry =
|
|
10108
|
+
const geometry = useMemo16(() => {
|
|
9828
10109
|
const nextGeometry = new PlaneGeometry3(
|
|
9829
10110
|
PREVIEW_RADIUS * 2,
|
|
9830
10111
|
PREVIEW_RADIUS * 2
|
|
@@ -9846,14 +10127,14 @@ function PreviewFace({
|
|
|
9846
10127
|
[geometry]
|
|
9847
10128
|
);
|
|
9848
10129
|
const transform = getFaceTransform(face, PREVIEW_RADIUS);
|
|
9849
|
-
return /* @__PURE__ */
|
|
10130
|
+
return /* @__PURE__ */ jsx21(
|
|
9850
10131
|
"mesh",
|
|
9851
10132
|
{
|
|
9852
10133
|
geometry,
|
|
9853
10134
|
position: transform.position,
|
|
9854
10135
|
renderOrder: -100,
|
|
9855
10136
|
rotation: transform.rotation,
|
|
9856
|
-
children: /* @__PURE__ */
|
|
10137
|
+
children: /* @__PURE__ */ jsx21(
|
|
9857
10138
|
PanoBasicMaterial,
|
|
9858
10139
|
{
|
|
9859
10140
|
depthTest: false,
|
|
@@ -9869,7 +10150,7 @@ function PreviewCube({
|
|
|
9869
10150
|
texture,
|
|
9870
10151
|
faceOrder
|
|
9871
10152
|
}) {
|
|
9872
|
-
return CUBE_FACES.map((face) => /* @__PURE__ */
|
|
10153
|
+
return CUBE_FACES.map((face) => /* @__PURE__ */ jsx21(
|
|
9873
10154
|
PreviewFace,
|
|
9874
10155
|
{
|
|
9875
10156
|
face,
|
|
@@ -9893,14 +10174,14 @@ var TileMesh = memo2(function TileMesh2({
|
|
|
9893
10174
|
if (!snapshot.texture) {
|
|
9894
10175
|
return null;
|
|
9895
10176
|
}
|
|
9896
|
-
return /* @__PURE__ */
|
|
10177
|
+
return /* @__PURE__ */ jsx21("group", { position: transform.position, rotation: transform.rotation, children: /* @__PURE__ */ jsx21(
|
|
9897
10178
|
"mesh",
|
|
9898
10179
|
{
|
|
9899
10180
|
geometry: SHARED_TILE_GEOMETRY,
|
|
9900
10181
|
position: [layout.x, layout.y, 0],
|
|
9901
10182
|
renderOrder,
|
|
9902
10183
|
scale: [layout.width, layout.height, 1],
|
|
9903
|
-
children: /* @__PURE__ */
|
|
10184
|
+
children: /* @__PURE__ */ jsx21(
|
|
9904
10185
|
PanoBasicMaterial,
|
|
9905
10186
|
{
|
|
9906
10187
|
depthTest: false,
|
|
@@ -9917,7 +10198,7 @@ var TileLayerMeshes = memo2(function TileLayerMeshes2({
|
|
|
9917
10198
|
manager,
|
|
9918
10199
|
resolveUrl
|
|
9919
10200
|
}) {
|
|
9920
|
-
return layer.addresses.map((address) => /* @__PURE__ */
|
|
10201
|
+
return layer.addresses.map((address) => /* @__PURE__ */ jsx21(
|
|
9921
10202
|
TileMesh,
|
|
9922
10203
|
{
|
|
9923
10204
|
address,
|
|
@@ -10084,10 +10365,10 @@ function Tile({
|
|
|
10084
10365
|
onLevelChange
|
|
10085
10366
|
}) {
|
|
10086
10367
|
const { camera, gl, size } = useThree15();
|
|
10087
|
-
const multiresConfig =
|
|
10368
|
+
const multiresConfig = useMemo16(() => parseMultires(multires), [multires]);
|
|
10088
10369
|
const { levels, tileSize } = multiresConfig;
|
|
10089
10370
|
const multiresToken = `${tileSize}:${levels.join(",")}`;
|
|
10090
|
-
const candidatesByLevel =
|
|
10371
|
+
const candidatesByLevel = useMemo16(
|
|
10091
10372
|
() => buildTileCandidates(levels, tileSize),
|
|
10092
10373
|
[levels, tileSize]
|
|
10093
10374
|
);
|
|
@@ -10105,7 +10386,7 @@ function Tile({
|
|
|
10105
10386
|
progressRef.current = onLoadProgress;
|
|
10106
10387
|
errorRef.current = onTileError;
|
|
10107
10388
|
levelChangeRef.current = onLevelChange;
|
|
10108
|
-
const ownedManager =
|
|
10389
|
+
const ownedManager = useMemo16(
|
|
10109
10390
|
() => new TileTextureManager({
|
|
10110
10391
|
anisotropy,
|
|
10111
10392
|
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
@@ -10148,14 +10429,14 @@ function Tile({
|
|
|
10148
10429
|
onReady?.();
|
|
10149
10430
|
}, [onReady, previewTexture]);
|
|
10150
10431
|
const template = urlTemplate ?? buildDefaultTileUrlTemplate();
|
|
10151
|
-
const resolveUrl =
|
|
10432
|
+
const resolveUrl = useMemo16(
|
|
10152
10433
|
() => (address) => {
|
|
10153
10434
|
const relativePath = resolveTileUrl ? resolveTileUrl(address) : resolveTemplateUrl(template, address);
|
|
10154
10435
|
return resolveRelativeTileUrl(baseUrl, relativePath);
|
|
10155
10436
|
},
|
|
10156
10437
|
[baseUrl, resolveTileUrl, template]
|
|
10157
10438
|
);
|
|
10158
|
-
const [layers, setLayers] =
|
|
10439
|
+
const [layers, setLayers] = useState10([]);
|
|
10159
10440
|
const layerTokenRef = useRef21("");
|
|
10160
10441
|
const currentLevelRef = useRef21(1);
|
|
10161
10442
|
const lastUpdateAtRef = useRef21(-Infinity);
|
|
@@ -10277,8 +10558,8 @@ function Tile({
|
|
|
10277
10558
|
);
|
|
10278
10559
|
});
|
|
10279
10560
|
return /* @__PURE__ */ jsxs11("group", { visible, children: [
|
|
10280
|
-
previewTexture ? /* @__PURE__ */
|
|
10281
|
-
layers.map((layer) => /* @__PURE__ */
|
|
10561
|
+
previewTexture ? /* @__PURE__ */ jsx21(PreviewCube, { texture: previewTexture, faceOrder: previewFaceOrder }) : null,
|
|
10562
|
+
layers.map((layer) => /* @__PURE__ */ jsx21(
|
|
10282
10563
|
TileLayerMeshes,
|
|
10283
10564
|
{
|
|
10284
10565
|
layer,
|
|
@@ -10291,7 +10572,7 @@ function Tile({
|
|
|
10291
10572
|
}
|
|
10292
10573
|
|
|
10293
10574
|
// src/scenes.tsx
|
|
10294
|
-
import { jsx as
|
|
10575
|
+
import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
10295
10576
|
function SceneSource({
|
|
10296
10577
|
scene,
|
|
10297
10578
|
visible,
|
|
@@ -10304,7 +10585,7 @@ function SceneSource({
|
|
|
10304
10585
|
}
|
|
10305
10586
|
switch (scene.type) {
|
|
10306
10587
|
case "sphere":
|
|
10307
|
-
return /* @__PURE__ */
|
|
10588
|
+
return /* @__PURE__ */ jsx22(
|
|
10308
10589
|
Sphere,
|
|
10309
10590
|
{
|
|
10310
10591
|
src: scene.src,
|
|
@@ -10316,8 +10597,8 @@ function SceneSource({
|
|
|
10316
10597
|
}
|
|
10317
10598
|
);
|
|
10318
10599
|
case "tile": {
|
|
10319
|
-
const { id: _id, type: _type, ...tileProps } = scene;
|
|
10320
|
-
return /* @__PURE__ */
|
|
10600
|
+
const { id: _id, type: _type, viewLimits: _limits, ...tileProps } = scene;
|
|
10601
|
+
return /* @__PURE__ */ jsx22(
|
|
10321
10602
|
Tile,
|
|
10322
10603
|
{
|
|
10323
10604
|
...tileProps,
|
|
@@ -10329,8 +10610,8 @@ function SceneSource({
|
|
|
10329
10610
|
);
|
|
10330
10611
|
}
|
|
10331
10612
|
case "sphereTile": {
|
|
10332
|
-
const { id: _id, type: _type, ...tileProps } = scene;
|
|
10333
|
-
return /* @__PURE__ */
|
|
10613
|
+
const { id: _id, type: _type, viewLimits: _limits, ...tileProps } = scene;
|
|
10614
|
+
return /* @__PURE__ */ jsx22(
|
|
10334
10615
|
SphereTile,
|
|
10335
10616
|
{
|
|
10336
10617
|
...tileProps,
|
|
@@ -10414,29 +10695,29 @@ function ScenesController({
|
|
|
10414
10695
|
transitionWaitForDetailMs,
|
|
10415
10696
|
phaseRef: externalPhaseRef
|
|
10416
10697
|
}) {
|
|
10417
|
-
const controlsRef =
|
|
10698
|
+
const controlsRef = useContext19(PanoramaViewContext);
|
|
10418
10699
|
const manager = useSharedTileTextureManager();
|
|
10419
|
-
const transition =
|
|
10700
|
+
const transition = useMemo17(
|
|
10420
10701
|
() => resolveTransition(transitionInput),
|
|
10421
10702
|
[transitionInput]
|
|
10422
10703
|
);
|
|
10423
|
-
const sceneMap =
|
|
10704
|
+
const sceneMap = useMemo17(
|
|
10424
10705
|
() => new Map(scenes.map((scene) => [scene.id, scene])),
|
|
10425
10706
|
[scenes]
|
|
10426
10707
|
);
|
|
10427
10708
|
const initialScene = sceneMap.get(activeSceneId) ?? null;
|
|
10428
|
-
const [slots, setSlots] =
|
|
10709
|
+
const [slots, setSlots] = useState11([
|
|
10429
10710
|
initialScene,
|
|
10430
10711
|
null
|
|
10431
10712
|
]);
|
|
10432
|
-
const [activeSlot, setActiveSlot] =
|
|
10433
|
-
const [liveSlot, setLiveSlot] =
|
|
10434
|
-
const [pendingSlot, setPendingSlot] =
|
|
10435
|
-
const [phase, setPhase] =
|
|
10436
|
-
const [captureRequestId, setCaptureRequestId] =
|
|
10437
|
-
const [transitionRunId, setTransitionRunId] =
|
|
10438
|
-
const [snapshot, setSnapshot] =
|
|
10439
|
-
const [recoveryKey, setRecoveryKey] =
|
|
10713
|
+
const [activeSlot, setActiveSlot] = useState11(0);
|
|
10714
|
+
const [liveSlot, setLiveSlot] = useState11(0);
|
|
10715
|
+
const [pendingSlot, setPendingSlot] = useState11(null);
|
|
10716
|
+
const [phase, setPhase] = useState11(initialScene ? "idle" : "preloading");
|
|
10717
|
+
const [captureRequestId, setCaptureRequestId] = useState11(0);
|
|
10718
|
+
const [transitionRunId, setTransitionRunId] = useState11(0);
|
|
10719
|
+
const [snapshot, setSnapshot] = useState11(null);
|
|
10720
|
+
const [recoveryKey, setRecoveryKey] = useState11(0);
|
|
10440
10721
|
const requestedSceneIdRef = useRef22(activeSceneId);
|
|
10441
10722
|
const captureReasonRef = useRef22("start");
|
|
10442
10723
|
const interactionReleaseRef = useRef22(null);
|
|
@@ -10448,7 +10729,7 @@ function ScenesController({
|
|
|
10448
10729
|
const waitRef = useRef22(null);
|
|
10449
10730
|
const waitTimerRef = useRef22(null);
|
|
10450
10731
|
const detailGenerationRef = useRef22(0);
|
|
10451
|
-
const [detailGeneration, setDetailGeneration] =
|
|
10732
|
+
const [detailGeneration, setDetailGeneration] = useState11(0);
|
|
10452
10733
|
const mountedRef = useRef22(true);
|
|
10453
10734
|
const waitForDetailMsRef = useRef22(0);
|
|
10454
10735
|
waitForDetailMsRef.current = normalizeTransitionWaitMs(transitionWaitForDetailMs);
|
|
@@ -10458,6 +10739,13 @@ function ScenesController({
|
|
|
10458
10739
|
externalPhaseRef.current = phase;
|
|
10459
10740
|
}
|
|
10460
10741
|
liveSlotRef.current = liveSlot;
|
|
10742
|
+
useEffect22(() => {
|
|
10743
|
+
const ready = readySceneRef.current;
|
|
10744
|
+
if (ready) controlsRef?.current?.setSceneViewLimits(sceneMap.get(ready.id)?.viewLimits);
|
|
10745
|
+
}, [controlsRef, sceneMap]);
|
|
10746
|
+
useEffect22(() => () => {
|
|
10747
|
+
controlsRef?.current?.setSceneViewLimits(void 0);
|
|
10748
|
+
}, [controlsRef]);
|
|
10461
10749
|
const releaseInteraction = useCallback8(() => {
|
|
10462
10750
|
interactionReleaseRef.current?.();
|
|
10463
10751
|
interactionReleaseRef.current = null;
|
|
@@ -10534,8 +10822,9 @@ function ScenesController({
|
|
|
10534
10822
|
const notifySceneReady = useCallback8((scene) => {
|
|
10535
10823
|
if (!scene || readySceneRef.current === scene) return;
|
|
10536
10824
|
readySceneRef.current = scene;
|
|
10825
|
+
controlsRef?.current?.setSceneViewLimits(sceneMap.get(scene.id)?.viewLimits);
|
|
10537
10826
|
onSceneReady?.(scene.id);
|
|
10538
|
-
}, [onSceneReady]);
|
|
10827
|
+
}, [controlsRef, onSceneReady, sceneMap]);
|
|
10539
10828
|
const handleReady = useCallback8((slot) => {
|
|
10540
10829
|
if (slot === liveSlotRef.current && pendingSlot === null && phaseRef.current === "idle") {
|
|
10541
10830
|
notifySceneReady(slotsRef.current[slot]);
|
|
@@ -10755,7 +11044,7 @@ function ScenesController({
|
|
|
10755
11044
|
const snapshotVisible = snapshot !== null && (phase === "transitioning" || phase === "recapturing" || phase === "preloading");
|
|
10756
11045
|
const slotSceneKey = `${slots[0]?.id ?? ""}
|
|
10757
11046
|
${slots[1]?.id ?? ""}`;
|
|
10758
|
-
const detailReporters =
|
|
11047
|
+
const detailReporters = useMemo17(() => {
|
|
10759
11048
|
const [firstSceneId = "", secondSceneId = ""] = slotSceneKey.split("\n");
|
|
10760
11049
|
const sceneIds = [firstSceneId, secondSceneId];
|
|
10761
11050
|
return sceneIds.map((sceneId) => ({
|
|
@@ -10773,7 +11062,7 @@ ${slots[1]?.id ?? ""}`;
|
|
|
10773
11062
|
}));
|
|
10774
11063
|
}, [consumeDetailSignal, detailGeneration, slotSceneKey]);
|
|
10775
11064
|
return /* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
10776
|
-
/* @__PURE__ */
|
|
11065
|
+
/* @__PURE__ */ jsx22(
|
|
10777
11066
|
SnapshotCapture,
|
|
10778
11067
|
{
|
|
10779
11068
|
requestId: captureRequestId,
|
|
@@ -10785,11 +11074,11 @@ ${slots[1]?.id ?? ""}`;
|
|
|
10785
11074
|
const source = slots[slot];
|
|
10786
11075
|
const isLive = slot === liveSlot;
|
|
10787
11076
|
const isPending = slot === pendingSlot;
|
|
10788
|
-
return /* @__PURE__ */
|
|
11077
|
+
return /* @__PURE__ */ jsx22(
|
|
10789
11078
|
SceneDetailContext.Provider,
|
|
10790
11079
|
{
|
|
10791
11080
|
value: detailReporters[slot],
|
|
10792
|
-
children: /* @__PURE__ */
|
|
11081
|
+
children: /* @__PURE__ */ jsx22(
|
|
10793
11082
|
SceneSource,
|
|
10794
11083
|
{
|
|
10795
11084
|
scene: source,
|
|
@@ -10807,8 +11096,8 @@ ${slots[1]?.id ?? ""}`;
|
|
|
10807
11096
|
`${slot}:${source?.id ?? "empty"}:${recoveryKey}`
|
|
10808
11097
|
);
|
|
10809
11098
|
}),
|
|
10810
|
-
snapshot !== null && phase === "awaitingDetail" ? /* @__PURE__ */
|
|
10811
|
-
snapshotVisible ? /* @__PURE__ */
|
|
11099
|
+
snapshot !== null && phase === "awaitingDetail" ? /* @__PURE__ */ jsx22(SnapshotHold, { snapshot }) : null,
|
|
11100
|
+
snapshotVisible ? /* @__PURE__ */ jsx22(
|
|
10812
11101
|
TransitionOverlay,
|
|
10813
11102
|
{
|
|
10814
11103
|
snapshot,
|
|
@@ -10831,7 +11120,7 @@ function Scenes({
|
|
|
10831
11120
|
...rest
|
|
10832
11121
|
}) {
|
|
10833
11122
|
const isControlled = controlledId !== void 0;
|
|
10834
|
-
const [internalId, setInternalId] =
|
|
11123
|
+
const [internalId, setInternalId] = useState11(
|
|
10835
11124
|
() => controlledId ?? defaultActiveSceneId ?? scenes[0]?.id ?? ""
|
|
10836
11125
|
);
|
|
10837
11126
|
const resolvedId = isControlled ? controlledId : internalId;
|
|
@@ -10849,7 +11138,7 @@ function Scenes({
|
|
|
10849
11138
|
scenesRef.current = scenes;
|
|
10850
11139
|
const resolvedIdRef = useRef22(resolvedId);
|
|
10851
11140
|
resolvedIdRef.current = resolvedId;
|
|
10852
|
-
const host =
|
|
11141
|
+
const host = useContext19(ScenesHostContext);
|
|
10853
11142
|
const phaseRef = useRef22("idle");
|
|
10854
11143
|
useEffect22(() => {
|
|
10855
11144
|
if (!host) {
|
|
@@ -10901,12 +11190,12 @@ function Scenes({
|
|
|
10901
11190
|
}
|
|
10902
11191
|
};
|
|
10903
11192
|
}, [host, requestSceneChange]);
|
|
10904
|
-
return /* @__PURE__ */
|
|
11193
|
+
return /* @__PURE__ */ jsx22(
|
|
10905
11194
|
TileTextureManagerProvider,
|
|
10906
11195
|
{
|
|
10907
11196
|
maxTextureMemoryMb,
|
|
10908
11197
|
maxConcurrentLoads: maxConcurrentTileLoads,
|
|
10909
|
-
children: /* @__PURE__ */
|
|
11198
|
+
children: /* @__PURE__ */ jsx22(
|
|
10910
11199
|
ScenesController,
|
|
10911
11200
|
{
|
|
10912
11201
|
...rest,
|
|
@@ -10920,8 +11209,8 @@ function Scenes({
|
|
|
10920
11209
|
}
|
|
10921
11210
|
|
|
10922
11211
|
// src/hotspot/image-hotspot.tsx
|
|
10923
|
-
import { useThree as
|
|
10924
|
-
import { useEffect as useEffect25, useRef as
|
|
11212
|
+
import { useThree as useThree20 } from "@react-three/fiber";
|
|
11213
|
+
import { useEffect as useEffect25, useRef as useRef26, useState as useState14 } from "react";
|
|
10925
11214
|
import {
|
|
10926
11215
|
ClampToEdgeWrapping as ClampToEdgeWrapping3,
|
|
10927
11216
|
LinearFilter as LinearFilter5,
|
|
@@ -10931,43 +11220,43 @@ import {
|
|
|
10931
11220
|
} from "three";
|
|
10932
11221
|
|
|
10933
11222
|
// src/hotspot/hotspot-anchor.tsx
|
|
10934
|
-
import { useFrame as
|
|
11223
|
+
import { useFrame as useFrame14, useThree as useThree19 } from "@react-three/fiber";
|
|
10935
11224
|
import {
|
|
10936
|
-
useContext as
|
|
11225
|
+
useContext as useContext21,
|
|
10937
11226
|
useEffect as useEffect24,
|
|
10938
|
-
useLayoutEffect as
|
|
10939
|
-
useMemo as
|
|
10940
|
-
useRef as
|
|
10941
|
-
useState as
|
|
11227
|
+
useLayoutEffect as useLayoutEffect7,
|
|
11228
|
+
useMemo as useMemo19,
|
|
11229
|
+
useRef as useRef25,
|
|
11230
|
+
useState as useState13
|
|
10942
11231
|
} from "react";
|
|
10943
11232
|
import {
|
|
10944
11233
|
Box3 as Box34,
|
|
10945
11234
|
EdgesGeometry,
|
|
10946
|
-
MathUtils as
|
|
11235
|
+
MathUtils as MathUtils7,
|
|
10947
11236
|
Matrix4 as Matrix44,
|
|
10948
11237
|
Plane,
|
|
10949
11238
|
PlaneGeometry as PlaneGeometry4,
|
|
10950
11239
|
Quaternion as Quaternion3,
|
|
10951
11240
|
Ray,
|
|
10952
|
-
Vector3 as
|
|
11241
|
+
Vector3 as Vector315
|
|
10953
11242
|
} from "three";
|
|
10954
11243
|
|
|
10955
11244
|
// src/hotspot/hotspot-tooltip.tsx
|
|
10956
|
-
import { useEffect as useEffect23, useMemo as
|
|
11245
|
+
import { useEffect as useEffect23, useMemo as useMemo18, useState as useState12 } from "react";
|
|
10957
11246
|
|
|
10958
11247
|
// src/webvr/stereo-html.tsx
|
|
10959
11248
|
import { useFrame as useFrame12, useThree as useThree17 } from "@react-three/fiber";
|
|
10960
11249
|
import {
|
|
10961
|
-
useContext as
|
|
10962
|
-
useLayoutEffect as
|
|
11250
|
+
useContext as useContext20,
|
|
11251
|
+
useLayoutEffect as useLayoutEffect5,
|
|
10963
11252
|
useRef as useRef23,
|
|
10964
11253
|
useSyncExternalStore as useSyncExternalStore7
|
|
10965
11254
|
} from "react";
|
|
10966
11255
|
import { createRoot } from "react-dom/client";
|
|
10967
11256
|
import { Vector3 as Vector312 } from "three";
|
|
10968
|
-
import { Fragment as Fragment5, jsx as
|
|
11257
|
+
import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
10969
11258
|
function useFallbackStereoView() {
|
|
10970
|
-
const runtime =
|
|
11259
|
+
const runtime = useContext20(WebVRRuntimeContext);
|
|
10971
11260
|
const host = runtime?.host ?? null;
|
|
10972
11261
|
const fallback = useSyncExternalStore7(
|
|
10973
11262
|
(onStoreChange) => host ? subscribeWebVRHost(host, onStoreChange) : () => void 0,
|
|
@@ -11015,7 +11304,7 @@ function ProjectedHtml({
|
|
|
11015
11304
|
)
|
|
11016
11305
|
);
|
|
11017
11306
|
};
|
|
11018
|
-
|
|
11307
|
+
useLayoutEffect5(() => {
|
|
11019
11308
|
if (!target) return;
|
|
11020
11309
|
const element = document.createElement("div");
|
|
11021
11310
|
Object.assign(element.style, {
|
|
@@ -11033,9 +11322,9 @@ function ProjectedHtml({
|
|
|
11033
11322
|
queueMicrotask(() => root.unmount());
|
|
11034
11323
|
};
|
|
11035
11324
|
}, [target]);
|
|
11036
|
-
|
|
11325
|
+
useLayoutEffect5(() => {
|
|
11037
11326
|
overlay.current?.root.render(
|
|
11038
|
-
/* @__PURE__ */
|
|
11327
|
+
/* @__PURE__ */ jsx23(
|
|
11039
11328
|
"div",
|
|
11040
11329
|
{
|
|
11041
11330
|
"aria-hidden": eye === "right" || void 0,
|
|
@@ -11047,18 +11336,18 @@ function ProjectedHtml({
|
|
|
11047
11336
|
updatePosition();
|
|
11048
11337
|
});
|
|
11049
11338
|
useFrame12(updatePosition);
|
|
11050
|
-
return /* @__PURE__ */
|
|
11339
|
+
return /* @__PURE__ */ jsx23("group", { ref: group });
|
|
11051
11340
|
}
|
|
11052
11341
|
function PanoHtml(props) {
|
|
11053
11342
|
const stereoView = useFallbackStereoView();
|
|
11054
11343
|
return stereoView ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
11055
|
-
/* @__PURE__ */
|
|
11056
|
-
/* @__PURE__ */
|
|
11057
|
-
] }) : /* @__PURE__ */
|
|
11344
|
+
/* @__PURE__ */ jsx23(ProjectedHtml, { ...props, stereoView, eye: "left" }),
|
|
11345
|
+
/* @__PURE__ */ jsx23(ProjectedHtml, { ...props, stereoView, eye: "right" })
|
|
11346
|
+
] }) : /* @__PURE__ */ jsx23(ProjectedHtml, { ...props });
|
|
11058
11347
|
}
|
|
11059
11348
|
|
|
11060
11349
|
// src/hotspot/hotspot-tooltip.tsx
|
|
11061
|
-
import { jsx as
|
|
11350
|
+
import { jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
11062
11351
|
var DEFAULT_HOTSPOT_TOOLTIP_OFFSET = 12;
|
|
11063
11352
|
var DEFAULT_HOTSPOT_TOOLTIP_APPEARANCE = {
|
|
11064
11353
|
background: "rgba(22, 22, 22, 0.72)",
|
|
@@ -11130,16 +11419,16 @@ function HotspotTooltip({
|
|
|
11130
11419
|
offset = DEFAULT_HOTSPOT_TOOLTIP_OFFSET,
|
|
11131
11420
|
appearance
|
|
11132
11421
|
}) {
|
|
11133
|
-
const [imageFailed, setImageFailed] =
|
|
11422
|
+
const [imageFailed, setImageFailed] = useState12(false);
|
|
11134
11423
|
useEffect23(() => {
|
|
11135
11424
|
setImageFailed(false);
|
|
11136
11425
|
}, [content.image]);
|
|
11137
11426
|
const showImage = Boolean(content.image) && !imageFailed;
|
|
11138
|
-
const resolvedAppearance =
|
|
11427
|
+
const resolvedAppearance = useMemo18(
|
|
11139
11428
|
() => resolveHotspotTooltipAppearance(appearance),
|
|
11140
11429
|
[appearance]
|
|
11141
11430
|
);
|
|
11142
|
-
const bubbleStyle =
|
|
11431
|
+
const bubbleStyle = useMemo18(
|
|
11143
11432
|
() => ({
|
|
11144
11433
|
background: resolvedAppearance.background,
|
|
11145
11434
|
border: resolvedAppearance.border,
|
|
@@ -11161,8 +11450,8 @@ function HotspotTooltip({
|
|
|
11161
11450
|
if (!showImage && !content.text) {
|
|
11162
11451
|
return null;
|
|
11163
11452
|
}
|
|
11164
|
-
return /* @__PURE__ */
|
|
11165
|
-
showImage ? /* @__PURE__ */
|
|
11453
|
+
return /* @__PURE__ */ jsx24(PanoHtml, { pointerEvents: "none", style: WRAPPER_STYLE, zIndexRange: [20, 10], children: /* @__PURE__ */ jsxs14("div", { className: "pano-hotspot-tooltip", role: "tooltip", style: bubbleStyle, children: [
|
|
11454
|
+
showImage ? /* @__PURE__ */ jsx24(
|
|
11166
11455
|
"img",
|
|
11167
11456
|
{
|
|
11168
11457
|
alt: content.imageAlt ?? content.text ?? "",
|
|
@@ -11171,7 +11460,7 @@ function HotspotTooltip({
|
|
|
11171
11460
|
src: content.image
|
|
11172
11461
|
}
|
|
11173
11462
|
) : null,
|
|
11174
|
-
content.text ? /* @__PURE__ */
|
|
11463
|
+
content.text ? /* @__PURE__ */ jsx24(
|
|
11175
11464
|
"p",
|
|
11176
11465
|
{
|
|
11177
11466
|
className: "pano-hotspot-tooltip-text",
|
|
@@ -11221,8 +11510,84 @@ function fixedScaleFactor(cameraFov, referenceFov) {
|
|
|
11221
11510
|
return Math.tan(MathUtils5.degToRad(cameraFov) / 2) / Math.tan(MathUtils5.degToRad(safeReferenceFov) / 2);
|
|
11222
11511
|
}
|
|
11223
11512
|
|
|
11513
|
+
// src/hotspot/hotspot-stroke-line.tsx
|
|
11514
|
+
import { Line } from "@react-three/drei";
|
|
11515
|
+
import { useFrame as useFrame13, useThree as useThree18 } from "@react-three/fiber";
|
|
11516
|
+
import { useLayoutEffect as useLayoutEffect6, useRef as useRef24 } from "react";
|
|
11517
|
+
import {
|
|
11518
|
+
MathUtils as MathUtils6,
|
|
11519
|
+
PerspectiveCamera as PerspectiveCamera6,
|
|
11520
|
+
Vector3 as Vector314
|
|
11521
|
+
} from "three";
|
|
11522
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
11523
|
+
var LINE_WORLD_POSITION = new Vector314();
|
|
11524
|
+
function applyScreenSpaceDashScale(object, camera, viewportHeight) {
|
|
11525
|
+
const material = object?.material;
|
|
11526
|
+
if (!object || typeof material?.dashScale !== "number") {
|
|
11527
|
+
return;
|
|
11528
|
+
}
|
|
11529
|
+
object.getWorldPosition(LINE_WORLD_POSITION);
|
|
11530
|
+
const depth = Math.max(camera.position.distanceTo(LINE_WORLD_POSITION), 1);
|
|
11531
|
+
const fov = camera instanceof PerspectiveCamera6 ? camera.fov : 75;
|
|
11532
|
+
material.dashScale = viewportHeight / (2 * Math.tan(MathUtils6.degToRad(fov) * 0.5) * depth);
|
|
11533
|
+
}
|
|
11534
|
+
function resolveDash(dashSize, gapSize) {
|
|
11535
|
+
if (dashSize === void 0 || !Number.isFinite(dashSize) || dashSize <= 0) {
|
|
11536
|
+
return { dashed: false, dashSize: 1, gapSize: 1 };
|
|
11537
|
+
}
|
|
11538
|
+
return {
|
|
11539
|
+
dashed: true,
|
|
11540
|
+
dashSize,
|
|
11541
|
+
gapSize: Number.isFinite(gapSize) ? Math.max(0, gapSize) : dashSize
|
|
11542
|
+
};
|
|
11543
|
+
}
|
|
11544
|
+
function HotspotStrokeLine({
|
|
11545
|
+
points,
|
|
11546
|
+
color,
|
|
11547
|
+
lineWidth,
|
|
11548
|
+
opacity,
|
|
11549
|
+
renderOrder,
|
|
11550
|
+
dashSize,
|
|
11551
|
+
gapSize
|
|
11552
|
+
}) {
|
|
11553
|
+
const lineRef = useRef24(null);
|
|
11554
|
+
const { camera, size } = useThree18();
|
|
11555
|
+
const dash = resolveDash(dashSize, gapSize);
|
|
11556
|
+
useLayoutEffect6(() => {
|
|
11557
|
+
if (!dash.dashed) {
|
|
11558
|
+
return;
|
|
11559
|
+
}
|
|
11560
|
+
applyScreenSpaceDashScale(lineRef.current, camera, size.height);
|
|
11561
|
+
}, [camera, dash.dashed, dash.dashSize, dash.gapSize, size.height]);
|
|
11562
|
+
useFrame13((state) => {
|
|
11563
|
+
if (!dash.dashed) {
|
|
11564
|
+
return;
|
|
11565
|
+
}
|
|
11566
|
+
applyScreenSpaceDashScale(lineRef.current, state.camera, state.size.height);
|
|
11567
|
+
});
|
|
11568
|
+
return /* @__PURE__ */ jsx25(
|
|
11569
|
+
Line,
|
|
11570
|
+
{
|
|
11571
|
+
ref: lineRef,
|
|
11572
|
+
alphaToCoverage: true,
|
|
11573
|
+
color,
|
|
11574
|
+
dashed: dash.dashed,
|
|
11575
|
+
dashSize: dash.dashSize,
|
|
11576
|
+
depthTest: true,
|
|
11577
|
+
depthWrite: false,
|
|
11578
|
+
gapSize: dash.gapSize,
|
|
11579
|
+
lineWidth: Math.max(0.5, lineWidth),
|
|
11580
|
+
opacity,
|
|
11581
|
+
points,
|
|
11582
|
+
renderOrder,
|
|
11583
|
+
transparent: true,
|
|
11584
|
+
worldUnits: false
|
|
11585
|
+
}
|
|
11586
|
+
);
|
|
11587
|
+
}
|
|
11588
|
+
|
|
11224
11589
|
// src/hotspot/hotspot-anchor.tsx
|
|
11225
|
-
import { jsx as
|
|
11590
|
+
import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
11226
11591
|
var DEFAULT_FLOATING_DISTANCE = 10;
|
|
11227
11592
|
var PANORAMA_RADIUS = DEFAULT_PANORAMA_RADIUS;
|
|
11228
11593
|
var PANORAMA_SURFACE_INSET = 4;
|
|
@@ -11230,27 +11595,34 @@ var DEFAULT_REFERENCE_FOV = 75;
|
|
|
11230
11595
|
var MIN_ANGULAR_SIZE = 0.01;
|
|
11231
11596
|
var MAX_ANGULAR_SIZE = 179;
|
|
11232
11597
|
var DRAG_EPSILON_DEGREES = 1e-3;
|
|
11598
|
+
var SELECTION_BORDER_POINTS = [
|
|
11599
|
+
[-0.5, -0.5, 1e-3],
|
|
11600
|
+
[0.5, -0.5, 1e-3],
|
|
11601
|
+
[0.5, 0.5, 1e-3],
|
|
11602
|
+
[-0.5, 0.5, 1e-3],
|
|
11603
|
+
[-0.5, -0.5, 1e-3]
|
|
11604
|
+
];
|
|
11233
11605
|
var TOOLTIP_WORLD_BOX = new Box34();
|
|
11234
11606
|
var TOOLTIP_LOCAL_BOX = new Box34();
|
|
11235
|
-
var TOOLTIP_CORNER = new
|
|
11607
|
+
var TOOLTIP_CORNER = new Vector315();
|
|
11236
11608
|
var TOOLTIP_INVERSE = new Matrix44();
|
|
11237
|
-
var TOOLTIP_WORLD_CORNER = new
|
|
11238
|
-
var TOOLTIP_PROJECTED = new
|
|
11239
|
-
var TOOLTIP_RAY_ORIGIN = new
|
|
11240
|
-
var TOOLTIP_RAY_FAR = new
|
|
11241
|
-
var TOOLTIP_RAY_DIRECTION = new
|
|
11609
|
+
var TOOLTIP_WORLD_CORNER = new Vector315();
|
|
11610
|
+
var TOOLTIP_PROJECTED = new Vector315();
|
|
11611
|
+
var TOOLTIP_RAY_ORIGIN = new Vector315();
|
|
11612
|
+
var TOOLTIP_RAY_FAR = new Vector315();
|
|
11613
|
+
var TOOLTIP_RAY_DIRECTION = new Vector315();
|
|
11242
11614
|
var TOOLTIP_RAY = new Ray();
|
|
11243
11615
|
var TOOLTIP_PLANE = new Plane();
|
|
11244
|
-
var TOOLTIP_INTERSECTION = new
|
|
11245
|
-
var TOOLTIP_PLANE_NORMAL = new
|
|
11246
|
-
var TOOLTIP_PLANE_POINT = new
|
|
11616
|
+
var TOOLTIP_INTERSECTION = new Vector315();
|
|
11617
|
+
var TOOLTIP_PLANE_NORMAL = new Vector315();
|
|
11618
|
+
var TOOLTIP_PLANE_POINT = new Vector315();
|
|
11247
11619
|
var HOTSPOT_MODE_RENDERING = {
|
|
11248
11620
|
surface: { orientation: "surface", placement: "surface" },
|
|
11249
11621
|
billboard: { orientation: "billboard", placement: "floating" }
|
|
11250
11622
|
};
|
|
11251
11623
|
function angularSizeToWorldSize(size, radius) {
|
|
11252
|
-
const safeSize = Number.isFinite(size) ?
|
|
11253
|
-
return 2 * radius * Math.tan(
|
|
11624
|
+
const safeSize = Number.isFinite(size) ? MathUtils7.clamp(Math.abs(size), MIN_ANGULAR_SIZE, MAX_ANGULAR_SIZE) : MIN_ANGULAR_SIZE;
|
|
11625
|
+
return 2 * radius * Math.tan(MathUtils7.degToRad(safeSize) / 2);
|
|
11254
11626
|
}
|
|
11255
11627
|
function resolveScale(scale) {
|
|
11256
11628
|
return Number.isFinite(scale) && scale > 0 ? scale : 1;
|
|
@@ -11263,32 +11635,32 @@ function resolveDistance(placement, distance, width, height) {
|
|
|
11263
11635
|
if (!Number.isFinite(distance)) {
|
|
11264
11636
|
return DEFAULT_FLOATING_DISTANCE;
|
|
11265
11637
|
}
|
|
11266
|
-
return
|
|
11638
|
+
return MathUtils7.clamp(Math.abs(distance), 0.1, maximumDistance);
|
|
11267
11639
|
}
|
|
11268
11640
|
function maximumHotspotDistance(width, height) {
|
|
11269
|
-
const safeWidth =
|
|
11641
|
+
const safeWidth = MathUtils7.clamp(
|
|
11270
11642
|
Math.abs(Number.isFinite(width) ? width : MIN_ANGULAR_SIZE),
|
|
11271
11643
|
MIN_ANGULAR_SIZE,
|
|
11272
11644
|
MAX_ANGULAR_SIZE
|
|
11273
11645
|
);
|
|
11274
|
-
const safeHeight =
|
|
11646
|
+
const safeHeight = MathUtils7.clamp(
|
|
11275
11647
|
Math.abs(Number.isFinite(height) ? height : MIN_ANGULAR_SIZE),
|
|
11276
11648
|
MIN_ANGULAR_SIZE,
|
|
11277
11649
|
MAX_ANGULAR_SIZE
|
|
11278
11650
|
);
|
|
11279
11651
|
const cornerFactor = Math.hypot(
|
|
11280
11652
|
1,
|
|
11281
|
-
Math.tan(
|
|
11282
|
-
Math.tan(
|
|
11653
|
+
Math.tan(MathUtils7.degToRad(safeWidth) / 2),
|
|
11654
|
+
Math.tan(MathUtils7.degToRad(safeHeight) / 2)
|
|
11283
11655
|
);
|
|
11284
11656
|
return (PANORAMA_RADIUS - PANORAMA_SURFACE_INSET) / cornerFactor;
|
|
11285
11657
|
}
|
|
11286
11658
|
function createSurfaceQuaternion(position) {
|
|
11287
11659
|
const outward = panoPositionToVector3(position).normalize();
|
|
11288
11660
|
const inward = outward.clone().negate();
|
|
11289
|
-
const pitch =
|
|
11290
|
-
const yaw =
|
|
11291
|
-
const localUp = new
|
|
11661
|
+
const pitch = MathUtils7.degToRad(position.pitch);
|
|
11662
|
+
const yaw = MathUtils7.degToRad(position.yaw);
|
|
11663
|
+
const localUp = new Vector315(
|
|
11292
11664
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
11293
11665
|
Math.cos(pitch),
|
|
11294
11666
|
Math.sin(pitch) * Math.cos(yaw)
|
|
@@ -11308,7 +11680,7 @@ function makeInteractionEvent(id, position, event) {
|
|
|
11308
11680
|
function angularDistance(a, b) {
|
|
11309
11681
|
const aVector = panoPositionToVector3(a);
|
|
11310
11682
|
const bVector = panoPositionToVector3(b);
|
|
11311
|
-
return
|
|
11683
|
+
return MathUtils7.radToDeg(aVector.angleTo(bVector));
|
|
11312
11684
|
}
|
|
11313
11685
|
function isTooltipOpen(trigger, hovered, focused, pinned) {
|
|
11314
11686
|
switch (trigger) {
|
|
@@ -11522,6 +11894,7 @@ function HotspotAnchor({
|
|
|
11522
11894
|
rotation = 0,
|
|
11523
11895
|
renderOrder = 0,
|
|
11524
11896
|
visible = true,
|
|
11897
|
+
selected = false,
|
|
11525
11898
|
draggable = false,
|
|
11526
11899
|
interactive = true,
|
|
11527
11900
|
pointerEvents = "auto",
|
|
@@ -11539,19 +11912,19 @@ function HotspotAnchor({
|
|
|
11539
11912
|
onPositionChange,
|
|
11540
11913
|
onDragEnd
|
|
11541
11914
|
}) {
|
|
11542
|
-
const controlsRef =
|
|
11543
|
-
const hotspotTargetRegistry =
|
|
11544
|
-
const eventBus =
|
|
11915
|
+
const controlsRef = useContext21(PanoramaViewContext);
|
|
11916
|
+
const hotspotTargetRegistry = useContext21(HotspotTargetRegistryContext);
|
|
11917
|
+
const eventBus = useContext21(PanoEventBusContext);
|
|
11545
11918
|
const cursorApi = usePanoCursor();
|
|
11546
|
-
const { camera, size } =
|
|
11547
|
-
const groupRef =
|
|
11548
|
-
const tooltipAnchorRef =
|
|
11549
|
-
const dragStateRef =
|
|
11550
|
-
const suppressNextClickRef =
|
|
11551
|
-
const [hovered, setHovered] =
|
|
11552
|
-
const [dragging, setDragging] =
|
|
11553
|
-
const [pinned, setPinned] =
|
|
11554
|
-
const tooltipContent =
|
|
11919
|
+
const { camera, size } = useThree19();
|
|
11920
|
+
const groupRef = useRef25(null);
|
|
11921
|
+
const tooltipAnchorRef = useRef25(null);
|
|
11922
|
+
const dragStateRef = useRef25(null);
|
|
11923
|
+
const suppressNextClickRef = useRef25(false);
|
|
11924
|
+
const [hovered, setHovered] = useState13(false);
|
|
11925
|
+
const [dragging, setDragging] = useState13(false);
|
|
11926
|
+
const [pinned, setPinned] = useState13(false);
|
|
11927
|
+
const tooltipContent = useMemo19(
|
|
11555
11928
|
() => resolveHotspotTooltipContent(tooltip),
|
|
11556
11929
|
[tooltip]
|
|
11557
11930
|
);
|
|
@@ -11573,22 +11946,26 @@ function HotspotAnchor({
|
|
|
11573
11946
|
scaledWidth,
|
|
11574
11947
|
scaledHeight
|
|
11575
11948
|
);
|
|
11576
|
-
const worldPosition =
|
|
11949
|
+
const worldPosition = useMemo19(
|
|
11577
11950
|
() => panoPositionToVector3(normalizedPosition, resolvedDistance),
|
|
11578
11951
|
[normalizedPosition.pitch, normalizedPosition.yaw, resolvedDistance]
|
|
11579
11952
|
);
|
|
11580
|
-
const surfaceQuaternion3 =
|
|
11953
|
+
const surfaceQuaternion3 = useMemo19(
|
|
11581
11954
|
() => createSurfaceQuaternion(normalizedPosition),
|
|
11582
11955
|
[normalizedPosition.pitch, normalizedPosition.yaw]
|
|
11583
11956
|
);
|
|
11584
11957
|
const worldWidth = angularSizeToWorldSize(scaledWidth, resolvedDistance);
|
|
11585
11958
|
const worldHeight = angularSizeToWorldSize(scaledHeight, resolvedDistance);
|
|
11586
|
-
const focusGeometry =
|
|
11959
|
+
const focusGeometry = useMemo19(() => {
|
|
11587
11960
|
const planeGeometry = new PlaneGeometry4(1, 1);
|
|
11588
11961
|
const geometry = new EdgesGeometry(planeGeometry);
|
|
11589
11962
|
planeGeometry.dispose();
|
|
11590
11963
|
return geometry;
|
|
11591
11964
|
}, []);
|
|
11965
|
+
const eventHovered = useRef25(false);
|
|
11966
|
+
useEffect24(() => {
|
|
11967
|
+
if (!visible || !interactive || pointerEvents === "none") eventHovered.current = false;
|
|
11968
|
+
}, [visible, interactive, pointerEvents]);
|
|
11592
11969
|
const acceptsPointer = acceptsHotspotPointerEvents(interactive, pointerEvents);
|
|
11593
11970
|
const canActivateFromKeyboard = Boolean(
|
|
11594
11971
|
visible && interactive && (onClick || tooltipTrigger === "click")
|
|
@@ -11673,7 +12050,7 @@ function HotspotAnchor({
|
|
|
11673
12050
|
dragStateRef.current = null;
|
|
11674
12051
|
setDragging(false);
|
|
11675
12052
|
}, [acceptsPointer]);
|
|
11676
|
-
|
|
12053
|
+
useLayoutEffect7(() => {
|
|
11677
12054
|
const group = groupRef.current;
|
|
11678
12055
|
if (!group) {
|
|
11679
12056
|
return;
|
|
@@ -11716,7 +12093,7 @@ function HotspotAnchor({
|
|
|
11716
12093
|
worldHeight,
|
|
11717
12094
|
worldWidth
|
|
11718
12095
|
]);
|
|
11719
|
-
|
|
12096
|
+
useFrame14((state) => {
|
|
11720
12097
|
const group = groupRef.current;
|
|
11721
12098
|
if (!group) {
|
|
11722
12099
|
return;
|
|
@@ -11834,6 +12211,13 @@ function HotspotAnchor({
|
|
|
11834
12211
|
} : void 0,
|
|
11835
12212
|
onPointerOut: acceptsPointer ? (event) => {
|
|
11836
12213
|
if (!dragStateRef.current) {
|
|
12214
|
+
if (!visible || event.nativeEvent.pointerType === "touch" || !eventHovered.current) return;
|
|
12215
|
+
const inside = event.intersections.some(({ object }) => {
|
|
12216
|
+
for (let node = object; node; node = node.parent) if (node === groupRef.current) return true;
|
|
12217
|
+
return false;
|
|
12218
|
+
});
|
|
12219
|
+
if (inside) return;
|
|
12220
|
+
eventHovered.current = false;
|
|
11837
12221
|
setHovered(false);
|
|
11838
12222
|
onHoverChange?.(
|
|
11839
12223
|
false,
|
|
@@ -11843,6 +12227,8 @@ function HotspotAnchor({
|
|
|
11843
12227
|
} : void 0,
|
|
11844
12228
|
onPointerOver: acceptsPointer ? (event) => {
|
|
11845
12229
|
if (!dragStateRef.current) {
|
|
12230
|
+
if (!visible || event.nativeEvent.pointerType === "touch" || eventHovered.current) return;
|
|
12231
|
+
eventHovered.current = true;
|
|
11846
12232
|
setHovered(true);
|
|
11847
12233
|
onHoverChange?.(
|
|
11848
12234
|
true,
|
|
@@ -11852,18 +12238,28 @@ function HotspotAnchor({
|
|
|
11852
12238
|
} : void 0,
|
|
11853
12239
|
onPointerUp: acceptsPointer ? (event) => releasePointer(event, true) : void 0,
|
|
11854
12240
|
children: [
|
|
11855
|
-
focused ? focusContent ?? /* @__PURE__ */
|
|
12241
|
+
focused ? focusContent ?? /* @__PURE__ */ jsx26(
|
|
11856
12242
|
"lineSegments",
|
|
11857
12243
|
{
|
|
11858
12244
|
geometry: focusGeometry,
|
|
11859
12245
|
position: [0, 0, 0.01],
|
|
11860
12246
|
renderOrder: renderOrder + 1,
|
|
11861
12247
|
scale: [1.12, 1.12, 1],
|
|
11862
|
-
children: /* @__PURE__ */
|
|
12248
|
+
children: /* @__PURE__ */ jsx26("lineBasicMaterial", { color: "#f5fbfc", depthTest: false })
|
|
11863
12249
|
}
|
|
11864
12250
|
) : null,
|
|
11865
12251
|
children,
|
|
11866
|
-
|
|
12252
|
+
selected && useAngularScale ? /* @__PURE__ */ jsx26(
|
|
12253
|
+
HotspotStrokeLine,
|
|
12254
|
+
{
|
|
12255
|
+
points: SELECTION_BORDER_POINTS,
|
|
12256
|
+
color: "#ffb300",
|
|
12257
|
+
lineWidth: 3,
|
|
12258
|
+
opacity: 1,
|
|
12259
|
+
renderOrder: renderOrder + 1
|
|
12260
|
+
}
|
|
12261
|
+
) : null,
|
|
12262
|
+
tooltipOpen && tooltipContent ? /* @__PURE__ */ jsx26("group", { ref: tooltipAnchorRef, children: /* @__PURE__ */ jsx26(
|
|
11867
12263
|
HotspotTooltip,
|
|
11868
12264
|
{
|
|
11869
12265
|
appearance: tooltipAppearance,
|
|
@@ -11884,7 +12280,7 @@ import {
|
|
|
11884
12280
|
MeshBasicMaterial,
|
|
11885
12281
|
Vector2 as Vector24
|
|
11886
12282
|
} from "three";
|
|
11887
|
-
import { jsx as
|
|
12283
|
+
import { jsx as jsx27, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
11888
12284
|
var HOTSPOT_ALPHA_CUTOFF = 0.05;
|
|
11889
12285
|
var SAMPLE_UV = new Vector24();
|
|
11890
12286
|
var RAYCAST_HITS = [];
|
|
@@ -11987,8 +12383,8 @@ function HotspotPlane({
|
|
|
11987
12383
|
opacity
|
|
11988
12384
|
}) {
|
|
11989
12385
|
return /* @__PURE__ */ jsxs16("mesh", { raycast: hotspotPlaneRaycast, children: [
|
|
11990
|
-
/* @__PURE__ */
|
|
11991
|
-
/* @__PURE__ */
|
|
12386
|
+
/* @__PURE__ */ jsx27("planeGeometry", { args: [1, 1] }),
|
|
12387
|
+
/* @__PURE__ */ jsx27(
|
|
11992
12388
|
PanoBasicMaterial,
|
|
11993
12389
|
{
|
|
11994
12390
|
target: "hotspot",
|
|
@@ -12004,12 +12400,12 @@ function HotspotPlane({
|
|
|
12004
12400
|
}
|
|
12005
12401
|
|
|
12006
12402
|
// src/hotspot/image-hotspot.tsx
|
|
12007
|
-
import { jsx as
|
|
12403
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
12008
12404
|
function useHotspotImageTexture(src, onLoad, onError) {
|
|
12009
|
-
const gl =
|
|
12010
|
-
const [texture, setTexture] =
|
|
12011
|
-
const onLoadRef =
|
|
12012
|
-
const onErrorRef =
|
|
12405
|
+
const gl = useThree20((state) => state.gl);
|
|
12406
|
+
const [texture, setTexture] = useState14(null);
|
|
12407
|
+
const onLoadRef = useRef26(onLoad);
|
|
12408
|
+
const onErrorRef = useRef26(onError);
|
|
12013
12409
|
onLoadRef.current = onLoad;
|
|
12014
12410
|
onErrorRef.current = onError;
|
|
12015
12411
|
useEffect25(() => {
|
|
@@ -12068,11 +12464,11 @@ function ImageHotspot({
|
|
|
12068
12464
|
...anchorProps
|
|
12069
12465
|
}) {
|
|
12070
12466
|
const texture = useHotspotImageTexture(src, onLoad, onError);
|
|
12071
|
-
return /* @__PURE__ */
|
|
12467
|
+
return /* @__PURE__ */ jsx28(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ jsx28(HotspotPlane, { map: texture, opacity }) });
|
|
12072
12468
|
}
|
|
12073
12469
|
|
|
12074
12470
|
// src/hotspot/graphic-hotspot.tsx
|
|
12075
|
-
import { useEffect as useEffect26, useRef as
|
|
12471
|
+
import { useEffect as useEffect26, useRef as useRef27, useState as useState15 } from "react";
|
|
12076
12472
|
import {
|
|
12077
12473
|
CanvasTexture,
|
|
12078
12474
|
ClampToEdgeWrapping as ClampToEdgeWrapping4,
|
|
@@ -12080,7 +12476,7 @@ import {
|
|
|
12080
12476
|
LinearMipmapLinearFilter as LinearMipmapLinearFilter3,
|
|
12081
12477
|
SRGBColorSpace as SRGBColorSpace5
|
|
12082
12478
|
} from "three";
|
|
12083
|
-
import { jsx as
|
|
12479
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
12084
12480
|
var GRAPHIC_TEXTURE_SIZE = 512;
|
|
12085
12481
|
function resolveStrokeWidth(value) {
|
|
12086
12482
|
return Number.isFinite(value) ? Math.max(value, 0) : 8;
|
|
@@ -12269,9 +12665,9 @@ function createGraphicTexture(graphic, aspectWidth, aspectHeight) {
|
|
|
12269
12665
|
return texture;
|
|
12270
12666
|
}
|
|
12271
12667
|
function useGraphicTexture(graphic, aspectWidth, aspectHeight, onLoad, onError) {
|
|
12272
|
-
const [texture, setTexture] =
|
|
12273
|
-
const onLoadRef =
|
|
12274
|
-
const onErrorRef =
|
|
12668
|
+
const [texture, setTexture] = useState15(null);
|
|
12669
|
+
const onLoadRef = useRef27(onLoad);
|
|
12670
|
+
const onErrorRef = useRef27(onError);
|
|
12275
12671
|
onLoadRef.current = onLoad;
|
|
12276
12672
|
onErrorRef.current = onError;
|
|
12277
12673
|
useEffect26(() => {
|
|
@@ -12300,20 +12696,20 @@ function CanvasGraphicHotspot({
|
|
|
12300
12696
|
...anchorProps
|
|
12301
12697
|
}) {
|
|
12302
12698
|
const texture = useGraphicTexture(graphic, width, height, onLoad, onError);
|
|
12303
|
-
return /* @__PURE__ */
|
|
12699
|
+
return /* @__PURE__ */ jsx29(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ jsx29(HotspotPlane, { map: texture, opacity }) });
|
|
12304
12700
|
}
|
|
12305
12701
|
function GraphicHotspot(props) {
|
|
12306
12702
|
const { graphic, ...restProps } = props;
|
|
12307
12703
|
if (graphic.kind === "svg") {
|
|
12308
12704
|
const imageProps = restProps;
|
|
12309
|
-
return /* @__PURE__ */
|
|
12705
|
+
return /* @__PURE__ */ jsx29(ImageHotspot, { ...imageProps, src: graphic.src });
|
|
12310
12706
|
}
|
|
12311
|
-
return /* @__PURE__ */
|
|
12707
|
+
return /* @__PURE__ */ jsx29(CanvasGraphicHotspot, { ...restProps, graphic });
|
|
12312
12708
|
}
|
|
12313
12709
|
|
|
12314
12710
|
// src/hotspot/sequence-hotspot.tsx
|
|
12315
|
-
import { useFrame as
|
|
12316
|
-
import { useEffect as useEffect27, useRef as
|
|
12711
|
+
import { useFrame as useFrame15, useThree as useThree21 } from "@react-three/fiber";
|
|
12712
|
+
import { useEffect as useEffect27, useRef as useRef28, useState as useState16 } from "react";
|
|
12317
12713
|
import {
|
|
12318
12714
|
ClampToEdgeWrapping as ClampToEdgeWrapping5,
|
|
12319
12715
|
LinearFilter as LinearFilter7,
|
|
@@ -12321,7 +12717,7 @@ import {
|
|
|
12321
12717
|
SRGBColorSpace as SRGBColorSpace6,
|
|
12322
12718
|
TextureLoader as TextureLoader5
|
|
12323
12719
|
} from "three";
|
|
12324
|
-
import { jsx as
|
|
12720
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
12325
12721
|
var DEFAULT_SEQUENCE_FPS = 12;
|
|
12326
12722
|
function resolveFps(value) {
|
|
12327
12723
|
return Number.isFinite(value) && value > 0 ? value : DEFAULT_SEQUENCE_FPS;
|
|
@@ -12335,10 +12731,10 @@ function useSpriteTexture({
|
|
|
12335
12731
|
onError,
|
|
12336
12732
|
onLoadProgress
|
|
12337
12733
|
}) {
|
|
12338
|
-
const gl =
|
|
12339
|
-
const [texture, setTexture] =
|
|
12340
|
-
const onErrorRef =
|
|
12341
|
-
const onLoadProgressRef =
|
|
12734
|
+
const gl = useThree21((state) => state.gl);
|
|
12735
|
+
const [texture, setTexture] = useState16(null);
|
|
12736
|
+
const onErrorRef = useRef28(onError);
|
|
12737
|
+
const onLoadProgressRef = useRef28(onLoadProgress);
|
|
12342
12738
|
onErrorRef.current = onError;
|
|
12343
12739
|
onLoadProgressRef.current = onLoadProgress;
|
|
12344
12740
|
useEffect27(() => {
|
|
@@ -12411,14 +12807,14 @@ function SequenceHotspot({
|
|
|
12411
12807
|
const texture = useSpriteTexture({ id, src, onError, onLoadProgress });
|
|
12412
12808
|
const frameCount = resolveFrameCount(requestedFrameCount);
|
|
12413
12809
|
const safeFps = resolveFps(fps);
|
|
12414
|
-
const [frameIndex, setFrameIndex] =
|
|
12415
|
-
const elapsedRef =
|
|
12416
|
-
const frameIndexRef =
|
|
12417
|
-
const endedRef =
|
|
12418
|
-
const lastPlaybackStateRef =
|
|
12419
|
-
const onFrameChangeRef =
|
|
12420
|
-
const onPlaybackStateChangeRef =
|
|
12421
|
-
const onEndedRef =
|
|
12810
|
+
const [frameIndex, setFrameIndex] = useState16(0);
|
|
12811
|
+
const elapsedRef = useRef28(0);
|
|
12812
|
+
const frameIndexRef = useRef28(0);
|
|
12813
|
+
const endedRef = useRef28(false);
|
|
12814
|
+
const lastPlaybackStateRef = useRef28(null);
|
|
12815
|
+
const onFrameChangeRef = useRef28(onFrameChange);
|
|
12816
|
+
const onPlaybackStateChangeRef = useRef28(onPlaybackStateChange);
|
|
12817
|
+
const onEndedRef = useRef28(onEnded);
|
|
12422
12818
|
onFrameChangeRef.current = onFrameChange;
|
|
12423
12819
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
12424
12820
|
onEndedRef.current = onEnded;
|
|
@@ -12467,7 +12863,7 @@ function SequenceHotspot({
|
|
|
12467
12863
|
onPlaybackStateChangeRef.current?.(nextState);
|
|
12468
12864
|
}
|
|
12469
12865
|
}, [playing, texture]);
|
|
12470
|
-
|
|
12866
|
+
useFrame15((_, deltaSeconds) => {
|
|
12471
12867
|
if (!texture || !playing || endedRef.current) {
|
|
12472
12868
|
return;
|
|
12473
12869
|
}
|
|
@@ -12497,12 +12893,12 @@ function SequenceHotspot({
|
|
|
12497
12893
|
onFrameChangeRef.current?.({ id, index: nextIndex, src });
|
|
12498
12894
|
}
|
|
12499
12895
|
});
|
|
12500
|
-
return /* @__PURE__ */
|
|
12896
|
+
return /* @__PURE__ */ jsx30(HotspotAnchor, { ...anchorProps, id, height, width, children: /* @__PURE__ */ jsx30(HotspotPlane, { map: texture, opacity }) });
|
|
12501
12897
|
}
|
|
12502
12898
|
|
|
12503
12899
|
// src/hotspot/video-hotspot.tsx
|
|
12504
|
-
import { useThree as
|
|
12505
|
-
import { useEffect as useEffect28, useLayoutEffect as
|
|
12900
|
+
import { useThree as useThree22 } from "@react-three/fiber";
|
|
12901
|
+
import { useEffect as useEffect28, useLayoutEffect as useLayoutEffect8, useRef as useRef29, useState as useState17 } from "react";
|
|
12506
12902
|
import {
|
|
12507
12903
|
ClampToEdgeWrapping as ClampToEdgeWrapping6,
|
|
12508
12904
|
LinearFilter as LinearFilter8,
|
|
@@ -12563,7 +12959,7 @@ function mountTextureVideo(video, canvas) {
|
|
|
12563
12959
|
}
|
|
12564
12960
|
|
|
12565
12961
|
// src/hotspot/video-hotspot.tsx
|
|
12566
|
-
import { jsx as
|
|
12962
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
12567
12963
|
function clampVolume2(volume) {
|
|
12568
12964
|
if (!Number.isFinite(volume)) {
|
|
12569
12965
|
return 1;
|
|
@@ -12571,9 +12967,9 @@ function clampVolume2(volume) {
|
|
|
12571
12967
|
return Math.max(0, Math.min(volume, 1));
|
|
12572
12968
|
}
|
|
12573
12969
|
function usePosterTexture(id, poster, onError) {
|
|
12574
|
-
const gl =
|
|
12575
|
-
const [texture, setTexture] =
|
|
12576
|
-
const onErrorRef =
|
|
12970
|
+
const gl = useThree22((state) => state.gl);
|
|
12971
|
+
const [texture, setTexture] = useState17(null);
|
|
12972
|
+
const onErrorRef = useRef29(onError);
|
|
12577
12973
|
onErrorRef.current = onError;
|
|
12578
12974
|
useEffect28(() => {
|
|
12579
12975
|
let active = true;
|
|
@@ -12630,11 +13026,11 @@ function useVideoResource({
|
|
|
12630
13026
|
poster,
|
|
12631
13027
|
src
|
|
12632
13028
|
}) {
|
|
12633
|
-
const gl =
|
|
12634
|
-
const [resource, setResource] =
|
|
12635
|
-
const onEndedRef =
|
|
12636
|
-
const onErrorRef =
|
|
12637
|
-
const onPlaybackStateChangeRef =
|
|
13029
|
+
const gl = useThree22((state) => state.gl);
|
|
13030
|
+
const [resource, setResource] = useState17(null);
|
|
13031
|
+
const onEndedRef = useRef29(onEnded);
|
|
13032
|
+
const onErrorRef = useRef29(onError);
|
|
13033
|
+
const onPlaybackStateChangeRef = useRef29(onPlaybackStateChange);
|
|
12638
13034
|
onEndedRef.current = onEnded;
|
|
12639
13035
|
onErrorRef.current = onError;
|
|
12640
13036
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
@@ -12708,7 +13104,7 @@ function useVideoResource({
|
|
|
12708
13104
|
texture.dispose();
|
|
12709
13105
|
};
|
|
12710
13106
|
}, [crossOrigin, gl, id, playsInline, poster, src]);
|
|
12711
|
-
|
|
13107
|
+
useLayoutEffect8(() => {
|
|
12712
13108
|
if (!resource) {
|
|
12713
13109
|
return;
|
|
12714
13110
|
}
|
|
@@ -12751,11 +13147,11 @@ function VideoHotspot({
|
|
|
12751
13147
|
src
|
|
12752
13148
|
});
|
|
12753
13149
|
const posterTexture = usePosterTexture(id, poster, onError);
|
|
12754
|
-
const onPlaybackErrorRef =
|
|
12755
|
-
const onPlaybackStateChangeRef =
|
|
13150
|
+
const onPlaybackErrorRef = useRef29(onPlaybackError);
|
|
13151
|
+
const onPlaybackStateChangeRef = useRef29(onPlaybackStateChange);
|
|
12756
13152
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
12757
13153
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
12758
|
-
|
|
13154
|
+
useLayoutEffect8(() => {
|
|
12759
13155
|
if (!resource) {
|
|
12760
13156
|
return;
|
|
12761
13157
|
}
|
|
@@ -12788,12 +13184,12 @@ function VideoHotspot({
|
|
|
12788
13184
|
};
|
|
12789
13185
|
}, [playing, resource]);
|
|
12790
13186
|
const activeTexture = resource?.ready ? resource.texture : posterTexture;
|
|
12791
|
-
return /* @__PURE__ */
|
|
13187
|
+
return /* @__PURE__ */ jsx31(HotspotAnchor, { ...anchorProps, id, height, width, children: /* @__PURE__ */ jsx31(HotspotPlane, { map: activeTexture, opacity }) });
|
|
12792
13188
|
}
|
|
12793
13189
|
|
|
12794
13190
|
// src/hotspot/audio-hotspot.tsx
|
|
12795
|
-
import { useFrame as
|
|
12796
|
-
import { useEffect as useEffect29, useRef as
|
|
13191
|
+
import { useFrame as useFrame16, useThree as useThree23 } from "@react-three/fiber";
|
|
13192
|
+
import { useEffect as useEffect29, useRef as useRef30, useState as useState18 } from "react";
|
|
12797
13193
|
import {
|
|
12798
13194
|
CanvasTexture as CanvasTexture2,
|
|
12799
13195
|
ClampToEdgeWrapping as ClampToEdgeWrapping7,
|
|
@@ -12804,10 +13200,10 @@ import {
|
|
|
12804
13200
|
} from "three";
|
|
12805
13201
|
|
|
12806
13202
|
// src/hotspot/audio-spatial.ts
|
|
12807
|
-
import { MathUtils as
|
|
12808
|
-
var LOOK_DIR = new
|
|
12809
|
-
var SOURCE_DIR = new
|
|
12810
|
-
var RIGHT_DIR = new
|
|
13203
|
+
import { MathUtils as MathUtils8, Vector3 as Vector316 } from "three";
|
|
13204
|
+
var LOOK_DIR = new Vector316();
|
|
13205
|
+
var SOURCE_DIR = new Vector316();
|
|
13206
|
+
var RIGHT_DIR = new Vector316();
|
|
12811
13207
|
function clampAudioVolume(volume) {
|
|
12812
13208
|
if (!Number.isFinite(volume)) {
|
|
12813
13209
|
return 1;
|
|
@@ -12832,11 +13228,11 @@ function lookRangeGain(angleDegrees, range) {
|
|
|
12832
13228
|
function audioSpatialFromView(camera, position, range) {
|
|
12833
13229
|
camera.getWorldDirection(LOOK_DIR);
|
|
12834
13230
|
SOURCE_DIR.copy(panoPositionToVector3(position)).normalize();
|
|
12835
|
-
const angleDegrees =
|
|
12836
|
-
Math.acos(
|
|
13231
|
+
const angleDegrees = MathUtils8.radToDeg(
|
|
13232
|
+
Math.acos(MathUtils8.clamp(LOOK_DIR.dot(SOURCE_DIR), -1, 1))
|
|
12837
13233
|
);
|
|
12838
13234
|
RIGHT_DIR.set(1, 0, 0).applyQuaternion(camera.quaternion);
|
|
12839
|
-
const pan =
|
|
13235
|
+
const pan = MathUtils8.clamp(
|
|
12840
13236
|
Math.atan2(SOURCE_DIR.dot(RIGHT_DIR), SOURCE_DIR.dot(LOOK_DIR)) / (Math.PI / 2),
|
|
12841
13237
|
-1,
|
|
12842
13238
|
1
|
|
@@ -12848,7 +13244,7 @@ function audioSpatialFromView(camera, position, range) {
|
|
|
12848
13244
|
}
|
|
12849
13245
|
|
|
12850
13246
|
// src/hotspot/audio-hotspot.tsx
|
|
12851
|
-
import { jsx as
|
|
13247
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
12852
13248
|
var SPEAKER_TEXTURE_SIZE = 512;
|
|
12853
13249
|
function paintSpeakerBody(context, center) {
|
|
12854
13250
|
context.fillStyle = "#f5fbfc";
|
|
@@ -12912,7 +13308,7 @@ function createSpeakerTexture(state) {
|
|
|
12912
13308
|
return texture;
|
|
12913
13309
|
}
|
|
12914
13310
|
function useSpeakerTextures(enabled) {
|
|
12915
|
-
const [textures, setTextures] =
|
|
13311
|
+
const [textures, setTextures] = useState18({ playing: null, stopped: null });
|
|
12916
13312
|
useEffect29(() => {
|
|
12917
13313
|
if (!enabled) {
|
|
12918
13314
|
setTextures({ playing: null, stopped: null });
|
|
@@ -12929,9 +13325,9 @@ function useSpeakerTextures(enabled) {
|
|
|
12929
13325
|
return textures;
|
|
12930
13326
|
}
|
|
12931
13327
|
function useIconTexture(icon, enabled, onError, id) {
|
|
12932
|
-
const gl =
|
|
12933
|
-
const [texture, setTexture] =
|
|
12934
|
-
const onErrorRef =
|
|
13328
|
+
const gl = useThree23((state) => state.gl);
|
|
13329
|
+
const [texture, setTexture] = useState18(null);
|
|
13330
|
+
const onErrorRef = useRef30(onError);
|
|
12935
13331
|
onErrorRef.current = onError;
|
|
12936
13332
|
useEffect29(() => {
|
|
12937
13333
|
let active = true;
|
|
@@ -12987,15 +13383,16 @@ function useAudioHowl({
|
|
|
12987
13383
|
onPlaybackError,
|
|
12988
13384
|
onPlaybackStateChange,
|
|
12989
13385
|
playing,
|
|
12990
|
-
src
|
|
13386
|
+
src,
|
|
13387
|
+
format
|
|
12991
13388
|
}) {
|
|
12992
|
-
const [howl, setHowl] =
|
|
12993
|
-
const playingRef =
|
|
12994
|
-
const loopRef =
|
|
12995
|
-
const onEndedRef =
|
|
12996
|
-
const onErrorRef =
|
|
12997
|
-
const onPlaybackErrorRef =
|
|
12998
|
-
const onPlaybackStateChangeRef =
|
|
13389
|
+
const [howl, setHowl] = useState18(null);
|
|
13390
|
+
const playingRef = useRef30(playing);
|
|
13391
|
+
const loopRef = useRef30(loop ?? false);
|
|
13392
|
+
const onEndedRef = useRef30(onEnded);
|
|
13393
|
+
const onErrorRef = useRef30(onError);
|
|
13394
|
+
const onPlaybackErrorRef = useRef30(onPlaybackError);
|
|
13395
|
+
const onPlaybackStateChangeRef = useRef30(onPlaybackStateChange);
|
|
12999
13396
|
playingRef.current = playing;
|
|
13000
13397
|
loopRef.current = loop ?? false;
|
|
13001
13398
|
onEndedRef.current = onEnded;
|
|
@@ -13003,6 +13400,7 @@ function useAudioHowl({
|
|
|
13003
13400
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
13004
13401
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
13005
13402
|
const sourcesKey = sourceList(src).join("\0");
|
|
13403
|
+
const formatsKey = sourceList(format).join("\0");
|
|
13006
13404
|
useEffect29(() => {
|
|
13007
13405
|
const sources = sourcesKey.length > 0 ? sourcesKey.split("\0") : [];
|
|
13008
13406
|
if (sources.length === 0) {
|
|
@@ -13012,6 +13410,7 @@ function useAudioHowl({
|
|
|
13012
13410
|
let active = true;
|
|
13013
13411
|
const handle = createUnlockingHowl({
|
|
13014
13412
|
src: sources,
|
|
13413
|
+
format: formatsKey ? formatsKey.split("\0") : void 0,
|
|
13015
13414
|
loop: loopRef.current,
|
|
13016
13415
|
crossOrigin,
|
|
13017
13416
|
isActive: () => active,
|
|
@@ -13039,7 +13438,7 @@ function useAudioHowl({
|
|
|
13039
13438
|
active = false;
|
|
13040
13439
|
handle.dispose();
|
|
13041
13440
|
};
|
|
13042
|
-
}, [crossOrigin, id, sourcesKey]);
|
|
13441
|
+
}, [crossOrigin, id, sourcesKey, formatsKey]);
|
|
13043
13442
|
useEffect29(() => {
|
|
13044
13443
|
howl?.loop(loop ?? false);
|
|
13045
13444
|
}, [howl, loop]);
|
|
@@ -13048,6 +13447,7 @@ function useAudioHowl({
|
|
|
13048
13447
|
function AudioHotspot({
|
|
13049
13448
|
id,
|
|
13050
13449
|
src,
|
|
13450
|
+
format,
|
|
13051
13451
|
playing,
|
|
13052
13452
|
loop = false,
|
|
13053
13453
|
muted = false,
|
|
@@ -13068,7 +13468,7 @@ function AudioHotspot({
|
|
|
13068
13468
|
...anchorProps
|
|
13069
13469
|
}) {
|
|
13070
13470
|
usePanoMediaActivationIntent(playing);
|
|
13071
|
-
const camera =
|
|
13471
|
+
const camera = useThree23((state) => state.camera);
|
|
13072
13472
|
const howl = useAudioHowl({
|
|
13073
13473
|
crossOrigin,
|
|
13074
13474
|
id,
|
|
@@ -13078,17 +13478,18 @@ function AudioHotspot({
|
|
|
13078
13478
|
onPlaybackError,
|
|
13079
13479
|
onPlaybackStateChange,
|
|
13080
13480
|
playing,
|
|
13081
|
-
src
|
|
13481
|
+
src,
|
|
13482
|
+
format
|
|
13082
13483
|
});
|
|
13083
13484
|
const speakerTextures = useSpeakerTextures(marker && !icon);
|
|
13084
13485
|
const stoppedIconTexture = useIconTexture(icon, marker, onError, id);
|
|
13085
13486
|
const playingIconTexture = useIconTexture(playingIcon, marker, onError, id);
|
|
13086
13487
|
const markerTexture = playing ? playingIconTexture ?? stoppedIconTexture ?? speakerTextures.playing : stoppedIconTexture ?? speakerTextures.stopped;
|
|
13087
|
-
const playingRef =
|
|
13488
|
+
const playingRef = useRef30(playing);
|
|
13088
13489
|
playingRef.current = playing;
|
|
13089
|
-
const mutedRef =
|
|
13090
|
-
const volumeRef =
|
|
13091
|
-
const rangeRef =
|
|
13490
|
+
const mutedRef = useRef30(muted);
|
|
13491
|
+
const volumeRef = useRef30(volume);
|
|
13492
|
+
const rangeRef = useRef30(range);
|
|
13092
13493
|
mutedRef.current = muted;
|
|
13093
13494
|
volumeRef.current = volume;
|
|
13094
13495
|
rangeRef.current = range;
|
|
@@ -13120,7 +13521,7 @@ function AudioHotspot({
|
|
|
13120
13521
|
document.removeEventListener("visibilitychange", handleVisibility);
|
|
13121
13522
|
};
|
|
13122
13523
|
}, [howl, pauseWhenHidden]);
|
|
13123
|
-
|
|
13524
|
+
useFrame16(() => {
|
|
13124
13525
|
if (!howl) {
|
|
13125
13526
|
return;
|
|
13126
13527
|
}
|
|
@@ -13133,21 +13534,21 @@ function AudioHotspot({
|
|
|
13133
13534
|
howl.mute(mutedRef.current);
|
|
13134
13535
|
howl.volume(clampAudioVolume(volumeRef.current) * spatial.gain);
|
|
13135
13536
|
});
|
|
13136
|
-
return /* @__PURE__ */
|
|
13537
|
+
return /* @__PURE__ */ jsx32(HotspotAnchor, { ...anchorProps, id, height, width, children: marker ? /* @__PURE__ */ jsx32(HotspotPlane, { map: markerTexture, opacity }) : null });
|
|
13137
13538
|
}
|
|
13138
13539
|
|
|
13139
13540
|
// src/hotspot/text-hotspot.tsx
|
|
13140
|
-
import { useEffect as useEffect30, useRef as
|
|
13141
|
-
import { useFrame as
|
|
13541
|
+
import { useEffect as useEffect30, useRef as useRef31, useState as useState19 } from "react";
|
|
13542
|
+
import { useFrame as useFrame17, useThree as useThree24 } from "@react-three/fiber";
|
|
13142
13543
|
import {
|
|
13143
13544
|
CanvasTexture as CanvasTexture3,
|
|
13144
13545
|
ClampToEdgeWrapping as ClampToEdgeWrapping8,
|
|
13145
13546
|
LinearFilter as LinearFilter10,
|
|
13146
|
-
MathUtils as
|
|
13147
|
-
PerspectiveCamera as
|
|
13547
|
+
MathUtils as MathUtils9,
|
|
13548
|
+
PerspectiveCamera as PerspectiveCamera7,
|
|
13148
13549
|
SRGBColorSpace as SRGBColorSpace9
|
|
13149
13550
|
} from "three";
|
|
13150
|
-
import { jsx as
|
|
13551
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
13151
13552
|
var TEXT_TEXTURE_LONG_SIDE = 1024;
|
|
13152
13553
|
var TEXT_RASTER_SUPERSAMPLE = 2;
|
|
13153
13554
|
var TEXT_RASTER_MAX_LONG_SIDE = 4096;
|
|
@@ -13218,7 +13619,7 @@ function projectedDevicePixels(angleDeg, fovDeg, viewportHeight) {
|
|
|
13218
13619
|
}
|
|
13219
13620
|
const fov = Math.min(179, Math.max(1, resolvePositive(fovDeg, DEFAULT_REFERENCE_FOV2)));
|
|
13220
13621
|
const angle = Math.min(179, Math.max(0.01, Math.abs(angleDeg)));
|
|
13221
|
-
return Math.tan(
|
|
13622
|
+
return Math.tan(MathUtils9.degToRad(angle) / 2) / Math.tan(MathUtils9.degToRad(fov) / 2) * viewportHeight;
|
|
13222
13623
|
}
|
|
13223
13624
|
function snapRasterLongSide(screenLong, layoutLong) {
|
|
13224
13625
|
if (!(screenLong > 0)) {
|
|
@@ -13414,13 +13815,13 @@ function createTextTexture(text, width, height, style, rasterLong) {
|
|
|
13414
13815
|
return texture;
|
|
13415
13816
|
}
|
|
13416
13817
|
function useRasterLongSide(width, height, scale, scaleMode, referenceFov) {
|
|
13417
|
-
const size =
|
|
13418
|
-
const camera =
|
|
13419
|
-
const getPixelRatio =
|
|
13818
|
+
const size = useThree24((state) => state.size);
|
|
13819
|
+
const camera = useThree24((state) => state.camera);
|
|
13820
|
+
const getPixelRatio = useThree24((state) => state.gl.getPixelRatio);
|
|
13420
13821
|
const measure = () => {
|
|
13421
13822
|
const pixelRatio = getPixelRatio();
|
|
13422
13823
|
const viewportHeight = size.height * (Number.isFinite(pixelRatio) && pixelRatio > 0 ? pixelRatio : 1);
|
|
13423
|
-
const cameraFov = camera instanceof
|
|
13824
|
+
const cameraFov = camera instanceof PerspectiveCamera7 ? camera.fov : DEFAULT_REFERENCE_FOV2;
|
|
13424
13825
|
const screenLong = Math.max(
|
|
13425
13826
|
projectedDevicePixels(
|
|
13426
13827
|
width * resolveScale2(scale),
|
|
@@ -13439,12 +13840,12 @@ function useRasterLongSide(width, height, scale, scaleMode, referenceFov) {
|
|
|
13439
13840
|
Math.max(layout.canvasWidth, layout.canvasHeight)
|
|
13440
13841
|
);
|
|
13441
13842
|
};
|
|
13442
|
-
const [rasterLong, setRasterLong] =
|
|
13843
|
+
const [rasterLong, setRasterLong] = useState19(measure);
|
|
13443
13844
|
const measured = measure();
|
|
13444
13845
|
if (measured !== rasterLong) {
|
|
13445
13846
|
setRasterLong(measured);
|
|
13446
13847
|
}
|
|
13447
|
-
|
|
13848
|
+
useFrame17(() => {
|
|
13448
13849
|
const next = measure();
|
|
13449
13850
|
setRasterLong((current) => current === next ? current : next);
|
|
13450
13851
|
});
|
|
@@ -13452,9 +13853,9 @@ function useRasterLongSide(width, height, scale, scaleMode, referenceFov) {
|
|
|
13452
13853
|
}
|
|
13453
13854
|
function useTextTexture(text, width, height, style, scale, scaleMode, referenceFov, onLoad, onError) {
|
|
13454
13855
|
const rasterLong = useRasterLongSide(width, height, scale, scaleMode, referenceFov);
|
|
13455
|
-
const [texture, setTexture] =
|
|
13456
|
-
const onLoadRef =
|
|
13457
|
-
const onErrorRef =
|
|
13856
|
+
const [texture, setTexture] = useState19(null);
|
|
13857
|
+
const onLoadRef = useRef31(onLoad);
|
|
13858
|
+
const onErrorRef = useRef31(onError);
|
|
13458
13859
|
onLoadRef.current = onLoad;
|
|
13459
13860
|
onErrorRef.current = onError;
|
|
13460
13861
|
useEffect30(() => {
|
|
@@ -13567,13 +13968,13 @@ function TextHotspot({
|
|
|
13567
13968
|
onLoad,
|
|
13568
13969
|
onError
|
|
13569
13970
|
);
|
|
13570
|
-
return /* @__PURE__ */
|
|
13971
|
+
return /* @__PURE__ */ jsx33(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ jsx33(HotspotPlane, { map: texture, opacity }) });
|
|
13571
13972
|
}
|
|
13572
13973
|
|
|
13573
13974
|
// src/hotspot/iframe-hotspot.tsx
|
|
13574
13975
|
import { Html } from "@react-three/drei";
|
|
13575
13976
|
import { DoubleSide as DoubleSide4 } from "three";
|
|
13576
|
-
import { jsx as
|
|
13977
|
+
import { jsx as jsx34, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
13577
13978
|
var IFRAME_LONG_SIDE = 800;
|
|
13578
13979
|
var CSS3D_DISTANCE_FACTOR = 400;
|
|
13579
13980
|
var DEFAULT_SANDBOX = "allow-scripts allow-popups allow-forms";
|
|
@@ -13640,8 +14041,8 @@ function IframeHotspot({
|
|
|
13640
14041
|
width,
|
|
13641
14042
|
children: [
|
|
13642
14043
|
/* @__PURE__ */ jsxs17("mesh", { children: [
|
|
13643
|
-
/* @__PURE__ */
|
|
13644
|
-
/* @__PURE__ */
|
|
14044
|
+
/* @__PURE__ */ jsx34("planeGeometry", { args: [1, 1] }),
|
|
14045
|
+
/* @__PURE__ */ jsx34(
|
|
13645
14046
|
"meshBasicMaterial",
|
|
13646
14047
|
{
|
|
13647
14048
|
depthWrite: false,
|
|
@@ -13652,7 +14053,7 @@ function IframeHotspot({
|
|
|
13652
14053
|
}
|
|
13653
14054
|
)
|
|
13654
14055
|
] }),
|
|
13655
|
-
/* @__PURE__ */
|
|
14056
|
+
/* @__PURE__ */ jsx34(
|
|
13656
14057
|
Html,
|
|
13657
14058
|
{
|
|
13658
14059
|
distanceFactor: CSS3D_DISTANCE_FACTOR,
|
|
@@ -13667,7 +14068,7 @@ function IframeHotspot({
|
|
|
13667
14068
|
},
|
|
13668
14069
|
transform: true,
|
|
13669
14070
|
zIndexRange: [10, 0],
|
|
13670
|
-
children: /* @__PURE__ */
|
|
14071
|
+
children: /* @__PURE__ */ jsx34(
|
|
13671
14072
|
"iframe",
|
|
13672
14073
|
{
|
|
13673
14074
|
allow,
|
|
@@ -13689,7 +14090,7 @@ function IframeHotspot({
|
|
|
13689
14090
|
}
|
|
13690
14091
|
|
|
13691
14092
|
// src/hotspot/polygon-hotspot.tsx
|
|
13692
|
-
import { useEffect as useEffect31, useMemo as
|
|
14093
|
+
import { useEffect as useEffect31, useMemo as useMemo20, useRef as useRef32 } from "react";
|
|
13693
14094
|
import {
|
|
13694
14095
|
BufferGeometry as BufferGeometry2,
|
|
13695
14096
|
DoubleSide as DoubleSide5,
|
|
@@ -13700,85 +14101,7 @@ import {
|
|
|
13700
14101
|
Vector2 as Vector25,
|
|
13701
14102
|
Vector3 as Vector317
|
|
13702
14103
|
} from "three";
|
|
13703
|
-
|
|
13704
|
-
// src/hotspot/hotspot-stroke-line.tsx
|
|
13705
|
-
import { Line } from "@react-three/drei";
|
|
13706
|
-
import { useFrame as useFrame17, useThree as useThree24 } from "@react-three/fiber";
|
|
13707
|
-
import { useLayoutEffect as useLayoutEffect6, useRef as useRef31 } from "react";
|
|
13708
|
-
import {
|
|
13709
|
-
MathUtils as MathUtils9,
|
|
13710
|
-
PerspectiveCamera as PerspectiveCamera7,
|
|
13711
|
-
Vector3 as Vector316
|
|
13712
|
-
} from "three";
|
|
13713
|
-
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
13714
|
-
var LINE_WORLD_POSITION = new Vector316();
|
|
13715
|
-
function applyScreenSpaceDashScale(object, camera, viewportHeight) {
|
|
13716
|
-
const material = object?.material;
|
|
13717
|
-
if (!object || typeof material?.dashScale !== "number") {
|
|
13718
|
-
return;
|
|
13719
|
-
}
|
|
13720
|
-
object.getWorldPosition(LINE_WORLD_POSITION);
|
|
13721
|
-
const depth = Math.max(camera.position.distanceTo(LINE_WORLD_POSITION), 1);
|
|
13722
|
-
const fov = camera instanceof PerspectiveCamera7 ? camera.fov : 75;
|
|
13723
|
-
material.dashScale = viewportHeight / (2 * Math.tan(MathUtils9.degToRad(fov) * 0.5) * depth);
|
|
13724
|
-
}
|
|
13725
|
-
function resolveDash(dashSize, gapSize) {
|
|
13726
|
-
if (dashSize === void 0 || !Number.isFinite(dashSize) || dashSize <= 0) {
|
|
13727
|
-
return { dashed: false, dashSize: 1, gapSize: 1 };
|
|
13728
|
-
}
|
|
13729
|
-
return {
|
|
13730
|
-
dashed: true,
|
|
13731
|
-
dashSize,
|
|
13732
|
-
gapSize: Number.isFinite(gapSize) ? Math.max(0, gapSize) : dashSize
|
|
13733
|
-
};
|
|
13734
|
-
}
|
|
13735
|
-
function HotspotStrokeLine({
|
|
13736
|
-
points,
|
|
13737
|
-
color,
|
|
13738
|
-
lineWidth,
|
|
13739
|
-
opacity,
|
|
13740
|
-
renderOrder,
|
|
13741
|
-
dashSize,
|
|
13742
|
-
gapSize
|
|
13743
|
-
}) {
|
|
13744
|
-
const lineRef = useRef31(null);
|
|
13745
|
-
const { camera, size } = useThree24();
|
|
13746
|
-
const dash = resolveDash(dashSize, gapSize);
|
|
13747
|
-
useLayoutEffect6(() => {
|
|
13748
|
-
if (!dash.dashed) {
|
|
13749
|
-
return;
|
|
13750
|
-
}
|
|
13751
|
-
applyScreenSpaceDashScale(lineRef.current, camera, size.height);
|
|
13752
|
-
}, [camera, dash.dashed, dash.dashSize, dash.gapSize, size.height]);
|
|
13753
|
-
useFrame17((state) => {
|
|
13754
|
-
if (!dash.dashed) {
|
|
13755
|
-
return;
|
|
13756
|
-
}
|
|
13757
|
-
applyScreenSpaceDashScale(lineRef.current, state.camera, state.size.height);
|
|
13758
|
-
});
|
|
13759
|
-
return /* @__PURE__ */ jsx33(
|
|
13760
|
-
Line,
|
|
13761
|
-
{
|
|
13762
|
-
ref: lineRef,
|
|
13763
|
-
alphaToCoverage: true,
|
|
13764
|
-
color,
|
|
13765
|
-
dashed: dash.dashed,
|
|
13766
|
-
dashSize: dash.dashSize,
|
|
13767
|
-
depthTest: true,
|
|
13768
|
-
depthWrite: false,
|
|
13769
|
-
gapSize: dash.gapSize,
|
|
13770
|
-
lineWidth: Math.max(0.5, lineWidth),
|
|
13771
|
-
opacity,
|
|
13772
|
-
points,
|
|
13773
|
-
renderOrder,
|
|
13774
|
-
transparent: true,
|
|
13775
|
-
worldUnits: false
|
|
13776
|
-
}
|
|
13777
|
-
);
|
|
13778
|
-
}
|
|
13779
|
-
|
|
13780
|
-
// src/hotspot/polygon-hotspot.tsx
|
|
13781
|
-
import { jsx as jsx34, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
14104
|
+
import { jsx as jsx35, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
13782
14105
|
var POLYGON_RADIUS = 990;
|
|
13783
14106
|
var MAX_FILL_SEGMENT_DEGREES = 7;
|
|
13784
14107
|
function cloneVertices(vertices) {
|
|
@@ -14008,10 +14331,10 @@ function makeStrokePositions(vertices, center) {
|
|
|
14008
14331
|
return points;
|
|
14009
14332
|
}
|
|
14010
14333
|
function translateVertices(vertices, from, to) {
|
|
14011
|
-
const
|
|
14334
|
+
const yawOffset2 = normalizePanoYaw(to.yaw - from.yaw);
|
|
14012
14335
|
const pitchOffset = to.pitch - from.pitch;
|
|
14013
14336
|
return vertices.map((vertex) => ({
|
|
14014
|
-
yaw: normalizePanoYaw(vertex.yaw +
|
|
14337
|
+
yaw: normalizePanoYaw(vertex.yaw + yawOffset2),
|
|
14015
14338
|
pitch: clampPanoPitch(vertex.pitch + pitchOffset)
|
|
14016
14339
|
}));
|
|
14017
14340
|
}
|
|
@@ -14034,14 +14357,14 @@ function PolygonHotspot({
|
|
|
14034
14357
|
onInvalid,
|
|
14035
14358
|
...anchorProps
|
|
14036
14359
|
}) {
|
|
14037
|
-
const issues =
|
|
14360
|
+
const issues = useMemo20(() => validatePolygonVertices(vertices), [vertices]);
|
|
14038
14361
|
const valid = issues.length === 0;
|
|
14039
|
-
const center =
|
|
14040
|
-
const fillGeometry =
|
|
14362
|
+
const center = useMemo20(() => valid ? polygonCenter(vertices) : null, [valid, vertices]);
|
|
14363
|
+
const fillGeometry = useMemo20(
|
|
14041
14364
|
() => valid && center ? makeFillGeometry(vertices, center) : null,
|
|
14042
14365
|
[center, valid, vertices]
|
|
14043
14366
|
);
|
|
14044
|
-
const strokePoints =
|
|
14367
|
+
const strokePoints = useMemo20(
|
|
14045
14368
|
() => valid && center ? makeStrokePositions(vertices, center) : null,
|
|
14046
14369
|
[center, valid, vertices]
|
|
14047
14370
|
);
|
|
@@ -14081,7 +14404,7 @@ function PolygonHotspot({
|
|
|
14081
14404
|
draggable,
|
|
14082
14405
|
interactive,
|
|
14083
14406
|
useAngularScale: false,
|
|
14084
|
-
focusContent: /* @__PURE__ */
|
|
14407
|
+
focusContent: /* @__PURE__ */ jsx35(
|
|
14085
14408
|
HotspotStrokeLine,
|
|
14086
14409
|
{
|
|
14087
14410
|
color: "#75cbd3",
|
|
@@ -14103,7 +14426,7 @@ function PolygonHotspot({
|
|
|
14103
14426
|
startVerticesRef.current = null;
|
|
14104
14427
|
},
|
|
14105
14428
|
children: [
|
|
14106
|
-
/* @__PURE__ */
|
|
14429
|
+
/* @__PURE__ */ jsx35("mesh", { geometry: fillGeometry, renderOrder, children: /* @__PURE__ */ jsx35(
|
|
14107
14430
|
"meshBasicMaterial",
|
|
14108
14431
|
{
|
|
14109
14432
|
color: fill,
|
|
@@ -14113,7 +14436,7 @@ function PolygonHotspot({
|
|
|
14113
14436
|
transparent: true
|
|
14114
14437
|
}
|
|
14115
14438
|
) }),
|
|
14116
|
-
/* @__PURE__ */
|
|
14439
|
+
/* @__PURE__ */ jsx35(
|
|
14117
14440
|
HotspotStrokeLine,
|
|
14118
14441
|
{
|
|
14119
14442
|
color: stroke,
|
|
@@ -14131,14 +14454,14 @@ function PolygonHotspot({
|
|
|
14131
14454
|
}
|
|
14132
14455
|
|
|
14133
14456
|
// src/hotspot/polyline-hotspot.tsx
|
|
14134
|
-
import { useEffect as useEffect32, useMemo as
|
|
14457
|
+
import { useEffect as useEffect32, useMemo as useMemo21, useRef as useRef33 } from "react";
|
|
14135
14458
|
import {
|
|
14136
14459
|
MathUtils as MathUtils10,
|
|
14137
14460
|
Matrix4 as Matrix46,
|
|
14138
14461
|
Quaternion as Quaternion5,
|
|
14139
14462
|
Vector3 as Vector318
|
|
14140
14463
|
} from "three";
|
|
14141
|
-
import { jsx as
|
|
14464
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
14142
14465
|
var POLYLINE_RADIUS = 990;
|
|
14143
14466
|
var MAX_SEGMENT_DEGREES = 7;
|
|
14144
14467
|
function cloneVertices2(vertices) {
|
|
@@ -14229,10 +14552,10 @@ function makeLinePositions(vertices, center) {
|
|
|
14229
14552
|
return points;
|
|
14230
14553
|
}
|
|
14231
14554
|
function translateVertices2(vertices, from, to) {
|
|
14232
|
-
const
|
|
14555
|
+
const yawOffset2 = normalizePanoYaw(to.yaw - from.yaw);
|
|
14233
14556
|
const pitchOffset = to.pitch - from.pitch;
|
|
14234
14557
|
return vertices.map((vertex) => ({
|
|
14235
|
-
yaw: normalizePanoYaw(vertex.yaw +
|
|
14558
|
+
yaw: normalizePanoYaw(vertex.yaw + yawOffset2),
|
|
14236
14559
|
pitch: clampPanoPitch(vertex.pitch + pitchOffset)
|
|
14237
14560
|
}));
|
|
14238
14561
|
}
|
|
@@ -14255,10 +14578,10 @@ function PolylineHotspot({
|
|
|
14255
14578
|
onInvalid,
|
|
14256
14579
|
...anchorProps
|
|
14257
14580
|
}) {
|
|
14258
|
-
const issues =
|
|
14581
|
+
const issues = useMemo21(() => validatePolylineVertices(vertices), [vertices]);
|
|
14259
14582
|
const valid = issues.length === 0;
|
|
14260
|
-
const center =
|
|
14261
|
-
const linePoints =
|
|
14583
|
+
const center = useMemo21(() => valid ? polylineCenter(vertices) : null, [valid, vertices]);
|
|
14584
|
+
const linePoints = useMemo21(
|
|
14262
14585
|
() => valid && center ? makeLinePositions(vertices, center) : null,
|
|
14263
14586
|
[center, valid, vertices]
|
|
14264
14587
|
);
|
|
@@ -14278,7 +14601,7 @@ function PolylineHotspot({
|
|
|
14278
14601
|
startPosition: event.startPosition
|
|
14279
14602
|
});
|
|
14280
14603
|
};
|
|
14281
|
-
return /* @__PURE__ */
|
|
14604
|
+
return /* @__PURE__ */ jsx36(
|
|
14282
14605
|
HotspotAnchor,
|
|
14283
14606
|
{
|
|
14284
14607
|
...anchorProps,
|
|
@@ -14292,7 +14615,7 @@ function PolylineHotspot({
|
|
|
14292
14615
|
renderOrder,
|
|
14293
14616
|
draggable,
|
|
14294
14617
|
useAngularScale: false,
|
|
14295
|
-
focusContent: /* @__PURE__ */
|
|
14618
|
+
focusContent: /* @__PURE__ */ jsx36(
|
|
14296
14619
|
HotspotStrokeLine,
|
|
14297
14620
|
{
|
|
14298
14621
|
color: "#75cbd3",
|
|
@@ -14313,7 +14636,7 @@ function PolylineHotspot({
|
|
|
14313
14636
|
emitVerticesChange(event, onDragEnd);
|
|
14314
14637
|
startVerticesRef.current = null;
|
|
14315
14638
|
},
|
|
14316
|
-
children: /* @__PURE__ */
|
|
14639
|
+
children: /* @__PURE__ */ jsx36(
|
|
14317
14640
|
HotspotStrokeLine,
|
|
14318
14641
|
{
|
|
14319
14642
|
color: stroke,
|
|
@@ -14330,13 +14653,14 @@ function PolylineHotspot({
|
|
|
14330
14653
|
}
|
|
14331
14654
|
|
|
14332
14655
|
// src/project-scenes.tsx
|
|
14333
|
-
import { jsx as
|
|
14656
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
14334
14657
|
function isMedia(hotspot) {
|
|
14335
14658
|
return hotspot.type === "audio" || hotspot.type === "video" || hotspot.type === "sequence";
|
|
14336
14659
|
}
|
|
14337
|
-
function handleProjectHotspotClick(hotspot, sceneId, interaction, callback, navigate, toggle) {
|
|
14660
|
+
function handleProjectHotspotClick(hotspot, sceneId, interaction, callback, navigate, toggle, execute, trigger = "click", onEvent) {
|
|
14338
14661
|
const nativeWasPrevented = interaction.nativeEvent.defaultPrevented;
|
|
14339
14662
|
const event = {
|
|
14663
|
+
trigger,
|
|
14340
14664
|
sceneId,
|
|
14341
14665
|
hotspot,
|
|
14342
14666
|
interaction,
|
|
@@ -14345,15 +14669,21 @@ function handleProjectHotspotClick(hotspot, sceneId, interaction, callback, navi
|
|
|
14345
14669
|
event.defaultPrevented = true;
|
|
14346
14670
|
}
|
|
14347
14671
|
};
|
|
14348
|
-
|
|
14672
|
+
onEvent?.(event);
|
|
14673
|
+
if (trigger === "click") callback?.(event);
|
|
14349
14674
|
if (event.defaultPrevented || !nativeWasPrevented && interaction.nativeEvent.defaultPrevented)
|
|
14350
14675
|
return;
|
|
14351
|
-
|
|
14352
|
-
|
|
14676
|
+
const action = hotspotAction(hotspot, trigger);
|
|
14677
|
+
if (action?.type === "scene") navigate(action.sceneId);
|
|
14678
|
+
else if (action) {
|
|
14679
|
+
if (!execute) throw new Error("No handler for hotspot action");
|
|
14680
|
+
return execute(action, event);
|
|
14681
|
+
} else if (trigger === "click" && isMedia(hotspot)) toggle();
|
|
14353
14682
|
}
|
|
14354
14683
|
function hotspotProps({
|
|
14355
14684
|
type: _type,
|
|
14356
14685
|
action: _action,
|
|
14686
|
+
events: _events,
|
|
14357
14687
|
label: _label,
|
|
14358
14688
|
...props
|
|
14359
14689
|
}) {
|
|
@@ -14363,13 +14693,14 @@ function ProjectHotspotSource({
|
|
|
14363
14693
|
hotspot,
|
|
14364
14694
|
playing,
|
|
14365
14695
|
onClick,
|
|
14696
|
+
onHoverChange,
|
|
14366
14697
|
onEnded,
|
|
14367
14698
|
onError
|
|
14368
14699
|
}) {
|
|
14369
|
-
const common = { ariaLabel: hotspot.label || hotspot.id, onClick };
|
|
14700
|
+
const common = { ariaLabel: hotspot.label || hotspot.id, onClick, onHoverChange };
|
|
14370
14701
|
switch (hotspot.type) {
|
|
14371
14702
|
case "image":
|
|
14372
|
-
return /* @__PURE__ */
|
|
14703
|
+
return /* @__PURE__ */ jsx37(
|
|
14373
14704
|
ImageHotspot,
|
|
14374
14705
|
{
|
|
14375
14706
|
...hotspotProps(hotspot),
|
|
@@ -14378,7 +14709,7 @@ function ProjectHotspotSource({
|
|
|
14378
14709
|
}
|
|
14379
14710
|
);
|
|
14380
14711
|
case "graphic":
|
|
14381
|
-
return /* @__PURE__ */
|
|
14712
|
+
return /* @__PURE__ */ jsx37(
|
|
14382
14713
|
GraphicHotspot,
|
|
14383
14714
|
{
|
|
14384
14715
|
...hotspotProps(hotspot),
|
|
@@ -14387,9 +14718,9 @@ function ProjectHotspotSource({
|
|
|
14387
14718
|
}
|
|
14388
14719
|
);
|
|
14389
14720
|
case "text":
|
|
14390
|
-
return /* @__PURE__ */
|
|
14721
|
+
return /* @__PURE__ */ jsx37(TextHotspot, { ...hotspotProps(hotspot), ...common, onError });
|
|
14391
14722
|
case "iframe":
|
|
14392
|
-
return /* @__PURE__ */
|
|
14723
|
+
return /* @__PURE__ */ jsx37(
|
|
14393
14724
|
IframeHotspot,
|
|
14394
14725
|
{
|
|
14395
14726
|
...hotspotProps(hotspot),
|
|
@@ -14399,11 +14730,11 @@ function ProjectHotspotSource({
|
|
|
14399
14730
|
}
|
|
14400
14731
|
);
|
|
14401
14732
|
case "polygon":
|
|
14402
|
-
return /* @__PURE__ */
|
|
14733
|
+
return /* @__PURE__ */ jsx37(PolygonHotspot, { ...hotspotProps(hotspot), ...common });
|
|
14403
14734
|
case "polyline":
|
|
14404
|
-
return /* @__PURE__ */
|
|
14735
|
+
return /* @__PURE__ */ jsx37(PolylineHotspot, { ...hotspotProps(hotspot), ...common });
|
|
14405
14736
|
case "sequence":
|
|
14406
|
-
return /* @__PURE__ */
|
|
14737
|
+
return /* @__PURE__ */ jsx37(
|
|
14407
14738
|
SequenceHotspot,
|
|
14408
14739
|
{
|
|
14409
14740
|
...hotspotProps(hotspot),
|
|
@@ -14414,7 +14745,7 @@ function ProjectHotspotSource({
|
|
|
14414
14745
|
}
|
|
14415
14746
|
);
|
|
14416
14747
|
case "video":
|
|
14417
|
-
return /* @__PURE__ */
|
|
14748
|
+
return /* @__PURE__ */ jsx37(
|
|
14418
14749
|
VideoHotspot,
|
|
14419
14750
|
{
|
|
14420
14751
|
...hotspotProps(hotspot),
|
|
@@ -14426,7 +14757,7 @@ function ProjectHotspotSource({
|
|
|
14426
14757
|
}
|
|
14427
14758
|
);
|
|
14428
14759
|
case "audio":
|
|
14429
|
-
return /* @__PURE__ */
|
|
14760
|
+
return /* @__PURE__ */ jsx37(
|
|
14430
14761
|
AudioHotspot,
|
|
14431
14762
|
{
|
|
14432
14763
|
...hotspotProps(hotspot),
|
|
@@ -14444,10 +14775,12 @@ function ProjectHotspot({
|
|
|
14444
14775
|
sceneId,
|
|
14445
14776
|
navigate,
|
|
14446
14777
|
onHotspotClick,
|
|
14778
|
+
onHotspotEvent,
|
|
14447
14779
|
onHotspotError,
|
|
14448
|
-
renderHotspot
|
|
14780
|
+
renderHotspot,
|
|
14781
|
+
execute
|
|
14449
14782
|
}) {
|
|
14450
|
-
const [playing, setPlaying] =
|
|
14783
|
+
const [playing, setPlaying] = useState20(
|
|
14451
14784
|
"playing" in hotspot ? hotspot.playing ?? false : false
|
|
14452
14785
|
);
|
|
14453
14786
|
const togglePlayback = () => setPlaying((value) => !value);
|
|
@@ -14455,20 +14788,26 @@ function ProjectHotspot({
|
|
|
14455
14788
|
if (isMedia(hotspot)) setPlaying(false);
|
|
14456
14789
|
onHotspotError?.({ sceneId, hotspot, error });
|
|
14457
14790
|
};
|
|
14458
|
-
const
|
|
14459
|
-
hotspot
|
|
14460
|
-
|
|
14461
|
-
|
|
14462
|
-
|
|
14463
|
-
|
|
14464
|
-
|
|
14465
|
-
|
|
14466
|
-
|
|
14791
|
+
const dispatch = (trigger, interaction) => {
|
|
14792
|
+
if (hotspot.visible === false || hotspot.interactive === false || interaction.source === "pointer" && hotspot.pointerEvents === "none") return;
|
|
14793
|
+
if (trigger !== "click" && (interaction.source !== "pointer" || "pointerType" in interaction.nativeEvent && interaction.nativeEvent.pointerType === "touch")) return;
|
|
14794
|
+
const failed = (error) => onHotspotError?.({ sceneId, hotspot, error, trigger });
|
|
14795
|
+
try {
|
|
14796
|
+
const result = handleProjectHotspotClick(hotspot, sceneId, interaction, onHotspotClick, navigate, togglePlayback, execute, trigger, onHotspotEvent);
|
|
14797
|
+
if (result) void Promise.resolve(result).catch(failed);
|
|
14798
|
+
} catch (error) {
|
|
14799
|
+
failed(error);
|
|
14800
|
+
}
|
|
14801
|
+
};
|
|
14802
|
+
const onClick = (event) => dispatch("click", event);
|
|
14803
|
+
const onHoverChange = (hovered, event) => dispatch(hovered ? "pointerenter" : "pointerleave", event);
|
|
14804
|
+
const renderDefault = () => /* @__PURE__ */ jsx37(
|
|
14467
14805
|
ProjectHotspotSource,
|
|
14468
14806
|
{
|
|
14469
14807
|
hotspot,
|
|
14470
14808
|
playing,
|
|
14471
14809
|
onClick,
|
|
14810
|
+
onHoverChange,
|
|
14472
14811
|
onEnded: () => setPlaying(false),
|
|
14473
14812
|
onError: reportError
|
|
14474
14813
|
}
|
|
@@ -14477,6 +14816,7 @@ function ProjectHotspot({
|
|
|
14477
14816
|
sceneId,
|
|
14478
14817
|
playing,
|
|
14479
14818
|
onClick,
|
|
14819
|
+
onHoverChange,
|
|
14480
14820
|
togglePlayback,
|
|
14481
14821
|
reportError,
|
|
14482
14822
|
renderDefault
|
|
@@ -14489,25 +14829,28 @@ function ProjectScenes({
|
|
|
14489
14829
|
onActiveSceneIdChange,
|
|
14490
14830
|
onSceneReady,
|
|
14491
14831
|
onHotspotClick,
|
|
14832
|
+
onHotspotEvent,
|
|
14492
14833
|
onHotspotError,
|
|
14834
|
+
onPopupRequest,
|
|
14835
|
+
onCustomAction,
|
|
14493
14836
|
renderHotspot,
|
|
14494
14837
|
...options
|
|
14495
14838
|
}) {
|
|
14496
|
-
const controls =
|
|
14839
|
+
const controls = useContext22(PanoramaViewContext);
|
|
14497
14840
|
if (!controls)
|
|
14498
14841
|
throw new Error("<ProjectScenes> must be rendered inside <PanoViewer>.");
|
|
14499
|
-
const [selection, setSelection] =
|
|
14842
|
+
const [selection, setSelection] = useState20({
|
|
14500
14843
|
project,
|
|
14501
14844
|
id: project.initialSceneId
|
|
14502
14845
|
});
|
|
14503
14846
|
if (selection.project !== project)
|
|
14504
14847
|
setSelection({ project, id: project.initialSceneId });
|
|
14505
14848
|
const currentId = activeSceneId ?? (selection.project === project ? selection.id : project.initialSceneId);
|
|
14506
|
-
const entries =
|
|
14849
|
+
const entries = useMemo22(
|
|
14507
14850
|
() => new Map(project.scenes.map((entry) => [entry.scene.id, entry])),
|
|
14508
14851
|
[project]
|
|
14509
14852
|
);
|
|
14510
|
-
const scenes =
|
|
14853
|
+
const scenes = useMemo22(
|
|
14511
14854
|
() => project.scenes.map((entry) => entry.scene),
|
|
14512
14855
|
[project]
|
|
14513
14856
|
);
|
|
@@ -14516,7 +14859,7 @@ function ProjectScenes({
|
|
|
14516
14859
|
if (activeSceneId === void 0) setSelection({ project, id });
|
|
14517
14860
|
onActiveSceneIdChange?.(id);
|
|
14518
14861
|
};
|
|
14519
|
-
return /* @__PURE__ */
|
|
14862
|
+
return /* @__PURE__ */ jsx37(
|
|
14520
14863
|
Scenes,
|
|
14521
14864
|
{
|
|
14522
14865
|
...options,
|
|
@@ -14528,12 +14871,27 @@ function ProjectScenes({
|
|
|
14528
14871
|
if (view) controls.current?.setView(view, { immediate: true });
|
|
14529
14872
|
onSceneReady?.(id);
|
|
14530
14873
|
},
|
|
14531
|
-
renderHotspots: (scene) => entries.get(scene.id)?.hotspots.map((hotspot) => /* @__PURE__ */
|
|
14874
|
+
renderHotspots: (scene) => entries.get(scene.id)?.hotspots.map((hotspot) => /* @__PURE__ */ jsx37(
|
|
14532
14875
|
ProjectHotspot,
|
|
14533
14876
|
{
|
|
14534
14877
|
hotspot,
|
|
14535
14878
|
sceneId: scene.id,
|
|
14536
14879
|
navigate,
|
|
14880
|
+
execute: (action, event) => {
|
|
14881
|
+
if (action.type === "view") {
|
|
14882
|
+
return controls.current?.lookTo(action.view, { fov: action.view.fov, duration: action.duration }).then(() => {
|
|
14883
|
+
});
|
|
14884
|
+
} else if (action.type === "custom") {
|
|
14885
|
+
if (!onCustomAction) throw new Error("Custom action requires an onCustomAction handler");
|
|
14886
|
+
return onCustomAction({ ...event, action });
|
|
14887
|
+
} else {
|
|
14888
|
+
const popup = project.popups?.find((entry) => entry.id === action.popupId);
|
|
14889
|
+
if (!popup) throw new Error(`Popup does not exist: ${action.popupId}`);
|
|
14890
|
+
if (!onPopupRequest) throw new Error("Popup action requires an onPopupRequest handler");
|
|
14891
|
+
onPopupRequest({ sceneId: scene.id, hotspot, popup });
|
|
14892
|
+
}
|
|
14893
|
+
},
|
|
14894
|
+
onHotspotEvent,
|
|
14537
14895
|
onHotspotClick,
|
|
14538
14896
|
onHotspotError,
|
|
14539
14897
|
renderHotspot
|
|
@@ -14545,7 +14903,7 @@ function ProjectScenes({
|
|
|
14545
14903
|
}
|
|
14546
14904
|
|
|
14547
14905
|
// src/background-audio.tsx
|
|
14548
|
-
import { useContext as
|
|
14906
|
+
import { useContext as useContext23, useEffect as useEffect33, useMemo as useMemo23, useRef as useRef34, useState as useState21 } from "react";
|
|
14549
14907
|
var DEFAULT_FADE_MS = 400;
|
|
14550
14908
|
function resolveFadeMs(value) {
|
|
14551
14909
|
if (!Number.isFinite(value)) {
|
|
@@ -14587,12 +14945,12 @@ function BackgroundAudio({
|
|
|
14587
14945
|
onEnded,
|
|
14588
14946
|
onError
|
|
14589
14947
|
}) {
|
|
14590
|
-
const controlsRef =
|
|
14948
|
+
const controlsRef = useContext23(PanoramaViewContext);
|
|
14591
14949
|
if (!controlsRef) {
|
|
14592
14950
|
throw new Error("<BackgroundAudio> must be rendered inside <PanoViewer>.");
|
|
14593
14951
|
}
|
|
14594
14952
|
const isControlled = controlledPlaying !== void 0;
|
|
14595
|
-
const [internalPlaying, setInternalPlaying] =
|
|
14953
|
+
const [internalPlaying, setInternalPlaying] = useState21(defaultPlaying);
|
|
14596
14954
|
const playing = isControlled ? controlledPlaying : internalPlaying;
|
|
14597
14955
|
const urls = resolveBackgroundAudioUrls(src, sources, sceneId);
|
|
14598
14956
|
usePanoMediaActivationIntent(playing && urls.length > 0);
|
|
@@ -14645,7 +15003,7 @@ function BackgroundAudio({
|
|
|
14645
15003
|
};
|
|
14646
15004
|
const isControlledRef = useRef34(isControlled);
|
|
14647
15005
|
isControlledRef.current = isControlled;
|
|
14648
|
-
const controller =
|
|
15006
|
+
const controller = useMemo23(
|
|
14649
15007
|
() => ({
|
|
14650
15008
|
subscribe: (onStoreChange) => {
|
|
14651
15009
|
snapshotListenersRef.current.add(onStoreChange);
|
|
@@ -14703,7 +15061,7 @@ function BackgroundAudio({
|
|
|
14703
15061
|
}),
|
|
14704
15062
|
[]
|
|
14705
15063
|
);
|
|
14706
|
-
const bgmHost =
|
|
15064
|
+
const bgmHost = useContext23(BackgroundAudioHostContext);
|
|
14707
15065
|
useEffect33(() => {
|
|
14708
15066
|
if (!bgmHost) {
|
|
14709
15067
|
return;
|
|
@@ -14893,7 +15251,7 @@ function BackgroundAudio({
|
|
|
14893
15251
|
}
|
|
14894
15252
|
|
|
14895
15253
|
// src/pano-filter/pano-filter.tsx
|
|
14896
|
-
import { useContext as
|
|
15254
|
+
import { useContext as useContext24, useEffect as useEffect34, useMemo as useMemo24 } from "react";
|
|
14897
15255
|
function PanoFilter({
|
|
14898
15256
|
preset = "none",
|
|
14899
15257
|
intensity,
|
|
@@ -14901,11 +15259,11 @@ function PanoFilter({
|
|
|
14901
15259
|
colorMatrix,
|
|
14902
15260
|
colorMatrixScope
|
|
14903
15261
|
}) {
|
|
14904
|
-
const host =
|
|
15262
|
+
const host = useContext24(PanoFilterHostContext);
|
|
14905
15263
|
if (!host) {
|
|
14906
15264
|
throw new Error("<PanoFilter> must be rendered inside <PanoViewer>.");
|
|
14907
15265
|
}
|
|
14908
|
-
const snapshot =
|
|
15266
|
+
const snapshot = useMemo24(
|
|
14909
15267
|
() => resolvePanoFilterSnapshot({
|
|
14910
15268
|
preset,
|
|
14911
15269
|
intensity,
|
|
@@ -14932,11 +15290,11 @@ import { useFrame as useFrame18, useThree as useThree25 } from "@react-three/fib
|
|
|
14932
15290
|
import {
|
|
14933
15291
|
forwardRef as forwardRef3,
|
|
14934
15292
|
useCallback as useCallback9,
|
|
14935
|
-
useContext as
|
|
15293
|
+
useContext as useContext25,
|
|
14936
15294
|
useEffect as useEffect35,
|
|
14937
15295
|
useImperativeHandle as useImperativeHandle3,
|
|
14938
15296
|
useRef as useRef35,
|
|
14939
|
-
useState as
|
|
15297
|
+
useState as useState22
|
|
14940
15298
|
} from "react";
|
|
14941
15299
|
|
|
14942
15300
|
// src/gyro-orientation.ts
|
|
@@ -15037,10 +15395,10 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
15037
15395
|
onDisable,
|
|
15038
15396
|
onDenied
|
|
15039
15397
|
}, ref) {
|
|
15040
|
-
const controlsRef =
|
|
15041
|
-
const eventBus =
|
|
15398
|
+
const controlsRef = useContext25(PanoramaViewContext);
|
|
15399
|
+
const eventBus = useContext25(PanoEventBusContext);
|
|
15042
15400
|
const { gl } = useThree25();
|
|
15043
|
-
const [internallyDisabled, setInternallyDisabled] =
|
|
15401
|
+
const [internallyDisabled, setInternallyDisabled] = useState22(false);
|
|
15044
15402
|
const availableRef = useRef35(false);
|
|
15045
15403
|
const availabilityReportedRef = useRef35(null);
|
|
15046
15404
|
const activeRef = useRef35(false);
|
|
@@ -15393,12 +15751,12 @@ import { useThree as useThree28 } from "@react-three/fiber";
|
|
|
15393
15751
|
import {
|
|
15394
15752
|
forwardRef as forwardRef4,
|
|
15395
15753
|
useCallback as useCallback10,
|
|
15396
|
-
useContext as
|
|
15754
|
+
useContext as useContext27,
|
|
15397
15755
|
useEffect as useEffect39,
|
|
15398
15756
|
useImperativeHandle as useImperativeHandle4,
|
|
15399
|
-
useMemo as
|
|
15757
|
+
useMemo as useMemo26,
|
|
15400
15758
|
useRef as useRef39,
|
|
15401
|
-
useState as
|
|
15759
|
+
useState as useState23
|
|
15402
15760
|
} from "react";
|
|
15403
15761
|
|
|
15404
15762
|
// src/webvr/detect.ts
|
|
@@ -15429,7 +15787,7 @@ import {
|
|
|
15429
15787
|
Vector2 as Vector26,
|
|
15430
15788
|
Vector3 as Vector320
|
|
15431
15789
|
} from "three";
|
|
15432
|
-
import { jsx as
|
|
15790
|
+
import { jsx as jsx38, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
15433
15791
|
var CENTER_NDC = new Vector26(0, 0);
|
|
15434
15792
|
var HUD_DISTANCE = 2;
|
|
15435
15793
|
var RETICLE_SCALE = 1;
|
|
@@ -15604,8 +15962,8 @@ function WebVRReticle({
|
|
|
15604
15962
|
raycast: noopRaycast,
|
|
15605
15963
|
renderOrder: RETICLE_RENDER_ORDER + 1,
|
|
15606
15964
|
children: [
|
|
15607
|
-
/* @__PURE__ */
|
|
15608
|
-
/* @__PURE__ */
|
|
15965
|
+
/* @__PURE__ */ jsx38("boxGeometry", { args: [CROSSHAIR_LENGTH, CROSSHAIR_THICKNESS, 1e-3] }),
|
|
15966
|
+
/* @__PURE__ */ jsx38(
|
|
15609
15967
|
"meshBasicMaterial",
|
|
15610
15968
|
{
|
|
15611
15969
|
color: "#ffffff",
|
|
@@ -15625,8 +15983,8 @@ function WebVRReticle({
|
|
|
15625
15983
|
raycast: noopRaycast,
|
|
15626
15984
|
renderOrder: RETICLE_RENDER_ORDER + 1,
|
|
15627
15985
|
children: [
|
|
15628
|
-
/* @__PURE__ */
|
|
15629
|
-
/* @__PURE__ */
|
|
15986
|
+
/* @__PURE__ */ jsx38("boxGeometry", { args: [CROSSHAIR_THICKNESS, CROSSHAIR_LENGTH, 1e-3] }),
|
|
15987
|
+
/* @__PURE__ */ jsx38(
|
|
15630
15988
|
"meshBasicMaterial",
|
|
15631
15989
|
{
|
|
15632
15990
|
color: "#ffffff",
|
|
@@ -15648,7 +16006,7 @@ function WebVRReticle({
|
|
|
15648
16006
|
renderOrder: RETICLE_RENDER_ORDER + 2,
|
|
15649
16007
|
visible: false,
|
|
15650
16008
|
children: [
|
|
15651
|
-
/* @__PURE__ */
|
|
16009
|
+
/* @__PURE__ */ jsx38(
|
|
15652
16010
|
"ringGeometry",
|
|
15653
16011
|
{
|
|
15654
16012
|
args: [
|
|
@@ -15661,7 +16019,7 @@ function WebVRReticle({
|
|
|
15661
16019
|
]
|
|
15662
16020
|
}
|
|
15663
16021
|
),
|
|
15664
|
-
/* @__PURE__ */
|
|
16022
|
+
/* @__PURE__ */ jsx38(
|
|
15665
16023
|
"meshBasicMaterial",
|
|
15666
16024
|
{
|
|
15667
16025
|
color: "#ffffff",
|
|
@@ -15682,7 +16040,7 @@ function WebVRReticle({
|
|
|
15682
16040
|
|
|
15683
16041
|
// src/webvr/stereo.tsx
|
|
15684
16042
|
import { useFrame as useFrame20, useThree as useThree27 } from "@react-three/fiber";
|
|
15685
|
-
import { useContext as
|
|
16043
|
+
import { useContext as useContext26, useEffect as useEffect36, useMemo as useMemo25, useRef as useRef37 } from "react";
|
|
15686
16044
|
import {
|
|
15687
16045
|
Mesh as Mesh6,
|
|
15688
16046
|
OrthographicCamera,
|
|
@@ -15768,7 +16126,7 @@ function WebVRStereoRenderer({
|
|
|
15768
16126
|
screensize
|
|
15769
16127
|
}) {
|
|
15770
16128
|
const { camera, gl } = useThree27();
|
|
15771
|
-
const runtime =
|
|
16129
|
+
const runtime = useContext26(WebVRRuntimeContext);
|
|
15772
16130
|
const fallbackStereoRef = useRef37(null);
|
|
15773
16131
|
if (!fallbackStereoRef.current) {
|
|
15774
16132
|
fallbackStereoRef.current = new StereoCamera2();
|
|
@@ -15776,7 +16134,7 @@ function WebVRStereoRenderer({
|
|
|
15776
16134
|
const stereo = runtime?.stereoView.stereo ?? fallbackStereoRef.current;
|
|
15777
16135
|
const stereoRef = useRef37(stereo);
|
|
15778
16136
|
stereoRef.current = stereo;
|
|
15779
|
-
const resources =
|
|
16137
|
+
const resources = useMemo25(createDistortionResources, []);
|
|
15780
16138
|
const drawingSizeRef = useRef37(new Vector27());
|
|
15781
16139
|
const viewportRef = useRef37(new Vector42());
|
|
15782
16140
|
const scissorRef = useRef37(new Vector42());
|
|
@@ -16108,7 +16466,7 @@ function useWebVRWakeLock(enabled) {
|
|
|
16108
16466
|
}
|
|
16109
16467
|
|
|
16110
16468
|
// src/webvr/webvr.tsx
|
|
16111
|
-
import { Fragment as Fragment6, jsx as
|
|
16469
|
+
import { Fragment as Fragment6, jsx as jsx39, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
16112
16470
|
function initializeSettings(screensize, profile) {
|
|
16113
16471
|
const stored = loadWebVRSettings();
|
|
16114
16472
|
return {
|
|
@@ -16137,9 +16495,9 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
16137
16495
|
onDenied,
|
|
16138
16496
|
onUnknownDevice
|
|
16139
16497
|
}, ref) {
|
|
16140
|
-
const runtime =
|
|
16141
|
-
const controlsRef =
|
|
16142
|
-
const eventBus =
|
|
16498
|
+
const runtime = useContext27(WebVRRuntimeContext);
|
|
16499
|
+
const controlsRef = useContext27(PanoramaViewContext);
|
|
16500
|
+
const eventBus = useContext27(PanoEventBusContext);
|
|
16143
16501
|
const gl = useThree28((state) => state.gl);
|
|
16144
16502
|
const gyroRef = useRef39(null);
|
|
16145
16503
|
const capabilitiesRef = useRef39({
|
|
@@ -16150,8 +16508,8 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
16150
16508
|
const availableRef = useRef39(false);
|
|
16151
16509
|
const modeRef = useRef39(null);
|
|
16152
16510
|
const webXRSessionRef = useRef39(null);
|
|
16153
|
-
const [mode, setMode] =
|
|
16154
|
-
const [settings, setSettings] =
|
|
16511
|
+
const [mode, setMode] = useState23(null);
|
|
16512
|
+
const [settings, setSettings] = useState23(
|
|
16155
16513
|
() => initializeSettings(screensize, profile)
|
|
16156
16514
|
);
|
|
16157
16515
|
const callbacksRef = useRef39({
|
|
@@ -16174,7 +16532,7 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
16174
16532
|
throw new Error("<WebVR> must be rendered inside <PanoViewer>.");
|
|
16175
16533
|
}
|
|
16176
16534
|
const { host, xrStore } = runtime;
|
|
16177
|
-
const resolvedProfile =
|
|
16535
|
+
const resolvedProfile = useMemo26(
|
|
16178
16536
|
() => resolveWebVRProfile(profile, settings.profileId),
|
|
16179
16537
|
[profile, settings.profileId]
|
|
16180
16538
|
);
|
|
@@ -16339,7 +16697,7 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
16339
16697
|
setSettings(normalized);
|
|
16340
16698
|
saveWebVRSettings(normalized);
|
|
16341
16699
|
}, []);
|
|
16342
|
-
const controller =
|
|
16700
|
+
const controller = useMemo26(
|
|
16343
16701
|
() => ({
|
|
16344
16702
|
closeSetup: () => updateWebVRHost(host, { setupOpen: false }),
|
|
16345
16703
|
enterVR,
|
|
@@ -16442,7 +16800,7 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
16442
16800
|
wakelock && (mode === "mobilevr" || mode === "fake")
|
|
16443
16801
|
);
|
|
16444
16802
|
return /* @__PURE__ */ jsxs20(Fragment6, { children: [
|
|
16445
|
-
/* @__PURE__ */
|
|
16803
|
+
/* @__PURE__ */ jsx39(
|
|
16446
16804
|
Gyro,
|
|
16447
16805
|
{
|
|
16448
16806
|
ref: gyroRef,
|
|
@@ -16456,7 +16814,7 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
16456
16814
|
touchMode: "off"
|
|
16457
16815
|
}
|
|
16458
16816
|
),
|
|
16459
|
-
/* @__PURE__ */
|
|
16817
|
+
/* @__PURE__ */ jsx39(
|
|
16460
16818
|
WebVRStereoRenderer,
|
|
16461
16819
|
{
|
|
16462
16820
|
mode,
|
|
@@ -16464,7 +16822,7 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
16464
16822
|
screensize: settings.screensize
|
|
16465
16823
|
}
|
|
16466
16824
|
),
|
|
16467
|
-
/* @__PURE__ */
|
|
16825
|
+
/* @__PURE__ */ jsx39(
|
|
16468
16826
|
WebVRReticle,
|
|
16469
16827
|
{
|
|
16470
16828
|
dwellMs: cursorDwellMs,
|
|
@@ -16475,7 +16833,7 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
16475
16833
|
});
|
|
16476
16834
|
|
|
16477
16835
|
// src/use-pano-viewer.ts
|
|
16478
|
-
import { useMemo as
|
|
16836
|
+
import { useMemo as useMemo27, useRef as useRef40 } from "react";
|
|
16479
16837
|
function createPanoViewerHandle(ref) {
|
|
16480
16838
|
return {
|
|
16481
16839
|
getView: () => ref.current?.getView() ?? { yaw: 0, pitch: 0, fov: 75 },
|
|
@@ -16558,20 +16916,20 @@ function createPanoViewerHandle(ref) {
|
|
|
16558
16916
|
}
|
|
16559
16917
|
function usePanoViewer() {
|
|
16560
16918
|
const ref = useRef40(null);
|
|
16561
|
-
const handle =
|
|
16562
|
-
return
|
|
16919
|
+
const handle = useMemo27(() => createPanoViewerHandle(ref), []);
|
|
16920
|
+
return useMemo27(() => ({ ref, ...handle }), [handle]);
|
|
16563
16921
|
}
|
|
16564
16922
|
|
|
16565
16923
|
// src/video/pano-video.tsx
|
|
16566
16924
|
import { useThree as useThree29 } from "@react-three/fiber";
|
|
16567
16925
|
import {
|
|
16568
16926
|
useCallback as useCallback11,
|
|
16569
|
-
useContext as
|
|
16927
|
+
useContext as useContext28,
|
|
16570
16928
|
useEffect as useEffect40,
|
|
16571
|
-
useLayoutEffect as
|
|
16572
|
-
useMemo as
|
|
16929
|
+
useLayoutEffect as useLayoutEffect9,
|
|
16930
|
+
useMemo as useMemo28,
|
|
16573
16931
|
useRef as useRef41,
|
|
16574
|
-
useState as
|
|
16932
|
+
useState as useState24
|
|
16575
16933
|
} from "react";
|
|
16576
16934
|
import {
|
|
16577
16935
|
BackSide as BackSide4,
|
|
@@ -16583,7 +16941,7 @@ import {
|
|
|
16583
16941
|
TextureLoader as TextureLoader8,
|
|
16584
16942
|
VideoTexture as VideoTexture2
|
|
16585
16943
|
} from "three";
|
|
16586
|
-
import { Fragment as Fragment7, jsx as
|
|
16944
|
+
import { Fragment as Fragment7, jsx as jsx40, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
16587
16945
|
var EMPTY_TRACKS = [];
|
|
16588
16946
|
var EMPTY_RATES = DEFAULT_PANO_VIDEO_PLAYBACK_RATES;
|
|
16589
16947
|
function createEmptySnapshot() {
|
|
@@ -16668,7 +17026,7 @@ function applyEquirectangularLayout(texture, anisotropy) {
|
|
|
16668
17026
|
}
|
|
16669
17027
|
function usePosterTexture2(poster, onError) {
|
|
16670
17028
|
const gl = useThree29((state) => state.gl);
|
|
16671
|
-
const [texture, setTexture] =
|
|
17029
|
+
const [texture, setTexture] = useState24(null);
|
|
16672
17030
|
const onErrorRef = useRef41(onError);
|
|
16673
17031
|
onErrorRef.current = onError;
|
|
16674
17032
|
useEffect40(() => {
|
|
@@ -16748,7 +17106,7 @@ function PanoVideo({
|
|
|
16748
17106
|
tracks: tracksProp,
|
|
16749
17107
|
captions = true,
|
|
16750
17108
|
controls = true,
|
|
16751
|
-
yawOffset = 0,
|
|
17109
|
+
yawOffset: yawOffset2 = 0,
|
|
16752
17110
|
loop = false,
|
|
16753
17111
|
muted = true,
|
|
16754
17112
|
volume = 1,
|
|
@@ -16767,26 +17125,26 @@ function PanoVideo({
|
|
|
16767
17125
|
}) {
|
|
16768
17126
|
usePanoMediaActivationIntent(autoPlay);
|
|
16769
17127
|
const gl = useThree29((state) => state.gl);
|
|
16770
|
-
const host =
|
|
16771
|
-
const variants =
|
|
17128
|
+
const host = useContext28(PanoVideoHostContext);
|
|
17129
|
+
const variants = useMemo28(
|
|
16772
17130
|
() => resolvePanoVideoVariants({ poster, src, variants: variantsProp }),
|
|
16773
17131
|
[poster, src, variantsProp]
|
|
16774
17132
|
);
|
|
16775
17133
|
const tracks = tracksProp ?? EMPTY_TRACKS;
|
|
16776
17134
|
const captionsEnabled = captions !== false;
|
|
16777
|
-
const captionAppearance =
|
|
17135
|
+
const captionAppearance = useMemo28(
|
|
16778
17136
|
() => resolvePanoVideoCaptionAppearance(
|
|
16779
17137
|
typeof captions === "object" ? captions : void 0
|
|
16780
17138
|
),
|
|
16781
17139
|
[captions]
|
|
16782
17140
|
);
|
|
16783
|
-
const [variantId, setVariantId] =
|
|
17141
|
+
const [variantId, setVariantId] = useState24(
|
|
16784
17142
|
() => resolvePanoVideoVariantId(variants, defaultVariantId)
|
|
16785
17143
|
);
|
|
16786
|
-
const [trackId, setTrackId] =
|
|
17144
|
+
const [trackId, setTrackId] = useState24(
|
|
16787
17145
|
() => captionsEnabled ? defaultPanoVideoTrackId(tracks) : null
|
|
16788
17146
|
);
|
|
16789
|
-
const [ready, setReady] =
|
|
17147
|
+
const [ready, setReady] = useState24(false);
|
|
16790
17148
|
const autoPlayRef = useRef41(autoPlay);
|
|
16791
17149
|
autoPlayRef.current = autoPlay;
|
|
16792
17150
|
const blockedRef = useRef41(false);
|
|
@@ -16839,7 +17197,7 @@ function PanoVideo({
|
|
|
16839
17197
|
onEndedRef.current = onEnded;
|
|
16840
17198
|
onVariantChangeRef.current = onVariantChange;
|
|
16841
17199
|
onTrackChangeRef.current = onTrackChange;
|
|
16842
|
-
const resource =
|
|
17200
|
+
const resource = useMemo28(() => {
|
|
16843
17201
|
if (typeof document === "undefined") {
|
|
16844
17202
|
return null;
|
|
16845
17203
|
}
|
|
@@ -16875,7 +17233,7 @@ function PanoVideo({
|
|
|
16875
17233
|
}
|
|
16876
17234
|
resource.texture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
16877
17235
|
}, [gl, resource]);
|
|
16878
|
-
|
|
17236
|
+
useLayoutEffect9(() => {
|
|
16879
17237
|
if (!resource) {
|
|
16880
17238
|
return;
|
|
16881
17239
|
}
|
|
@@ -16943,7 +17301,7 @@ function PanoVideo({
|
|
|
16943
17301
|
captionAppearance
|
|
16944
17302
|
]
|
|
16945
17303
|
);
|
|
16946
|
-
const controller =
|
|
17304
|
+
const controller = useMemo28(
|
|
16947
17305
|
() => ({
|
|
16948
17306
|
subscribe: (onStoreChange) => {
|
|
16949
17307
|
const store = storeRef.current;
|
|
@@ -16995,7 +17353,7 @@ function PanoVideo({
|
|
|
16995
17353
|
}),
|
|
16996
17354
|
[]
|
|
16997
17355
|
);
|
|
16998
|
-
|
|
17356
|
+
useLayoutEffect9(() => {
|
|
16999
17357
|
if (!host || variants.length === 0) {
|
|
17000
17358
|
return;
|
|
17001
17359
|
}
|
|
@@ -17008,7 +17366,7 @@ function PanoVideo({
|
|
|
17008
17366
|
notifyPanoVideoHost(host);
|
|
17009
17367
|
};
|
|
17010
17368
|
}, [captionsEnabled, controller, controls, host, variants.length]);
|
|
17011
|
-
|
|
17369
|
+
useLayoutEffect9(() => {
|
|
17012
17370
|
if (!resource) {
|
|
17013
17371
|
return;
|
|
17014
17372
|
}
|
|
@@ -17173,7 +17531,7 @@ function PanoVideo({
|
|
|
17173
17531
|
}
|
|
17174
17532
|
};
|
|
17175
17533
|
}, [emitSnapshot, resource]);
|
|
17176
|
-
|
|
17534
|
+
useLayoutEffect9(() => {
|
|
17177
17535
|
if (!resource) {
|
|
17178
17536
|
return;
|
|
17179
17537
|
}
|
|
@@ -17286,11 +17644,11 @@ function PanoVideo({
|
|
|
17286
17644
|
activeTexture ? /* @__PURE__ */ jsxs21(
|
|
17287
17645
|
"mesh",
|
|
17288
17646
|
{
|
|
17289
|
-
rotation: [0, MathUtils12.degToRad(90 +
|
|
17647
|
+
rotation: [0, MathUtils12.degToRad(90 + yawOffset2), 0],
|
|
17290
17648
|
visible,
|
|
17291
17649
|
children: [
|
|
17292
|
-
/* @__PURE__ */
|
|
17293
|
-
/* @__PURE__ */
|
|
17650
|
+
/* @__PURE__ */ jsx40("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
|
|
17651
|
+
/* @__PURE__ */ jsx40(
|
|
17294
17652
|
PanoBasicMaterial,
|
|
17295
17653
|
{
|
|
17296
17654
|
map: activeTexture,
|
|
@@ -17301,7 +17659,7 @@ function PanoVideo({
|
|
|
17301
17659
|
]
|
|
17302
17660
|
}
|
|
17303
17661
|
) : null,
|
|
17304
|
-
captionsEnabled ? /* @__PURE__ */
|
|
17662
|
+
captionsEnabled ? /* @__PURE__ */ jsx40(PanoVideoCaptions, { appearance: typeof captions === "object" ? captions : void 0 }) : null
|
|
17305
17663
|
] });
|
|
17306
17664
|
}
|
|
17307
17665
|
export {
|
|
@@ -17328,6 +17686,7 @@ export {
|
|
|
17328
17686
|
PanoContextMenu,
|
|
17329
17687
|
PanoEvents,
|
|
17330
17688
|
PanoFilter,
|
|
17689
|
+
PanoOverlayPortalProvider,
|
|
17331
17690
|
PanoVideo,
|
|
17332
17691
|
PanoVideoControls,
|
|
17333
17692
|
PanoViewer,
|
|
@@ -17356,6 +17715,8 @@ export {
|
|
|
17356
17715
|
resolvePanoContextMenuEntries,
|
|
17357
17716
|
unwrapPolygonVertices,
|
|
17358
17717
|
usePanoEvents,
|
|
17718
|
+
usePanoModal,
|
|
17719
|
+
usePanoOverlay,
|
|
17359
17720
|
usePanoViewer,
|
|
17360
17721
|
validatePolygonVertices,
|
|
17361
17722
|
validatePolylineVertices,
|