@ericchen1990/pano-view 3.9.0 → 3.10.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 +99 -55
- package/README.zh-CN.md +76 -42
- package/dist/index.cjs +1476 -768
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +75 -4
- package/dist/index.d.ts +75 -4
- package/dist/index.mjs +1241 -528
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +8 -0
- package/dist/ui.cjs.map +1 -1
- package/dist/ui.d.mts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.mjs.map +1 -1
- package/docs/dialogs.md +51 -41
- package/docs/dialogs.zh-CN.md +51 -41
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1291,8 +1291,8 @@ var require_howler = __commonJS({
|
|
|
1291
1291
|
break;
|
|
1292
1292
|
}
|
|
1293
1293
|
}
|
|
1294
|
-
if (
|
|
1295
|
-
delete
|
|
1294
|
+
if (cache2 && remCache) {
|
|
1295
|
+
delete cache2[self._src];
|
|
1296
1296
|
}
|
|
1297
1297
|
Howler4.noAudio = false;
|
|
1298
1298
|
self._state = "unloaded";
|
|
@@ -1547,7 +1547,7 @@ var require_howler = __commonJS({
|
|
|
1547
1547
|
_refreshBuffer: function(sound) {
|
|
1548
1548
|
var self = this;
|
|
1549
1549
|
sound._node.bufferSource = Howler4.ctx.createBufferSource();
|
|
1550
|
-
sound._node.bufferSource.buffer =
|
|
1550
|
+
sound._node.bufferSource.buffer = cache2[self._src];
|
|
1551
1551
|
if (sound._panner) {
|
|
1552
1552
|
sound._node.bufferSource.connect(sound._panner);
|
|
1553
1553
|
} else {
|
|
@@ -1709,11 +1709,11 @@ var require_howler = __commonJS({
|
|
|
1709
1709
|
self._node.removeEventListener("ended", self._endFn, false);
|
|
1710
1710
|
}
|
|
1711
1711
|
};
|
|
1712
|
-
var
|
|
1712
|
+
var cache2 = {};
|
|
1713
1713
|
var loadBuffer = function(self) {
|
|
1714
1714
|
var url = self._src;
|
|
1715
|
-
if (
|
|
1716
|
-
self._duration =
|
|
1715
|
+
if (cache2[url]) {
|
|
1716
|
+
self._duration = cache2[url].duration;
|
|
1717
1717
|
loadSound(self);
|
|
1718
1718
|
return;
|
|
1719
1719
|
}
|
|
@@ -1747,7 +1747,7 @@ var require_howler = __commonJS({
|
|
|
1747
1747
|
self._html5 = true;
|
|
1748
1748
|
self._webAudio = false;
|
|
1749
1749
|
self._sounds = [];
|
|
1750
|
-
delete
|
|
1750
|
+
delete cache2[url];
|
|
1751
1751
|
self.load();
|
|
1752
1752
|
}
|
|
1753
1753
|
};
|
|
@@ -1767,7 +1767,7 @@ var require_howler = __commonJS({
|
|
|
1767
1767
|
};
|
|
1768
1768
|
var success = function(buffer) {
|
|
1769
1769
|
if (buffer && self._sounds.length > 0) {
|
|
1770
|
-
|
|
1770
|
+
cache2[self._src] = buffer;
|
|
1771
1771
|
loadSound(self, buffer);
|
|
1772
1772
|
} else {
|
|
1773
1773
|
error();
|
|
@@ -2260,6 +2260,7 @@ __export(index_exports, {
|
|
|
2260
2260
|
DEFAULT_PANO_VIDEO_PLAYBACK_RATES: () => DEFAULT_PANO_VIDEO_PLAYBACK_RATES,
|
|
2261
2261
|
DEFAULT_WEBVR_CHROME_APPEARANCE: () => DEFAULT_WEBVR_CHROME_APPEARANCE,
|
|
2262
2262
|
DEFAULT_WEBVR_CURSOR_DWELL_MS: () => DEFAULT_WEBVR_CURSOR_DWELL_MS,
|
|
2263
|
+
EMPTY_WEBVR_STATE: () => EMPTY_WEBVR_STATE,
|
|
2263
2264
|
GraphicHotspot: () => GraphicHotspot,
|
|
2264
2265
|
Gyro: () => Gyro,
|
|
2265
2266
|
IframeHotspot: () => IframeHotspot,
|
|
@@ -2274,6 +2275,7 @@ __export(index_exports, {
|
|
|
2274
2275
|
PanoFilter: () => PanoFilter,
|
|
2275
2276
|
PanoMap: () => PanoMap,
|
|
2276
2277
|
PanoMapOverlay: () => PanoMapOverlay,
|
|
2278
|
+
PanoOverlay: () => PanoOverlay,
|
|
2277
2279
|
PanoOverlayPortalProvider: () => PanoOverlayPortalProvider,
|
|
2278
2280
|
PanoSceneMenu: () => PanoSceneMenu,
|
|
2279
2281
|
PanoVideo: () => PanoVideo,
|
|
@@ -2387,7 +2389,7 @@ function limitedYawDelta(from, to, range, shortestPath = true) {
|
|
|
2387
2389
|
// src/pano-viewer.tsx
|
|
2388
2390
|
var import_fiber10 = require("@react-three/fiber");
|
|
2389
2391
|
var import_xr3 = require("@react-three/xr");
|
|
2390
|
-
var
|
|
2392
|
+
var import_react30 = require("react");
|
|
2391
2393
|
|
|
2392
2394
|
// src/background-audio-host.ts
|
|
2393
2395
|
var import_react = require("react");
|
|
@@ -3939,6 +3941,18 @@ var import_react7 = require("react");
|
|
|
3939
3941
|
// src/webvr/host.ts
|
|
3940
3942
|
var import_react6 = require("react");
|
|
3941
3943
|
var WebVRRuntimeContext = (0, import_react6.createContext)(null);
|
|
3944
|
+
var EMPTY_WEBVR_STATE = Object.freeze({
|
|
3945
|
+
available: false,
|
|
3946
|
+
enabled: false,
|
|
3947
|
+
mode: null
|
|
3948
|
+
});
|
|
3949
|
+
function createWebVRState(available, mode) {
|
|
3950
|
+
return Object.freeze({
|
|
3951
|
+
available,
|
|
3952
|
+
enabled: mode !== null,
|
|
3953
|
+
mode
|
|
3954
|
+
});
|
|
3955
|
+
}
|
|
3942
3956
|
function createWebVRHost() {
|
|
3943
3957
|
return {
|
|
3944
3958
|
controller: null,
|
|
@@ -3948,18 +3962,28 @@ function createWebVRHost() {
|
|
|
3948
3962
|
chrome: true,
|
|
3949
3963
|
mode: null,
|
|
3950
3964
|
setupOpen: false,
|
|
3951
|
-
settings: { screensize: "auto", profileId: "cardboard-v1" }
|
|
3965
|
+
settings: { screensize: "auto", profileId: "cardboard-v1" },
|
|
3966
|
+
detectedScreensize: null
|
|
3952
3967
|
},
|
|
3968
|
+
state: EMPTY_WEBVR_STATE,
|
|
3953
3969
|
listeners: /* @__PURE__ */ new Set()
|
|
3954
3970
|
};
|
|
3955
3971
|
}
|
|
3956
3972
|
function updateWebVRHost(host, snapshot) {
|
|
3957
|
-
|
|
3973
|
+
const previous = host.snapshot;
|
|
3974
|
+
const next = { ...previous, ...snapshot };
|
|
3975
|
+
host.snapshot = next;
|
|
3958
3976
|
host.revision += 1;
|
|
3977
|
+
if (previous.available !== next.available || previous.mode !== next.mode) {
|
|
3978
|
+
host.state = createWebVRState(next.available, next.mode);
|
|
3979
|
+
}
|
|
3959
3980
|
for (const listener of host.listeners) {
|
|
3960
3981
|
listener();
|
|
3961
3982
|
}
|
|
3962
3983
|
}
|
|
3984
|
+
function getWebVRState(host) {
|
|
3985
|
+
return host.state;
|
|
3986
|
+
}
|
|
3963
3987
|
function subscribeWebVRHost(host, listener) {
|
|
3964
3988
|
host.listeners.add(listener);
|
|
3965
3989
|
return () => {
|
|
@@ -6190,8 +6214,50 @@ function createPanoModalHost() {
|
|
|
6190
6214
|
};
|
|
6191
6215
|
}
|
|
6192
6216
|
|
|
6193
|
-
// src/overlay/
|
|
6217
|
+
// src/overlay/partition.ts
|
|
6194
6218
|
var import_react17 = require("react");
|
|
6219
|
+
var PANO_OVERLAY_TYPE = /* @__PURE__ */ Symbol.for("pano-view.PanoOverlay");
|
|
6220
|
+
function isPanoOverlayType(type) {
|
|
6221
|
+
return typeof type === "function" && type[PANO_OVERLAY_TYPE] === true;
|
|
6222
|
+
}
|
|
6223
|
+
function isPanoOverlayElement(node) {
|
|
6224
|
+
return (0, import_react17.isValidElement)(node) && isPanoOverlayType(node.type);
|
|
6225
|
+
}
|
|
6226
|
+
function isFragmentElement(node) {
|
|
6227
|
+
return (0, import_react17.isValidElement)(node) && node.type === import_react17.Fragment;
|
|
6228
|
+
}
|
|
6229
|
+
function flattenViewerChildren(children) {
|
|
6230
|
+
const flat = [];
|
|
6231
|
+
for (const item of import_react17.Children.toArray(children)) {
|
|
6232
|
+
if (isFragmentElement(item)) {
|
|
6233
|
+
flat.push(...flattenViewerChildren(item.props.children));
|
|
6234
|
+
} else {
|
|
6235
|
+
flat.push(item);
|
|
6236
|
+
}
|
|
6237
|
+
}
|
|
6238
|
+
return flat;
|
|
6239
|
+
}
|
|
6240
|
+
function partitionPanoOverlay(children) {
|
|
6241
|
+
const items = flattenViewerChildren(children);
|
|
6242
|
+
const overlayElements = [];
|
|
6243
|
+
const sceneItems = [];
|
|
6244
|
+
let found = false;
|
|
6245
|
+
for (const item of items) {
|
|
6246
|
+
if (isPanoOverlayElement(item)) {
|
|
6247
|
+
found = true;
|
|
6248
|
+
overlayElements.push(item);
|
|
6249
|
+
} else {
|
|
6250
|
+
sceneItems.push(item);
|
|
6251
|
+
}
|
|
6252
|
+
}
|
|
6253
|
+
if (!found) {
|
|
6254
|
+
return { sceneChildren: children, overlayElements: [] };
|
|
6255
|
+
}
|
|
6256
|
+
return { sceneChildren: sceneItems, overlayElements };
|
|
6257
|
+
}
|
|
6258
|
+
|
|
6259
|
+
// src/overlay/pano-overlay.tsx
|
|
6260
|
+
var import_react18 = require("react");
|
|
6195
6261
|
|
|
6196
6262
|
// src/overlay/visible-rect.ts
|
|
6197
6263
|
function getOverlayVisibleRect(rect, viewport) {
|
|
@@ -6204,33 +6270,49 @@ function getOverlayVisibleRect(rect, viewport) {
|
|
|
6204
6270
|
|
|
6205
6271
|
// src/overlay/pano-overlay.tsx
|
|
6206
6272
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
6207
|
-
var PanoOverlayContext = (0,
|
|
6208
|
-
var PanoModalHostContext = (0,
|
|
6273
|
+
var PanoOverlayContext = (0, import_react18.createContext)(null);
|
|
6274
|
+
var PanoModalHostContext = (0, import_react18.createContext)(null);
|
|
6275
|
+
var PanoOverlayOutletContext = (0, import_react18.createContext)(false);
|
|
6276
|
+
function PanoOverlay({ children }) {
|
|
6277
|
+
const inOutlet = (0, import_react18.useContext)(PanoOverlayOutletContext);
|
|
6278
|
+
if (!inOutlet) {
|
|
6279
|
+
throw new Error(
|
|
6280
|
+
"PanoOverlay must be a direct child of PanoViewer (or of a Fragment under PanoViewer), not nested inside scene components."
|
|
6281
|
+
);
|
|
6282
|
+
}
|
|
6283
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children });
|
|
6284
|
+
}
|
|
6285
|
+
PanoOverlay[PANO_OVERLAY_TYPE] = true;
|
|
6286
|
+
var OVERLAY_HOOK_SCOPE = "PanoOverlay or PanoViewer.renderOverlay";
|
|
6209
6287
|
function usePanoOverlay() {
|
|
6210
|
-
const context = (0,
|
|
6211
|
-
if (!context)
|
|
6288
|
+
const context = (0, import_react18.useContext)(PanoOverlayContext);
|
|
6289
|
+
if (!context) {
|
|
6290
|
+
throw new Error(`usePanoOverlay must be used inside ${OVERLAY_HOOK_SCOPE}.`);
|
|
6291
|
+
}
|
|
6212
6292
|
return context;
|
|
6213
6293
|
}
|
|
6214
6294
|
function usePanoModal(open) {
|
|
6215
|
-
const host = (0,
|
|
6216
|
-
if (!host)
|
|
6217
|
-
|
|
6295
|
+
const host = (0, import_react18.useContext)(PanoModalHostContext);
|
|
6296
|
+
if (!host) {
|
|
6297
|
+
throw new Error(`usePanoModal must be used inside ${OVERLAY_HOOK_SCOPE}.`);
|
|
6298
|
+
}
|
|
6299
|
+
(0, import_react18.useLayoutEffect)(() => open ? host.acquire() : void 0, [host, open]);
|
|
6218
6300
|
}
|
|
6219
6301
|
function PanoOverlayPortalProvider({
|
|
6220
6302
|
container,
|
|
6221
6303
|
children
|
|
6222
6304
|
}) {
|
|
6223
6305
|
const context = usePanoOverlay();
|
|
6224
|
-
const value = (0,
|
|
6306
|
+
const value = (0, import_react18.useMemo)(() => ({ ...context, portalContainer: container }), [context, container]);
|
|
6225
6307
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PanoOverlayContext.Provider, { value, children });
|
|
6226
6308
|
}
|
|
6227
6309
|
function usePanoOverlayHost(isFullscreen) {
|
|
6228
|
-
const [portalContainer, setPortalContainer] = (0,
|
|
6229
|
-
const [geometry, setGeometry] = (0,
|
|
6310
|
+
const [portalContainer, setPortalContainer] = (0, import_react18.useState)(null);
|
|
6311
|
+
const [geometry, setGeometry] = (0, import_react18.useState)({
|
|
6230
6312
|
size: { width: 0, height: 0 },
|
|
6231
6313
|
visibleRect: { left: 0, top: 0, width: 0, height: 0 }
|
|
6232
6314
|
});
|
|
6233
|
-
(0,
|
|
6315
|
+
(0, import_react18.useLayoutEffect)(() => {
|
|
6234
6316
|
if (!portalContainer) return;
|
|
6235
6317
|
const win = portalContainer.ownerDocument.defaultView;
|
|
6236
6318
|
if (!win) return;
|
|
@@ -6269,13 +6351,13 @@ function usePanoOverlayHost(isFullscreen) {
|
|
|
6269
6351
|
win.visualViewport?.removeEventListener("scroll", scheduleMeasure);
|
|
6270
6352
|
};
|
|
6271
6353
|
}, [portalContainer]);
|
|
6272
|
-
const context = (0,
|
|
6354
|
+
const context = (0, import_react18.useMemo)(() => ({ portalContainer, ...geometry, isFullscreen }), [portalContainer, geometry, isFullscreen]);
|
|
6273
6355
|
return { context, setPortalContainer };
|
|
6274
6356
|
}
|
|
6275
6357
|
|
|
6276
6358
|
// src/panorama-event-surface.tsx
|
|
6277
6359
|
var import_fiber7 = require("@react-three/fiber");
|
|
6278
|
-
var
|
|
6360
|
+
var import_react19 = require("react");
|
|
6279
6361
|
var import_three5 = require("three");
|
|
6280
6362
|
|
|
6281
6363
|
// src/hotspot/coordinates.ts
|
|
@@ -6374,9 +6456,9 @@ function makePanoramaPointerEvent(event) {
|
|
|
6374
6456
|
};
|
|
6375
6457
|
}
|
|
6376
6458
|
function PanoramaEventSurface() {
|
|
6377
|
-
const eventBus = (0,
|
|
6459
|
+
const eventBus = (0, import_react19.useContext)(PanoEventBusContext);
|
|
6378
6460
|
const { camera, gl } = (0, import_fiber7.useThree)();
|
|
6379
|
-
(0,
|
|
6461
|
+
(0, import_react19.useEffect)(() => {
|
|
6380
6462
|
if (!eventBus) {
|
|
6381
6463
|
return;
|
|
6382
6464
|
}
|
|
@@ -6445,8 +6527,8 @@ function PanoramaEventSurface() {
|
|
|
6445
6527
|
}
|
|
6446
6528
|
|
|
6447
6529
|
// src/scenes-host.ts
|
|
6448
|
-
var
|
|
6449
|
-
var ScenesHostContext = (0,
|
|
6530
|
+
var import_react20 = require("react");
|
|
6531
|
+
var ScenesHostContext = (0, import_react20.createContext)(null);
|
|
6450
6532
|
function createScenesHost() {
|
|
6451
6533
|
return {
|
|
6452
6534
|
controller: null,
|
|
@@ -6463,7 +6545,7 @@ function notifyScenesHost(host) {
|
|
|
6463
6545
|
|
|
6464
6546
|
// src/touch-controls.tsx
|
|
6465
6547
|
var import_fiber8 = require("@react-three/fiber");
|
|
6466
|
-
var
|
|
6548
|
+
var import_react21 = require("react");
|
|
6467
6549
|
var DEFAULT_ROTATE_SPEED3 = 0.35;
|
|
6468
6550
|
function pointerAt2(event) {
|
|
6469
6551
|
return event.timeStamp > 0 ? event.timeStamp : performance.now();
|
|
@@ -6481,18 +6563,18 @@ function TouchControls({
|
|
|
6481
6563
|
pinchZoom = true
|
|
6482
6564
|
}) {
|
|
6483
6565
|
useClaimControlChannel("touch");
|
|
6484
|
-
const controlsRef = (0,
|
|
6566
|
+
const controlsRef = (0, import_react21.useContext)(PanoramaViewContext);
|
|
6485
6567
|
const { gl, camera } = (0, import_fiber8.useThree)();
|
|
6486
|
-
const validateDragRef = (0,
|
|
6568
|
+
const validateDragRef = (0, import_react21.useRef)(void 0);
|
|
6487
6569
|
(0, import_fiber8.useFrame)((_, delta) => validateDragRef.current?.(delta), -1);
|
|
6488
|
-
const pointersRef = (0,
|
|
6489
|
-
const pinchDistanceRef = (0,
|
|
6490
|
-
const optionsRef = (0,
|
|
6570
|
+
const pointersRef = (0, import_react21.useRef)(/* @__PURE__ */ new Map());
|
|
6571
|
+
const pinchDistanceRef = (0, import_react21.useRef)(null);
|
|
6572
|
+
const optionsRef = (0, import_react21.useRef)({ rotateSpeed, invert, pinchZoom });
|
|
6491
6573
|
if (!controlsRef) {
|
|
6492
6574
|
throw new Error("<TouchControls> must be rendered inside <PanoViewer>.");
|
|
6493
6575
|
}
|
|
6494
6576
|
optionsRef.current = { rotateSpeed, invert, pinchZoom };
|
|
6495
|
-
(0,
|
|
6577
|
+
(0, import_react21.useEffect)(() => {
|
|
6496
6578
|
const element = gl.domElement;
|
|
6497
6579
|
const drag = createPointerDrag(camera, element, () => controlsRef.current, "touch");
|
|
6498
6580
|
const pending = /* @__PURE__ */ new Set();
|
|
@@ -6667,17 +6749,17 @@ function TouchControls({
|
|
|
6667
6749
|
}
|
|
6668
6750
|
|
|
6669
6751
|
// src/video/chrome-overlay.tsx
|
|
6670
|
-
var
|
|
6752
|
+
var import_react22 = require("react");
|
|
6671
6753
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
6672
|
-
var PanoChromeOverlayContext = (0,
|
|
6754
|
+
var PanoChromeOverlayContext = (0, import_react22.createContext)(null);
|
|
6673
6755
|
function usePanoChromeOverlay() {
|
|
6674
|
-
const [overlayElement, setOverlayElement] = (0,
|
|
6756
|
+
const [overlayElement, setOverlayElement] = (0, import_react22.useState)(
|
|
6675
6757
|
null
|
|
6676
6758
|
);
|
|
6677
|
-
const setOverlayNode = (0,
|
|
6759
|
+
const setOverlayNode = (0, import_react22.useCallback)((node) => {
|
|
6678
6760
|
setOverlayElement(node);
|
|
6679
6761
|
}, []);
|
|
6680
|
-
const api = (0,
|
|
6762
|
+
const api = (0, import_react22.useMemo)(
|
|
6681
6763
|
() => ({ overlayElement }),
|
|
6682
6764
|
[overlayElement]
|
|
6683
6765
|
);
|
|
@@ -6693,9 +6775,9 @@ function usePanoChromeOverlay() {
|
|
|
6693
6775
|
}
|
|
6694
6776
|
|
|
6695
6777
|
// src/video/host.ts
|
|
6696
|
-
var
|
|
6697
|
-
var PanoVideoHostContext = (0,
|
|
6698
|
-
var DefaultPanoVideoControlsContext = (0,
|
|
6778
|
+
var import_react23 = require("react");
|
|
6779
|
+
var PanoVideoHostContext = (0, import_react23.createContext)(null);
|
|
6780
|
+
var DefaultPanoVideoControlsContext = (0, import_react23.createContext)(false);
|
|
6699
6781
|
function createPanoVideoHost() {
|
|
6700
6782
|
return {
|
|
6701
6783
|
controller: null,
|
|
@@ -6740,8 +6822,8 @@ function isProduction3() {
|
|
|
6740
6822
|
return nodeEnv === "production";
|
|
6741
6823
|
}
|
|
6742
6824
|
function useClaimPanoVideoControls() {
|
|
6743
|
-
const host = (0,
|
|
6744
|
-
const isDefault = (0,
|
|
6825
|
+
const host = (0, import_react23.useContext)(PanoVideoHostContext);
|
|
6826
|
+
const isDefault = (0, import_react23.useContext)(DefaultPanoVideoControlsContext);
|
|
6745
6827
|
if (!host || isDefault) {
|
|
6746
6828
|
return;
|
|
6747
6829
|
}
|
|
@@ -6754,10 +6836,10 @@ function useClaimPanoVideoControls() {
|
|
|
6754
6836
|
}
|
|
6755
6837
|
|
|
6756
6838
|
// src/video/pano-video-chrome-bridge.tsx
|
|
6757
|
-
var
|
|
6839
|
+
var import_react26 = require("react");
|
|
6758
6840
|
|
|
6759
6841
|
// src/video/pano-video-captions.tsx
|
|
6760
|
-
var
|
|
6842
|
+
var import_react24 = require("react");
|
|
6761
6843
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
6762
6844
|
var DEFAULT_PANO_VIDEO_CAPTION_APPEARANCE = {
|
|
6763
6845
|
color: "#ffffff",
|
|
@@ -6781,7 +6863,7 @@ function resolvePanoVideoCaptionAppearance(appearance) {
|
|
|
6781
6863
|
function PanoVideoCaptionsOverlay({
|
|
6782
6864
|
controller
|
|
6783
6865
|
}) {
|
|
6784
|
-
const snapshot = (0,
|
|
6866
|
+
const snapshot = (0, import_react24.useSyncExternalStore)(
|
|
6785
6867
|
controller.subscribe,
|
|
6786
6868
|
controller.getSnapshot,
|
|
6787
6869
|
controller.getSnapshot
|
|
@@ -6823,7 +6905,7 @@ function PanoVideoCaptions({
|
|
|
6823
6905
|
}
|
|
6824
6906
|
|
|
6825
6907
|
// src/video/pano-video-controls.tsx
|
|
6826
|
-
var
|
|
6908
|
+
var import_react25 = require("react");
|
|
6827
6909
|
|
|
6828
6910
|
// src/video/format.ts
|
|
6829
6911
|
var DEFAULT_PANO_VIDEO_PLAYBACK_RATES = [0.5, 1, 1.25, 1.5, 2];
|
|
@@ -7275,7 +7357,7 @@ function VerticalVolumeSlider({
|
|
|
7275
7357
|
onVolume,
|
|
7276
7358
|
volume
|
|
7277
7359
|
}) {
|
|
7278
|
-
const trackRef = (0,
|
|
7360
|
+
const trackRef = (0, import_react25.useRef)(null);
|
|
7279
7361
|
const applyPointer = (event) => {
|
|
7280
7362
|
const track = trackRef.current;
|
|
7281
7363
|
if (!track) {
|
|
@@ -7411,14 +7493,14 @@ function VolumeControl({
|
|
|
7411
7493
|
volume,
|
|
7412
7494
|
volumeAdjustable
|
|
7413
7495
|
}) {
|
|
7414
|
-
const rootRef = (0,
|
|
7415
|
-
const [open, setOpen] = (0,
|
|
7496
|
+
const rootRef = (0, import_react25.useRef)(null);
|
|
7497
|
+
const [open, setOpen] = (0, import_react25.useState)(false);
|
|
7416
7498
|
const displayVolume = muted ? 0 : volume;
|
|
7417
7499
|
const mutedOrSilent = muted || volume === 0;
|
|
7418
|
-
(0,
|
|
7500
|
+
(0, import_react25.useEffect)(() => {
|
|
7419
7501
|
onOpenChange(open);
|
|
7420
7502
|
}, [onOpenChange, open]);
|
|
7421
|
-
(0,
|
|
7503
|
+
(0, import_react25.useEffect)(() => {
|
|
7422
7504
|
if (!open || !volumeAdjustable || hasFinePointerHover()) {
|
|
7423
7505
|
return;
|
|
7424
7506
|
}
|
|
@@ -7505,24 +7587,24 @@ function PanoVideoControlsHud({
|
|
|
7505
7587
|
fullscreen,
|
|
7506
7588
|
overlayElement
|
|
7507
7589
|
}) {
|
|
7508
|
-
const resolved = (0,
|
|
7590
|
+
const resolved = (0, import_react25.useMemo)(
|
|
7509
7591
|
() => resolveControlsAppearance(appearance),
|
|
7510
7592
|
[appearance]
|
|
7511
7593
|
);
|
|
7512
|
-
const snapshot = (0,
|
|
7594
|
+
const snapshot = (0, import_react25.useSyncExternalStore)(
|
|
7513
7595
|
controller.subscribe,
|
|
7514
7596
|
controller.getSnapshot,
|
|
7515
7597
|
controller.getSnapshot
|
|
7516
7598
|
);
|
|
7517
|
-
const [menu, setMenu] = (0,
|
|
7518
|
-
const [captionsPanel, setCaptionsPanel] = (0,
|
|
7519
|
-
const [visible, setVisible] = (0,
|
|
7520
|
-
const [volumeOpen, setVolumeOpen] = (0,
|
|
7521
|
-
const [overlayWidth, setOverlayWidth] = (0,
|
|
7599
|
+
const [menu, setMenu] = (0, import_react25.useState)(null);
|
|
7600
|
+
const [captionsPanel, setCaptionsPanel] = (0, import_react25.useState)("tracks");
|
|
7601
|
+
const [visible, setVisible] = (0, import_react25.useState)(true);
|
|
7602
|
+
const [volumeOpen, setVolumeOpen] = (0, import_react25.useState)(false);
|
|
7603
|
+
const [overlayWidth, setOverlayWidth] = (0, import_react25.useState)(
|
|
7522
7604
|
() => overlayElement.clientWidth
|
|
7523
7605
|
);
|
|
7524
|
-
const idleTimerRef = (0,
|
|
7525
|
-
const barId = (0,
|
|
7606
|
+
const idleTimerRef = (0, import_react25.useRef)(0);
|
|
7607
|
+
const barId = (0, import_react25.useId)();
|
|
7526
7608
|
const rateMenuId = `${barId}-rate`;
|
|
7527
7609
|
const variantMenuId = `${barId}-variant`;
|
|
7528
7610
|
const captionsMenuId = `${barId}-captions`;
|
|
@@ -7530,7 +7612,7 @@ function PanoVideoControlsHud({
|
|
|
7530
7612
|
const compact = overlayWidth < COMPACT_CONTROLS_WIDTH;
|
|
7531
7613
|
const hideTime = overlayWidth < NARROW_CONTROLS_WIDTH;
|
|
7532
7614
|
const showFullscreen = canEnterViewerFullscreen();
|
|
7533
|
-
const bumpVisibility = (0,
|
|
7615
|
+
const bumpVisibility = (0, import_react25.useCallback)(
|
|
7534
7616
|
(playing) => {
|
|
7535
7617
|
setVisible(true);
|
|
7536
7618
|
window.clearTimeout(idleTimerRef.current);
|
|
@@ -7543,7 +7625,7 @@ function PanoVideoControlsHud({
|
|
|
7543
7625
|
},
|
|
7544
7626
|
[menu, volumeOpen]
|
|
7545
7627
|
);
|
|
7546
|
-
(0,
|
|
7628
|
+
(0, import_react25.useEffect)(() => {
|
|
7547
7629
|
if (typeof ResizeObserver === "undefined") {
|
|
7548
7630
|
return;
|
|
7549
7631
|
}
|
|
@@ -7558,15 +7640,15 @@ function PanoVideoControlsHud({
|
|
|
7558
7640
|
observer.disconnect();
|
|
7559
7641
|
};
|
|
7560
7642
|
}, [overlayElement]);
|
|
7561
|
-
(0,
|
|
7643
|
+
(0, import_react25.useEffect)(() => {
|
|
7562
7644
|
if (!compact && menu === "more") {
|
|
7563
7645
|
setMenu(null);
|
|
7564
7646
|
}
|
|
7565
7647
|
}, [compact, menu]);
|
|
7566
|
-
(0,
|
|
7648
|
+
(0, import_react25.useEffect)(() => {
|
|
7567
7649
|
bumpVisibility(snapshot.playing);
|
|
7568
7650
|
}, [bumpVisibility, snapshot.playing]);
|
|
7569
|
-
(0,
|
|
7651
|
+
(0, import_react25.useEffect)(() => {
|
|
7570
7652
|
const root = overlayElement.parentElement;
|
|
7571
7653
|
if (!root) {
|
|
7572
7654
|
return;
|
|
@@ -7625,7 +7707,7 @@ function PanoVideoControlsHud({
|
|
|
7625
7707
|
document.removeEventListener("pointerdown", handlePointerDown, true);
|
|
7626
7708
|
};
|
|
7627
7709
|
}, [bumpVisibility, controller, menu, overlayElement, snapshot.playing, volumeOpen]);
|
|
7628
|
-
(0,
|
|
7710
|
+
(0, import_react25.useEffect)(
|
|
7629
7711
|
() => () => {
|
|
7630
7712
|
window.clearTimeout(idleTimerRef.current);
|
|
7631
7713
|
},
|
|
@@ -7916,7 +7998,7 @@ function PanoVideoControlsHud({
|
|
|
7916
7998
|
}
|
|
7917
7999
|
function PanoVideoControls({ appearance }) {
|
|
7918
8000
|
useClaimPanoVideoControls();
|
|
7919
|
-
const host = (0,
|
|
8001
|
+
const host = (0, import_react25.useContext)(PanoVideoHostContext);
|
|
7920
8002
|
if (host && appearance) {
|
|
7921
8003
|
host.controls = appearance;
|
|
7922
8004
|
}
|
|
@@ -7930,7 +8012,7 @@ function PanoVideoChromeBridge({
|
|
|
7930
8012
|
host,
|
|
7931
8013
|
overlayElement
|
|
7932
8014
|
}) {
|
|
7933
|
-
(0,
|
|
8015
|
+
(0, import_react26.useSyncExternalStore)(
|
|
7934
8016
|
(onStoreChange) => subscribePanoVideoHost(host, onStoreChange),
|
|
7935
8017
|
() => getPanoVideoHostRevision(host),
|
|
7936
8018
|
() => getPanoVideoHostRevision(host)
|
|
@@ -7954,7 +8036,7 @@ function PanoVideoChromeBridge({
|
|
|
7954
8036
|
}
|
|
7955
8037
|
|
|
7956
8038
|
// src/webvr/chrome.tsx
|
|
7957
|
-
var
|
|
8039
|
+
var import_react28 = require("react");
|
|
7958
8040
|
|
|
7959
8041
|
// src/webvr/appearance.ts
|
|
7960
8042
|
var DEFAULT_WEBVR_CHROME_APPEARANCE = {
|
|
@@ -7966,7 +8048,7 @@ var DEFAULT_WEBVR_CHROME_APPEARANCE = {
|
|
|
7966
8048
|
};
|
|
7967
8049
|
|
|
7968
8050
|
// src/webvr/orientation.ts
|
|
7969
|
-
var
|
|
8051
|
+
var import_react27 = require("react");
|
|
7970
8052
|
function subscribePortraitOrientation(onChange) {
|
|
7971
8053
|
if (typeof window === "undefined") {
|
|
7972
8054
|
return () => {
|
|
@@ -7998,7 +8080,7 @@ function getPortraitOrientation() {
|
|
|
7998
8080
|
return window.matchMedia("(orientation: portrait)").matches;
|
|
7999
8081
|
}
|
|
8000
8082
|
function usePortraitOrientation() {
|
|
8001
|
-
return (0,
|
|
8083
|
+
return (0, import_react27.useSyncExternalStore)(
|
|
8002
8084
|
subscribePortraitOrientation,
|
|
8003
8085
|
getPortraitOrientation,
|
|
8004
8086
|
() => false
|
|
@@ -8020,6 +8102,7 @@ var WEBVR_PROFILES = {
|
|
|
8020
8102
|
fov: 80,
|
|
8021
8103
|
ipdMm: 60,
|
|
8022
8104
|
screenToLensMm: 42,
|
|
8105
|
+
trayDistanceMm: 0,
|
|
8023
8106
|
k1: 0,
|
|
8024
8107
|
k2: 0
|
|
8025
8108
|
},
|
|
@@ -8029,6 +8112,7 @@ var WEBVR_PROFILES = {
|
|
|
8029
8112
|
fov: 80,
|
|
8030
8113
|
ipdMm: 60,
|
|
8031
8114
|
screenToLensMm: 42,
|
|
8115
|
+
trayDistanceMm: 35,
|
|
8032
8116
|
k1: 0.441,
|
|
8033
8117
|
k2: 0.156
|
|
8034
8118
|
},
|
|
@@ -8038,6 +8122,7 @@ var WEBVR_PROFILES = {
|
|
|
8038
8122
|
fov: 90,
|
|
8039
8123
|
ipdMm: 64,
|
|
8040
8124
|
screenToLensMm: 39,
|
|
8125
|
+
trayDistanceMm: 0,
|
|
8041
8126
|
k1: 0.336,
|
|
8042
8127
|
k2: 0.553
|
|
8043
8128
|
},
|
|
@@ -8047,6 +8132,7 @@ var WEBVR_PROFILES = {
|
|
|
8047
8132
|
fov: 96,
|
|
8048
8133
|
ipdMm: 63.5,
|
|
8049
8134
|
screenToLensMm: 50,
|
|
8135
|
+
trayDistanceMm: 0,
|
|
8050
8136
|
k1: 0.215,
|
|
8051
8137
|
k2: 0.215
|
|
8052
8138
|
},
|
|
@@ -8056,6 +8142,7 @@ var WEBVR_PROFILES = {
|
|
|
8056
8142
|
fov: 90,
|
|
8057
8143
|
ipdMm: 61.5,
|
|
8058
8144
|
screenToLensMm: 44,
|
|
8145
|
+
trayDistanceMm: 0,
|
|
8059
8146
|
k1: 0.385,
|
|
8060
8147
|
k2: 0.593
|
|
8061
8148
|
}
|
|
@@ -8106,12 +8193,28 @@ function saveWebVRSettings(settings) {
|
|
|
8106
8193
|
} catch {
|
|
8107
8194
|
}
|
|
8108
8195
|
}
|
|
8196
|
+
function clearWebVRSettings() {
|
|
8197
|
+
if (typeof localStorage === "undefined") {
|
|
8198
|
+
return;
|
|
8199
|
+
}
|
|
8200
|
+
try {
|
|
8201
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
8202
|
+
} catch {
|
|
8203
|
+
}
|
|
8204
|
+
}
|
|
8205
|
+
function resolveInitialWebVRSettings(screensize, profile) {
|
|
8206
|
+
return {
|
|
8207
|
+
screensize: screensize ?? DEFAULT_WEBVR_SETTINGS.screensize,
|
|
8208
|
+
profileId: typeof profile === "string" ? profile : DEFAULT_WEBVR_SETTINGS.profileId
|
|
8209
|
+
};
|
|
8210
|
+
}
|
|
8109
8211
|
function clamp2(value, min, max) {
|
|
8110
8212
|
return Math.max(min, Math.min(max, Number.isFinite(value) ? value : min));
|
|
8111
8213
|
}
|
|
8112
8214
|
|
|
8113
8215
|
// src/webvr/chrome.tsx
|
|
8114
8216
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
8217
|
+
var SESSION_CHROME_IDLE_MS = 3e3;
|
|
8115
8218
|
function resolveAppearance(value) {
|
|
8116
8219
|
return {
|
|
8117
8220
|
...DEFAULT_WEBVR_CHROME_APPEARANCE,
|
|
@@ -8139,8 +8242,15 @@ function ChromeButton2({
|
|
|
8139
8242
|
}
|
|
8140
8243
|
);
|
|
8141
8244
|
}
|
|
8245
|
+
function formatScreensizeLabel(settings, detectedScreensize) {
|
|
8246
|
+
if (settings.screensize === "auto") {
|
|
8247
|
+
return detectedScreensize === null ? "Auto" : `Auto \xB7 ${detectedScreensize.toFixed(1)}`;
|
|
8248
|
+
}
|
|
8249
|
+
return settings.screensize.toFixed(1);
|
|
8250
|
+
}
|
|
8142
8251
|
function SetupPanel({
|
|
8143
8252
|
appearance,
|
|
8253
|
+
detectedScreensize,
|
|
8144
8254
|
host,
|
|
8145
8255
|
settings
|
|
8146
8256
|
}) {
|
|
@@ -8184,7 +8294,7 @@ function SetupPanel({
|
|
|
8184
8294
|
children: "\u2039"
|
|
8185
8295
|
}
|
|
8186
8296
|
),
|
|
8187
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { className: "pano-webvr-setup-value", children: settings
|
|
8297
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { className: "pano-webvr-setup-value", children: formatScreensizeLabel(settings, detectedScreensize) }),
|
|
8188
8298
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
8189
8299
|
"button",
|
|
8190
8300
|
{
|
|
@@ -8225,42 +8335,61 @@ function SetupPanel({
|
|
|
8225
8335
|
)
|
|
8226
8336
|
] })
|
|
8227
8337
|
] }),
|
|
8338
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "pano-webvr-setup-row", children: [
|
|
8339
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
8340
|
+
ChromeButton2,
|
|
8341
|
+
{
|
|
8342
|
+
appearance,
|
|
8343
|
+
onClick: () => controller?.resetSettings(),
|
|
8344
|
+
children: "Reset"
|
|
8345
|
+
}
|
|
8346
|
+
),
|
|
8347
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
8348
|
+
ChromeButton2,
|
|
8349
|
+
{
|
|
8350
|
+
appearance,
|
|
8351
|
+
onClick: () => controller?.closeSetup(),
|
|
8352
|
+
children: "Close"
|
|
8353
|
+
}
|
|
8354
|
+
)
|
|
8355
|
+
] })
|
|
8356
|
+
]
|
|
8357
|
+
}
|
|
8358
|
+
);
|
|
8359
|
+
}
|
|
8360
|
+
function SessionActions({
|
|
8361
|
+
appearance,
|
|
8362
|
+
host,
|
|
8363
|
+
mode,
|
|
8364
|
+
visible
|
|
8365
|
+
}) {
|
|
8366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
8367
|
+
"div",
|
|
8368
|
+
{
|
|
8369
|
+
"aria-hidden": !visible,
|
|
8370
|
+
className: visible ? "pano-webvr-toolbar-actions" : "pano-webvr-toolbar-actions pano-webvr-toolbar-actions-hidden",
|
|
8371
|
+
inert: !visible ? true : void 0,
|
|
8372
|
+
children: [
|
|
8373
|
+
mode !== "webxr" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
8374
|
+
ChromeButton2,
|
|
8375
|
+
{
|
|
8376
|
+
appearance,
|
|
8377
|
+
onClick: () => host.controller?.openSetup(),
|
|
8378
|
+
children: "VR Setup"
|
|
8379
|
+
}
|
|
8380
|
+
) : null,
|
|
8228
8381
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
8229
8382
|
ChromeButton2,
|
|
8230
8383
|
{
|
|
8231
8384
|
appearance,
|
|
8232
|
-
onClick: () => controller?.
|
|
8233
|
-
children: "
|
|
8385
|
+
onClick: () => void host.controller?.exitVR(),
|
|
8386
|
+
children: "Exit VR"
|
|
8234
8387
|
}
|
|
8235
8388
|
)
|
|
8236
8389
|
]
|
|
8237
8390
|
}
|
|
8238
8391
|
);
|
|
8239
8392
|
}
|
|
8240
|
-
function SessionActions({
|
|
8241
|
-
appearance,
|
|
8242
|
-
host,
|
|
8243
|
-
mode
|
|
8244
|
-
}) {
|
|
8245
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "pano-webvr-toolbar-actions", children: [
|
|
8246
|
-
mode !== "webxr" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
8247
|
-
ChromeButton2,
|
|
8248
|
-
{
|
|
8249
|
-
appearance,
|
|
8250
|
-
onClick: () => host.controller?.openSetup(),
|
|
8251
|
-
children: "VR Setup"
|
|
8252
|
-
}
|
|
8253
|
-
) : null,
|
|
8254
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
8255
|
-
ChromeButton2,
|
|
8256
|
-
{
|
|
8257
|
-
appearance,
|
|
8258
|
-
onClick: () => void host.controller?.exitVR(),
|
|
8259
|
-
children: "Exit VR"
|
|
8260
|
-
}
|
|
8261
|
-
)
|
|
8262
|
-
] });
|
|
8263
|
-
}
|
|
8264
8393
|
function RotatePhoneIcon2() {
|
|
8265
8394
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
8266
8395
|
"svg",
|
|
@@ -8291,18 +8420,81 @@ function PortraitPrompt() {
|
|
|
8291
8420
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "pano-webvr-portrait-text", children: "Rotate your phone to landscape" })
|
|
8292
8421
|
] });
|
|
8293
8422
|
}
|
|
8423
|
+
function useSessionChromeVisibility(active, keepVisible, viewer) {
|
|
8424
|
+
const [visible, setVisible] = (0, import_react28.useState)(true);
|
|
8425
|
+
const idleTimerRef = (0, import_react28.useRef)(0);
|
|
8426
|
+
const bump = (0, import_react28.useCallback)(() => {
|
|
8427
|
+
setVisible(true);
|
|
8428
|
+
window.clearTimeout(idleTimerRef.current);
|
|
8429
|
+
if (!active || keepVisible) {
|
|
8430
|
+
return;
|
|
8431
|
+
}
|
|
8432
|
+
idleTimerRef.current = window.setTimeout(() => {
|
|
8433
|
+
setVisible(false);
|
|
8434
|
+
}, SESSION_CHROME_IDLE_MS);
|
|
8435
|
+
}, [active, keepVisible]);
|
|
8436
|
+
(0, import_react28.useEffect)(() => {
|
|
8437
|
+
if (!active) {
|
|
8438
|
+
window.clearTimeout(idleTimerRef.current);
|
|
8439
|
+
setVisible(true);
|
|
8440
|
+
return;
|
|
8441
|
+
}
|
|
8442
|
+
bump();
|
|
8443
|
+
}, [active, bump, keepVisible]);
|
|
8444
|
+
(0, import_react28.useEffect)(() => {
|
|
8445
|
+
if (!active || !viewer) {
|
|
8446
|
+
return;
|
|
8447
|
+
}
|
|
8448
|
+
const reveal = () => {
|
|
8449
|
+
bump();
|
|
8450
|
+
};
|
|
8451
|
+
viewer.addEventListener("pointerdown", reveal);
|
|
8452
|
+
viewer.addEventListener("wheel", reveal, { passive: true });
|
|
8453
|
+
viewer.addEventListener("keydown", reveal);
|
|
8454
|
+
return () => {
|
|
8455
|
+
viewer.removeEventListener("pointerdown", reveal);
|
|
8456
|
+
viewer.removeEventListener("wheel", reveal);
|
|
8457
|
+
viewer.removeEventListener("keydown", reveal);
|
|
8458
|
+
};
|
|
8459
|
+
}, [active, bump, viewer]);
|
|
8460
|
+
(0, import_react28.useEffect)(
|
|
8461
|
+
() => () => {
|
|
8462
|
+
window.clearTimeout(idleTimerRef.current);
|
|
8463
|
+
},
|
|
8464
|
+
[]
|
|
8465
|
+
);
|
|
8466
|
+
return keepVisible || visible;
|
|
8467
|
+
}
|
|
8294
8468
|
function WebVRChromeBridge({ host }) {
|
|
8295
|
-
(0,
|
|
8469
|
+
(0, import_react28.useSyncExternalStore)(
|
|
8296
8470
|
(listener) => subscribeWebVRHost(host, listener),
|
|
8297
8471
|
() => host.revision,
|
|
8298
8472
|
() => host.revision
|
|
8299
8473
|
);
|
|
8300
8474
|
const portrait = usePortraitOrientation();
|
|
8301
|
-
const {
|
|
8302
|
-
|
|
8303
|
-
|
|
8475
|
+
const {
|
|
8476
|
+
chrome,
|
|
8477
|
+
detectedScreensize,
|
|
8478
|
+
mode,
|
|
8479
|
+
settings,
|
|
8480
|
+
setupOpen
|
|
8481
|
+
} = host.snapshot;
|
|
8482
|
+
const [mounted, setMounted] = (0, import_react28.useState)(false);
|
|
8483
|
+
const [viewer, setViewer] = (0, import_react28.useState)(null);
|
|
8484
|
+
const toolbarRef = (0, import_react28.useRef)(null);
|
|
8485
|
+
(0, import_react28.useEffect)(() => {
|
|
8304
8486
|
setMounted(true);
|
|
8305
8487
|
}, []);
|
|
8488
|
+
(0, import_react28.useEffect)(() => {
|
|
8489
|
+
const node = toolbarRef.current?.closest("[data-pano-viewer]") ?? null;
|
|
8490
|
+
setViewer(node);
|
|
8491
|
+
}, [mode]);
|
|
8492
|
+
const sessionActive = mode !== null;
|
|
8493
|
+
const chromeVisible = useSessionChromeVisibility(
|
|
8494
|
+
sessionActive,
|
|
8495
|
+
setupOpen,
|
|
8496
|
+
viewer
|
|
8497
|
+
);
|
|
8306
8498
|
if (chrome === false || !host.controller) {
|
|
8307
8499
|
return null;
|
|
8308
8500
|
}
|
|
@@ -8311,17 +8503,29 @@ function WebVRChromeBridge({ host }) {
|
|
|
8311
8503
|
if (showPortraitPrompt) {
|
|
8312
8504
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PortraitPrompt, {});
|
|
8313
8505
|
}
|
|
8506
|
+
if (!mode) {
|
|
8507
|
+
return null;
|
|
8508
|
+
}
|
|
8314
8509
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
8315
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "pano-webvr-toolbar",
|
|
8316
|
-
|
|
8510
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "pano-webvr-toolbar", ref: toolbarRef, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
8511
|
+
SessionActions,
|
|
8317
8512
|
{
|
|
8318
8513
|
appearance,
|
|
8319
|
-
|
|
8320
|
-
|
|
8514
|
+
host,
|
|
8515
|
+
mode,
|
|
8516
|
+
visible: chromeVisible
|
|
8321
8517
|
}
|
|
8322
8518
|
) }),
|
|
8323
|
-
mode === "fake" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "pano-webvr-hint", style: { color: appearance.color }, 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." }) : null,
|
|
8324
|
-
setupOpen ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
8519
|
+
mode === "fake" && chromeVisible ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "pano-webvr-hint", style: { color: appearance.color }, 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." }) : null,
|
|
8520
|
+
setupOpen ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
8521
|
+
SetupPanel,
|
|
8522
|
+
{
|
|
8523
|
+
appearance,
|
|
8524
|
+
detectedScreensize,
|
|
8525
|
+
host,
|
|
8526
|
+
settings
|
|
8527
|
+
}
|
|
8528
|
+
) : null
|
|
8325
8529
|
] });
|
|
8326
8530
|
}
|
|
8327
8531
|
|
|
@@ -8354,12 +8558,12 @@ function projectStereoHtmlPosition(el, camera, size, eye) {
|
|
|
8354
8558
|
// src/webvr/xr-origin.tsx
|
|
8355
8559
|
var import_fiber9 = require("@react-three/fiber");
|
|
8356
8560
|
var import_xr2 = require("@react-three/xr");
|
|
8357
|
-
var
|
|
8561
|
+
var import_react29 = require("react");
|
|
8358
8562
|
var import_three7 = require("three");
|
|
8359
8563
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
8360
8564
|
function PanoramaXROrigin() {
|
|
8361
|
-
const originRef = (0,
|
|
8362
|
-
const localHeadPositionRef = (0,
|
|
8565
|
+
const originRef = (0, import_react29.useRef)(null);
|
|
8566
|
+
const localHeadPositionRef = (0, import_react29.useRef)(new import_three7.Vector3());
|
|
8363
8567
|
const session2 = (0, import_xr2.useXR)((state) => state.session);
|
|
8364
8568
|
const gl = (0, import_fiber9.useThree)((state) => state.gl);
|
|
8365
8569
|
(0, import_fiber9.useFrame)(() => {
|
|
@@ -8424,7 +8628,7 @@ function PanoCursorTree({
|
|
|
8424
8628
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PanoCursorController, { cursors, children });
|
|
8425
8629
|
}
|
|
8426
8630
|
function PanoVideoHostReset() {
|
|
8427
|
-
const host = (0,
|
|
8631
|
+
const host = (0, import_react30.useContext)(PanoVideoHostContext);
|
|
8428
8632
|
if (host) {
|
|
8429
8633
|
host.controlClaims = 0;
|
|
8430
8634
|
}
|
|
@@ -8437,7 +8641,7 @@ function DefaultControlChannels({
|
|
|
8437
8641
|
keyboardChannel,
|
|
8438
8642
|
fovSpeed
|
|
8439
8643
|
}) {
|
|
8440
|
-
const claims = (0,
|
|
8644
|
+
const claims = (0, import_react30.useContext)(ControlClaimsContext);
|
|
8441
8645
|
if (!claims) {
|
|
8442
8646
|
return null;
|
|
8443
8647
|
}
|
|
@@ -8453,7 +8657,7 @@ function DefaultControlChannels({
|
|
|
8453
8657
|
) : null
|
|
8454
8658
|
] });
|
|
8455
8659
|
}
|
|
8456
|
-
var PanoViewer = (0,
|
|
8660
|
+
var PanoViewer = (0, import_react30.forwardRef)(
|
|
8457
8661
|
function PanoViewer2({
|
|
8458
8662
|
children,
|
|
8459
8663
|
renderOverlay,
|
|
@@ -8474,37 +8678,37 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8474
8678
|
"aria-label": ariaLabel = "Panorama viewer",
|
|
8475
8679
|
...divProps
|
|
8476
8680
|
}, ref) {
|
|
8477
|
-
const rootRef = (0,
|
|
8478
|
-
const controlsRef = (0,
|
|
8479
|
-
const modalHost = (0,
|
|
8480
|
-
const modalOpen = (0,
|
|
8481
|
-
const setControlsRuntime = (0,
|
|
8681
|
+
const rootRef = (0, import_react30.useRef)(null);
|
|
8682
|
+
const controlsRef = (0, import_react30.useRef)(null);
|
|
8683
|
+
const modalHost = (0, import_react30.useMemo)(() => createPanoModalHost(), []);
|
|
8684
|
+
const modalOpen = (0, import_react30.useSyncExternalStore)(modalHost.subscribe, modalHost.getSnapshot, () => false);
|
|
8685
|
+
const setControlsRuntime = (0, import_react30.useCallback)((runtime) => {
|
|
8482
8686
|
controlsRef.current = runtime;
|
|
8483
8687
|
modalHost.connect(runtime);
|
|
8484
8688
|
}, [modalHost]);
|
|
8485
|
-
const eventBus = (0,
|
|
8689
|
+
const eventBus = (0, import_react30.useMemo)(() => createPanoEventBus(), []);
|
|
8486
8690
|
const { controls: hotspotAccessibilityControls, registry } = useHotspotAccessibilityLayer();
|
|
8487
|
-
const hotspotTargetRegistry = (0,
|
|
8691
|
+
const hotspotTargetRegistry = (0, import_react30.useMemo)(() => createHotspotTargetRegistry(), []);
|
|
8488
8692
|
const { api: contextMenuOverlayApi, overlay: contextMenuOverlay } = usePanoContextMenuOverlay();
|
|
8489
8693
|
const { api: chromeOverlayApi, setOverlayNode, overlayElement } = usePanoChromeOverlay();
|
|
8490
|
-
const videoHost = (0,
|
|
8491
|
-
const filterHost = (0,
|
|
8492
|
-
const webVRHost = (0,
|
|
8493
|
-
const scenesHost = (0,
|
|
8494
|
-
const bgmHost = (0,
|
|
8495
|
-
const mediaActivationHost = (0,
|
|
8496
|
-
const mediaActivationOptions = (0,
|
|
8694
|
+
const videoHost = (0, import_react30.useMemo)(() => createPanoVideoHost(), []);
|
|
8695
|
+
const filterHost = (0, import_react30.useMemo)(() => createPanoFilterHost(), []);
|
|
8696
|
+
const webVRHost = (0, import_react30.useMemo)(() => createWebVRHost(), []);
|
|
8697
|
+
const scenesHost = (0, import_react30.useMemo)(() => createScenesHost(), []);
|
|
8698
|
+
const bgmHost = (0, import_react30.useMemo)(() => createBackgroundAudioHost(), []);
|
|
8699
|
+
const mediaActivationHost = (0, import_react30.useMemo)(() => createPanoMediaActivationHost(), []);
|
|
8700
|
+
const mediaActivationOptions = (0, import_react30.useMemo)(
|
|
8497
8701
|
() => mediaActivation === false ? null : mediaActivation ?? {},
|
|
8498
8702
|
[mediaActivation]
|
|
8499
8703
|
);
|
|
8500
|
-
const mediaActivationRevision = (0,
|
|
8704
|
+
const mediaActivationRevision = (0, import_react30.useSyncExternalStore)(
|
|
8501
8705
|
(onStoreChange) => subscribePanoMediaActivation(mediaActivationHost, onStoreChange),
|
|
8502
8706
|
() => getPanoMediaActivationRevision(mediaActivationHost),
|
|
8503
8707
|
() => getPanoMediaActivationRevision(mediaActivationHost)
|
|
8504
8708
|
);
|
|
8505
|
-
const [mediaActivated, setMediaActivated] = (0,
|
|
8506
|
-
const stereoView = (0,
|
|
8507
|
-
const xrStore = (0,
|
|
8709
|
+
const [mediaActivated, setMediaActivated] = (0, import_react30.useState)(false);
|
|
8710
|
+
const stereoView = (0, import_react30.useMemo)(() => createWebVRStereoView(), []);
|
|
8711
|
+
const xrStore = (0, import_react30.useMemo)(
|
|
8508
8712
|
() => (0, import_xr3.createXRStore)({
|
|
8509
8713
|
anchors: false,
|
|
8510
8714
|
bodyTracking: false,
|
|
@@ -8520,7 +8724,7 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8520
8724
|
}),
|
|
8521
8725
|
[]
|
|
8522
8726
|
);
|
|
8523
|
-
const mediaActivationControls = (0,
|
|
8727
|
+
const mediaActivationControls = (0, import_react30.useMemo)(
|
|
8524
8728
|
() => ({
|
|
8525
8729
|
resumeAudio: () => resumePanoAudio(),
|
|
8526
8730
|
playVideo: async ({ unmute = false } = {}) => {
|
|
@@ -8538,18 +8742,18 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8538
8742
|
}),
|
|
8539
8743
|
[bgmHost, videoHost]
|
|
8540
8744
|
);
|
|
8541
|
-
const runMediaActivation = (0,
|
|
8745
|
+
const runMediaActivation = (0, import_react30.useCallback)(() => {
|
|
8542
8746
|
const resume = mediaActivationControls.resumeAudio();
|
|
8543
8747
|
mediaActivationOptions?.onActivate?.(mediaActivationControls);
|
|
8544
8748
|
return resume;
|
|
8545
8749
|
}, [mediaActivationControls, mediaActivationOptions]);
|
|
8546
|
-
const activateMedia = (0,
|
|
8750
|
+
const activateMedia = (0, import_react30.useCallback)(() => {
|
|
8547
8751
|
setMediaActivated(true);
|
|
8548
8752
|
return runMediaActivation();
|
|
8549
8753
|
}, [runMediaActivation]);
|
|
8550
8754
|
const hasMediaActivationIntent = mediaActivationRevision >= 0 && hasPanoMediaActivationIntent(mediaActivationHost);
|
|
8551
8755
|
const shouldActivateMedia = mediaActivationOptions !== null && hasMediaActivationIntent && !mediaActivated;
|
|
8552
|
-
(0,
|
|
8756
|
+
(0, import_react30.useEffect)(() => {
|
|
8553
8757
|
if (!shouldActivateMedia) {
|
|
8554
8758
|
return;
|
|
8555
8759
|
}
|
|
@@ -8624,14 +8828,14 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8624
8828
|
videoHost
|
|
8625
8829
|
]);
|
|
8626
8830
|
const limitsKey = JSON.stringify(viewLimits);
|
|
8627
|
-
const parsedLimits = (0,
|
|
8628
|
-
const fallbackViewRef = (0,
|
|
8831
|
+
const parsedLimits = (0, import_react30.useMemo)(() => parseViewLimits(viewLimits), [limitsKey]);
|
|
8832
|
+
const fallbackViewRef = (0, import_react30.useRef)(DEFAULT_VIEW);
|
|
8629
8833
|
const normalizedMinFov = Math.max(1, Math.min(minFov, maxFov - 1));
|
|
8630
8834
|
const normalizedMaxFov = Math.min(
|
|
8631
8835
|
179,
|
|
8632
8836
|
Math.max(maxFov, normalizedMinFov + 1)
|
|
8633
8837
|
);
|
|
8634
|
-
const normalizedInitialView = (0,
|
|
8838
|
+
const normalizedInitialView = (0, import_react30.useMemo)(
|
|
8635
8839
|
() => ({
|
|
8636
8840
|
yaw: initialView?.yaw ?? DEFAULT_VIEW.yaw,
|
|
8637
8841
|
pitch: clampPanoPitch(initialView?.pitch ?? DEFAULT_VIEW.pitch),
|
|
@@ -8646,10 +8850,10 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8646
8850
|
]
|
|
8647
8851
|
);
|
|
8648
8852
|
fallbackViewRef.current = normalizedInitialView;
|
|
8649
|
-
const controlClaims = (0,
|
|
8853
|
+
const controlClaims = (0, import_react30.useMemo)(() => createControlClaims(), []);
|
|
8650
8854
|
resetControlClaims(controlClaims);
|
|
8651
8855
|
const controlsEnabled = controls !== false;
|
|
8652
|
-
const controlOptions = (0,
|
|
8856
|
+
const controlOptions = (0, import_react30.useMemo)(
|
|
8653
8857
|
() => typeof controls === "object" ? controls : {},
|
|
8654
8858
|
[controls]
|
|
8655
8859
|
);
|
|
@@ -8657,7 +8861,7 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8657
8861
|
const allModeInvert = controlOptions.invert === true;
|
|
8658
8862
|
const topRotateSpeed = controlOptions.rotateSpeed ?? DEFAULT_POINTER_ROTATE_SPEED;
|
|
8659
8863
|
const topZoomSpeed = controlOptions.zoomSpeed ?? DEFAULT_MOUSE_ZOOM_SPEED;
|
|
8660
|
-
const mouseChannel = (0,
|
|
8864
|
+
const mouseChannel = (0, import_react30.useMemo)(
|
|
8661
8865
|
() => resolveChannel(controlOptions.mouse, {
|
|
8662
8866
|
enabled: true,
|
|
8663
8867
|
rotateSpeed: topRotateSpeed,
|
|
@@ -8673,7 +8877,7 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8673
8877
|
topZoomSpeed
|
|
8674
8878
|
]
|
|
8675
8879
|
);
|
|
8676
|
-
const touchChannel = (0,
|
|
8880
|
+
const touchChannel = (0, import_react30.useMemo)(
|
|
8677
8881
|
() => resolveChannel(controlOptions.touch, {
|
|
8678
8882
|
enabled: true,
|
|
8679
8883
|
rotateSpeed: topRotateSpeed,
|
|
@@ -8682,13 +8886,13 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8682
8886
|
}),
|
|
8683
8887
|
[allModeInvert, controlOptions.touch, topRotateSpeed]
|
|
8684
8888
|
);
|
|
8685
|
-
const keyboardChannel = (0,
|
|
8889
|
+
const keyboardChannel = (0, import_react30.useMemo)(
|
|
8686
8890
|
() => resolveChannel(controlOptions.keyboard, {
|
|
8687
8891
|
enabled: true
|
|
8688
8892
|
}),
|
|
8689
8893
|
[controlOptions.keyboard]
|
|
8690
8894
|
);
|
|
8691
|
-
const enterFullscreen = (0,
|
|
8895
|
+
const enterFullscreen = (0, import_react30.useCallback)(async () => {
|
|
8692
8896
|
if (typeof document === "undefined") {
|
|
8693
8897
|
return;
|
|
8694
8898
|
}
|
|
@@ -8707,7 +8911,7 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8707
8911
|
acquireIphoneLandscapeFullscreen(root, "viewer");
|
|
8708
8912
|
}
|
|
8709
8913
|
}, []);
|
|
8710
|
-
const exitFullscreen = (0,
|
|
8914
|
+
const exitFullscreen = (0, import_react30.useCallback)(async () => {
|
|
8711
8915
|
if (typeof document === "undefined") {
|
|
8712
8916
|
return;
|
|
8713
8917
|
}
|
|
@@ -8719,7 +8923,7 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8719
8923
|
await exitElementFullscreen();
|
|
8720
8924
|
}
|
|
8721
8925
|
}, []);
|
|
8722
|
-
const toggleFullscreen = (0,
|
|
8926
|
+
const toggleFullscreen = (0, import_react30.useCallback)(async () => {
|
|
8723
8927
|
if (typeof document === "undefined") {
|
|
8724
8928
|
return;
|
|
8725
8929
|
}
|
|
@@ -8733,17 +8937,21 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8733
8937
|
}
|
|
8734
8938
|
await enterFullscreen();
|
|
8735
8939
|
}, [enterFullscreen, exitFullscreen]);
|
|
8736
|
-
const [isViewerFullscreen, setIsViewerFullscreen] = (0,
|
|
8940
|
+
const [isViewerFullscreen, setIsViewerFullscreen] = (0, import_react30.useState)(false);
|
|
8737
8941
|
const { context: overlayContext, setPortalContainer } = usePanoOverlayHost(isViewerFullscreen);
|
|
8738
|
-
const
|
|
8942
|
+
const { sceneChildren, overlayElements } = (0, import_react30.useMemo)(
|
|
8943
|
+
() => partitionPanoOverlay(children),
|
|
8944
|
+
[children]
|
|
8945
|
+
);
|
|
8946
|
+
const iphoneFullscreenAllowsScroll = (0, import_react30.useSyncExternalStore)(
|
|
8739
8947
|
subscribeIphoneLandscapeFullscreen,
|
|
8740
8948
|
() => getIphoneLandscapeFullscreenSnapshot().allowsDocumentScroll,
|
|
8741
8949
|
() => false
|
|
8742
8950
|
);
|
|
8743
|
-
(0,
|
|
8951
|
+
(0, import_react30.useEffect)(() => {
|
|
8744
8952
|
if (modalOpen) contextMenuOverlayApi.setSession(null);
|
|
8745
8953
|
}, [contextMenuOverlayApi, modalOpen]);
|
|
8746
|
-
(0,
|
|
8954
|
+
(0, import_react30.useEffect)(() => {
|
|
8747
8955
|
if (typeof document === "undefined") {
|
|
8748
8956
|
return;
|
|
8749
8957
|
}
|
|
@@ -8770,7 +8978,7 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8770
8978
|
unsubscribeIphone();
|
|
8771
8979
|
};
|
|
8772
8980
|
}, []);
|
|
8773
|
-
(0,
|
|
8981
|
+
(0, import_react30.useEffect)(() => {
|
|
8774
8982
|
const root = rootRef.current;
|
|
8775
8983
|
return () => {
|
|
8776
8984
|
if (root) {
|
|
@@ -8778,7 +8986,7 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8778
8986
|
}
|
|
8779
8987
|
};
|
|
8780
8988
|
}, []);
|
|
8781
|
-
(0,
|
|
8989
|
+
(0, import_react30.useEffect)(() => {
|
|
8782
8990
|
const root = rootRef.current;
|
|
8783
8991
|
if (!root) {
|
|
8784
8992
|
return;
|
|
@@ -8791,7 +8999,7 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8791
8999
|
root.removeEventListener("contextmenu", suppressNativeContextMenu, true);
|
|
8792
9000
|
};
|
|
8793
9001
|
}, []);
|
|
8794
|
-
const contextMenuActions = (0,
|
|
9002
|
+
const contextMenuActions = (0, import_react30.useMemo)(
|
|
8795
9003
|
() => ({
|
|
8796
9004
|
reset: () => {
|
|
8797
9005
|
controlsRef.current?.reset();
|
|
@@ -8803,24 +9011,24 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8803
9011
|
}),
|
|
8804
9012
|
[isViewerFullscreen, toggleFullscreen]
|
|
8805
9013
|
);
|
|
8806
|
-
const contextMenuChannel = (0,
|
|
9014
|
+
const contextMenuChannel = (0, import_react30.useMemo)(
|
|
8807
9015
|
() => resolveContextMenuChannel(contextMenu),
|
|
8808
9016
|
[contextMenu]
|
|
8809
9017
|
);
|
|
8810
|
-
const resolvedCursors = (0,
|
|
9018
|
+
const resolvedCursors = (0, import_react30.useMemo)(
|
|
8811
9019
|
() => resolvePanoCursors(cursors),
|
|
8812
9020
|
[cursors]
|
|
8813
9021
|
);
|
|
8814
9022
|
const legacyAutoRotateOptions = controlOptions;
|
|
8815
|
-
const [legacyAutoRotate, setLegacyAutoRotate] = (0,
|
|
9023
|
+
const [legacyAutoRotate, setLegacyAutoRotate] = (0, import_react30.useState)(
|
|
8816
9024
|
legacyAutoRotateOptions.autoRotate ?? false
|
|
8817
9025
|
);
|
|
8818
|
-
(0,
|
|
9026
|
+
(0, import_react30.useEffect)(() => {
|
|
8819
9027
|
setLegacyAutoRotate(legacyAutoRotateOptions.autoRotate ?? false);
|
|
8820
9028
|
}, [legacyAutoRotateOptions.autoRotate]);
|
|
8821
|
-
const isFullscreenRef = (0,
|
|
9029
|
+
const isFullscreenRef = (0, import_react30.useRef)(false);
|
|
8822
9030
|
isFullscreenRef.current = isViewerFullscreen;
|
|
8823
|
-
(0,
|
|
9031
|
+
(0, import_react30.useImperativeHandle)(
|
|
8824
9032
|
ref,
|
|
8825
9033
|
() => ({
|
|
8826
9034
|
// -- View --
|
|
@@ -8858,6 +9066,8 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8858
9066
|
isVRAvailable: () => webVRHost.snapshot.available,
|
|
8859
9067
|
isVREnabled: () => webVRHost.snapshot.mode !== null,
|
|
8860
9068
|
getVRMode: () => webVRHost.snapshot.mode,
|
|
9069
|
+
getVRState: () => webVRHost.state,
|
|
9070
|
+
subscribeVR: (onStoreChange) => subscribeWebVRHost(webVRHost, onStoreChange),
|
|
8861
9071
|
requestVRPermission: () => webVRHost.controller?.requestPermission() ?? Promise.resolve(false),
|
|
8862
9072
|
// -- Video --
|
|
8863
9073
|
getVideo: () => videoHost.controller,
|
|
@@ -8901,7 +9111,7 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8901
9111
|
webVRHost
|
|
8902
9112
|
]
|
|
8903
9113
|
);
|
|
8904
|
-
const rootStyle = (0,
|
|
9114
|
+
const rootStyle = (0, import_react30.useMemo)(
|
|
8905
9115
|
() => ({
|
|
8906
9116
|
overflow: "hidden",
|
|
8907
9117
|
position: "relative",
|
|
@@ -8990,7 +9200,7 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
8990
9200
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PanoramaEventSurface, {}),
|
|
8991
9201
|
contextMenuChannel.mount ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PanoContextMenu, { ...contextMenuChannel.props }) : null,
|
|
8992
9202
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(ControlClaimsContext.Provider, { value: controlClaims, children: [
|
|
8993
|
-
|
|
9203
|
+
sceneChildren,
|
|
8994
9204
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
8995
9205
|
DefaultControlChannels,
|
|
8996
9206
|
{
|
|
@@ -9035,15 +9245,18 @@ var PanoViewer = (0, import_react29.forwardRef)(
|
|
|
9035
9245
|
contextMenuOverlay,
|
|
9036
9246
|
hotspotAccessibilityControls
|
|
9037
9247
|
] }),
|
|
9038
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PanoEventBusContext.Provider, { value: eventBus, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PanoModalHostContext.Provider, { value: modalHost, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PanoOverlayContext.Provider, { value: overlayContext, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
9248
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PanoEventBusContext.Provider, { value: eventBus, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PanoModalHostContext.Provider, { value: modalHost, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PanoOverlayContext.Provider, { value: overlayContext, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PanoOverlayOutletContext.Provider, { value: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
9039
9249
|
"div",
|
|
9040
9250
|
{
|
|
9041
9251
|
"data-pano-overlay": "",
|
|
9042
9252
|
ref: setPortalContainer,
|
|
9043
9253
|
style: { position: "absolute", inset: 0, zIndex: 30, pointerEvents: "none" },
|
|
9044
|
-
children:
|
|
9254
|
+
children: [
|
|
9255
|
+
renderOverlay?.(overlayContext),
|
|
9256
|
+
overlayElements
|
|
9257
|
+
]
|
|
9045
9258
|
}
|
|
9046
|
-
) }) }) })
|
|
9259
|
+
) }) }) }) })
|
|
9047
9260
|
]
|
|
9048
9261
|
}
|
|
9049
9262
|
);
|
|
@@ -9136,18 +9349,18 @@ function hotspotAction(hotspot, trigger) {
|
|
|
9136
9349
|
}
|
|
9137
9350
|
|
|
9138
9351
|
// src/project-scenes.tsx
|
|
9139
|
-
var
|
|
9352
|
+
var import_react54 = require("react");
|
|
9140
9353
|
|
|
9141
9354
|
// src/scenes.tsx
|
|
9142
9355
|
var import_fiber18 = require("@react-three/fiber");
|
|
9143
|
-
var
|
|
9356
|
+
var import_react41 = require("react");
|
|
9144
9357
|
var import_three21 = require("three");
|
|
9145
9358
|
|
|
9146
9359
|
// src/scene-detail.tsx
|
|
9147
|
-
var
|
|
9148
|
-
var SceneDetailContext = (0,
|
|
9360
|
+
var import_react31 = require("react");
|
|
9361
|
+
var SceneDetailContext = (0, import_react31.createContext)(null);
|
|
9149
9362
|
function useSceneDetailReporter() {
|
|
9150
|
-
return (0,
|
|
9363
|
+
return (0, import_react31.useContext)(SceneDetailContext);
|
|
9151
9364
|
}
|
|
9152
9365
|
function viewTilesAreDrawable(textures) {
|
|
9153
9366
|
return textures.length > 0 && textures.every((texture) => texture != null);
|
|
@@ -9212,7 +9425,7 @@ function isSnapshotTransition(preset) {
|
|
|
9212
9425
|
|
|
9213
9426
|
// src/scene-transitions/snapshot-hold.tsx
|
|
9214
9427
|
var import_fiber11 = require("@react-three/fiber");
|
|
9215
|
-
var
|
|
9428
|
+
var import_react32 = require("react");
|
|
9216
9429
|
var import_three10 = require("three");
|
|
9217
9430
|
|
|
9218
9431
|
// src/scene-transitions/overlay-utils.ts
|
|
@@ -9548,13 +9761,13 @@ function createSnapshotMaterial(preset, texture) {
|
|
|
9548
9761
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
9549
9762
|
function SnapshotHold({ snapshot }) {
|
|
9550
9763
|
const { camera, gl } = (0, import_fiber11.useThree)();
|
|
9551
|
-
const meshRef = (0,
|
|
9552
|
-
const directionRef = (0,
|
|
9553
|
-
const material = (0,
|
|
9764
|
+
const meshRef = (0, import_react32.useRef)(null);
|
|
9765
|
+
const directionRef = (0, import_react32.useRef)(new import_three10.Vector3());
|
|
9766
|
+
const material = (0, import_react32.useMemo)(
|
|
9554
9767
|
() => createSnapshotMaterial("crossfade", snapshot.texture),
|
|
9555
9768
|
[snapshot.texture]
|
|
9556
9769
|
);
|
|
9557
|
-
(0,
|
|
9770
|
+
(0, import_react32.useEffect)(() => () => material.dispose(), [material]);
|
|
9558
9771
|
(0, import_fiber11.useFrame)(() => {
|
|
9559
9772
|
const mesh = meshRef.current;
|
|
9560
9773
|
if (!mesh || !isPerspectiveCamera(camera)) {
|
|
@@ -9632,7 +9845,7 @@ function phaseAfterSnapshot(preset, hold) {
|
|
|
9632
9845
|
|
|
9633
9846
|
// src/scene-transitions/particle-overlay.tsx
|
|
9634
9847
|
var import_fiber12 = require("@react-three/fiber");
|
|
9635
|
-
var
|
|
9848
|
+
var import_react33 = require("react");
|
|
9636
9849
|
var import_three11 = require("three");
|
|
9637
9850
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
9638
9851
|
var PARTICLE_GRID = 48;
|
|
@@ -9711,12 +9924,12 @@ function ParticleOverlay({
|
|
|
9711
9924
|
onFinish
|
|
9712
9925
|
}) {
|
|
9713
9926
|
const { camera } = (0, import_fiber12.useThree)();
|
|
9714
|
-
const meshRef = (0,
|
|
9715
|
-
const startRef = (0,
|
|
9716
|
-
const finishedRef = (0,
|
|
9717
|
-
const directionRef = (0,
|
|
9718
|
-
const geometry = (0,
|
|
9719
|
-
const material = (0,
|
|
9927
|
+
const meshRef = (0, import_react33.useRef)(null);
|
|
9928
|
+
const startRef = (0, import_react33.useRef)(null);
|
|
9929
|
+
const finishedRef = (0, import_react33.useRef)(false);
|
|
9930
|
+
const directionRef = (0, import_react33.useRef)(new import_three11.Vector3());
|
|
9931
|
+
const geometry = (0, import_react33.useMemo)(() => createParticleGeometry(), []);
|
|
9932
|
+
const material = (0, import_react33.useMemo)(
|
|
9720
9933
|
() => new import_three11.ShaderMaterial({
|
|
9721
9934
|
transparent: true,
|
|
9722
9935
|
depthTest: false,
|
|
@@ -9732,9 +9945,9 @@ function ParticleOverlay({
|
|
|
9732
9945
|
}),
|
|
9733
9946
|
[snapshot.texture]
|
|
9734
9947
|
);
|
|
9735
|
-
(0,
|
|
9736
|
-
(0,
|
|
9737
|
-
(0,
|
|
9948
|
+
(0, import_react33.useEffect)(() => () => geometry.dispose(), [geometry]);
|
|
9949
|
+
(0, import_react33.useEffect)(() => () => material.dispose(), [material]);
|
|
9950
|
+
(0, import_react33.useEffect)(() => {
|
|
9738
9951
|
startRef.current = null;
|
|
9739
9952
|
finishedRef.current = false;
|
|
9740
9953
|
material.uniforms.progress.value = 0;
|
|
@@ -9770,7 +9983,7 @@ function ParticleOverlay({
|
|
|
9770
9983
|
|
|
9771
9984
|
// src/scene-transitions/snapshot-overlay.tsx
|
|
9772
9985
|
var import_fiber13 = require("@react-three/fiber");
|
|
9773
|
-
var
|
|
9986
|
+
var import_react34 = require("react");
|
|
9774
9987
|
var import_three12 = require("three");
|
|
9775
9988
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
9776
9989
|
function SnapshotOverlay({
|
|
@@ -9781,18 +9994,18 @@ function SnapshotOverlay({
|
|
|
9781
9994
|
onFinish
|
|
9782
9995
|
}) {
|
|
9783
9996
|
const { camera, gl } = (0, import_fiber13.useThree)();
|
|
9784
|
-
const meshRef = (0,
|
|
9785
|
-
const startRef = (0,
|
|
9786
|
-
const finishedRef = (0,
|
|
9787
|
-
const directionRef = (0,
|
|
9788
|
-
const material = (0,
|
|
9997
|
+
const meshRef = (0, import_react34.useRef)(null);
|
|
9998
|
+
const startRef = (0, import_react34.useRef)(null);
|
|
9999
|
+
const finishedRef = (0, import_react34.useRef)(false);
|
|
10000
|
+
const directionRef = (0, import_react34.useRef)(new import_three12.Vector3());
|
|
10001
|
+
const material = (0, import_react34.useMemo)(() => {
|
|
9789
10002
|
if (!isSnapshotTransition(transition.preset)) {
|
|
9790
10003
|
return null;
|
|
9791
10004
|
}
|
|
9792
10005
|
return createSnapshotMaterial(transition.preset, snapshot.texture);
|
|
9793
10006
|
}, [snapshot.texture, transition.preset]);
|
|
9794
|
-
(0,
|
|
9795
|
-
(0,
|
|
10007
|
+
(0, import_react34.useEffect)(() => () => material?.dispose(), [material]);
|
|
10008
|
+
(0, import_react34.useEffect)(() => {
|
|
9796
10009
|
startRef.current = null;
|
|
9797
10010
|
finishedRef.current = false;
|
|
9798
10011
|
if (material) {
|
|
@@ -9874,11 +10087,11 @@ function TransitionOverlay(props) {
|
|
|
9874
10087
|
|
|
9875
10088
|
// src/sphere.tsx
|
|
9876
10089
|
var import_fiber14 = require("@react-three/fiber");
|
|
9877
|
-
var
|
|
10090
|
+
var import_react36 = require("react");
|
|
9878
10091
|
var import_three14 = require("three");
|
|
9879
10092
|
|
|
9880
10093
|
// src/pano-filter/pano-basic-material.tsx
|
|
9881
|
-
var
|
|
10094
|
+
var import_react35 = require("react");
|
|
9882
10095
|
var import_three13 = require("three");
|
|
9883
10096
|
|
|
9884
10097
|
// src/pano-filter/shaders.ts
|
|
@@ -10075,10 +10288,10 @@ function PanoBasicMaterial({
|
|
|
10075
10288
|
const preset = snapshot.enabled && target === "panorama" ? snapshot.preset : "none";
|
|
10076
10289
|
const matrix = snapshot.enabled && (target === "panorama" || snapshot.colorMatrixScope === "all") ? snapshot.colorMatrix : null;
|
|
10077
10290
|
const hasMatrix = matrix !== null;
|
|
10078
|
-
const currentRef = (0,
|
|
10291
|
+
const currentRef = (0, import_react35.useRef)({ matrix, intensity: snapshot.intensity });
|
|
10079
10292
|
currentRef.current = { matrix, intensity: snapshot.intensity };
|
|
10080
|
-
const shaderRef = (0,
|
|
10081
|
-
const onBeforeCompile = (0,
|
|
10293
|
+
const shaderRef = (0, import_react35.useRef)(null);
|
|
10294
|
+
const onBeforeCompile = (0, import_react35.useMemo)(() => {
|
|
10082
10295
|
const compile = (shader) => {
|
|
10083
10296
|
shaderRef.current = shader;
|
|
10084
10297
|
if (preset !== "none") {
|
|
@@ -10098,7 +10311,7 @@ function PanoBasicMaterial({
|
|
|
10098
10311
|
compile.toString = () => `pano-filter:${preset}:matrix:${hasMatrix}`;
|
|
10099
10312
|
return compile;
|
|
10100
10313
|
}, [preset, hasMatrix]);
|
|
10101
|
-
(0,
|
|
10314
|
+
(0, import_react35.useLayoutEffect)(() => {
|
|
10102
10315
|
const shader = shaderRef.current;
|
|
10103
10316
|
if (!shader) return;
|
|
10104
10317
|
if (shader.uniforms.uPanoFilterIntensity)
|
|
@@ -10124,12 +10337,12 @@ function PanoBasicMaterial({
|
|
|
10124
10337
|
// src/sphere.tsx
|
|
10125
10338
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
10126
10339
|
function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
10127
|
-
const [texture, setTexture] = (0,
|
|
10128
|
-
const onLoadRef = (0,
|
|
10129
|
-
const onErrorRef = (0,
|
|
10340
|
+
const [texture, setTexture] = (0, import_react36.useState)(null);
|
|
10341
|
+
const onLoadRef = (0, import_react36.useRef)(onLoad);
|
|
10342
|
+
const onErrorRef = (0, import_react36.useRef)(onError);
|
|
10130
10343
|
onLoadRef.current = onLoad;
|
|
10131
10344
|
onErrorRef.current = onError;
|
|
10132
|
-
(0,
|
|
10345
|
+
(0, import_react36.useEffect)(() => {
|
|
10133
10346
|
if (!url) {
|
|
10134
10347
|
setTexture(null);
|
|
10135
10348
|
return;
|
|
@@ -10168,7 +10381,7 @@ function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
|
10168
10381
|
active = false;
|
|
10169
10382
|
};
|
|
10170
10383
|
}, [anisotropy, generateMipmaps, url]);
|
|
10171
|
-
(0,
|
|
10384
|
+
(0, import_react36.useEffect)(
|
|
10172
10385
|
() => () => {
|
|
10173
10386
|
texture?.dispose();
|
|
10174
10387
|
},
|
|
@@ -10188,7 +10401,7 @@ function Sphere({
|
|
|
10188
10401
|
}) {
|
|
10189
10402
|
const gl = (0, import_fiber14.useThree)((state) => state.gl);
|
|
10190
10403
|
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
10191
|
-
const resolvedPreviewUrl = (0,
|
|
10404
|
+
const resolvedPreviewUrl = (0, import_react36.useMemo)(
|
|
10192
10405
|
() => resolveUrlAgainstFile(src, previewUrl),
|
|
10193
10406
|
[previewUrl, src]
|
|
10194
10407
|
);
|
|
@@ -10207,12 +10420,12 @@ function Sphere({
|
|
|
10207
10420
|
onPreviewError
|
|
10208
10421
|
);
|
|
10209
10422
|
const displayTexture = texture ?? previewTexture;
|
|
10210
|
-
const readyRef = (0,
|
|
10423
|
+
const readyRef = (0, import_react36.useRef)(false);
|
|
10211
10424
|
const detailReporter = useSceneDetailReporter();
|
|
10212
|
-
(0,
|
|
10425
|
+
(0, import_react36.useEffect)(() => {
|
|
10213
10426
|
readyRef.current = false;
|
|
10214
10427
|
}, [resolvedPreviewUrl, src]);
|
|
10215
|
-
(0,
|
|
10428
|
+
(0, import_react36.useEffect)(() => {
|
|
10216
10429
|
if (!detailReporter) {
|
|
10217
10430
|
return;
|
|
10218
10431
|
}
|
|
@@ -10221,7 +10434,7 @@ function Sphere({
|
|
|
10221
10434
|
detailReporter.report(false);
|
|
10222
10435
|
};
|
|
10223
10436
|
}, [detailReporter, texture]);
|
|
10224
|
-
(0,
|
|
10437
|
+
(0, import_react36.useEffect)(() => {
|
|
10225
10438
|
if (!displayTexture || readyRef.current) {
|
|
10226
10439
|
return;
|
|
10227
10440
|
}
|
|
@@ -10253,7 +10466,7 @@ function Sphere({
|
|
|
10253
10466
|
|
|
10254
10467
|
// src/sphere-tile/sphere-tile.tsx
|
|
10255
10468
|
var import_fiber16 = require("@react-three/fiber");
|
|
10256
|
-
var
|
|
10469
|
+
var import_react39 = require("react");
|
|
10257
10470
|
var import_three18 = require("three");
|
|
10258
10471
|
|
|
10259
10472
|
// src/tile/texture-manager.ts
|
|
@@ -10263,6 +10476,20 @@ var EMPTY_TEXTURE_SNAPSHOT = {
|
|
|
10263
10476
|
texture: null,
|
|
10264
10477
|
error: null
|
|
10265
10478
|
};
|
|
10479
|
+
var MIPMAP_MEMORY_FACTOR = 4 / 3;
|
|
10480
|
+
function mipmappedTextureBytes(width, height) {
|
|
10481
|
+
return Math.ceil(width * height * 4 * MIPMAP_MEMORY_FACTOR);
|
|
10482
|
+
}
|
|
10483
|
+
function configureMipmappedTexture(texture, anisotropy) {
|
|
10484
|
+
texture.colorSpace = import_three15.SRGBColorSpace;
|
|
10485
|
+
texture.wrapS = import_three15.ClampToEdgeWrapping;
|
|
10486
|
+
texture.wrapT = import_three15.ClampToEdgeWrapping;
|
|
10487
|
+
texture.magFilter = import_three15.LinearFilter;
|
|
10488
|
+
texture.minFilter = import_three15.LinearMipmapLinearFilter;
|
|
10489
|
+
texture.generateMipmaps = true;
|
|
10490
|
+
texture.anisotropy = Math.max(1, anisotropy);
|
|
10491
|
+
texture.needsUpdate = true;
|
|
10492
|
+
}
|
|
10266
10493
|
var TileTextureManager = class {
|
|
10267
10494
|
constructor(options) {
|
|
10268
10495
|
this.loader = new import_three15.TextureLoader();
|
|
@@ -10414,7 +10641,10 @@ var TileTextureManager = class {
|
|
|
10414
10641
|
entry.texture = texture;
|
|
10415
10642
|
entry.status = "loaded";
|
|
10416
10643
|
entry.error = null;
|
|
10417
|
-
entry.bytes =
|
|
10644
|
+
entry.bytes = mipmappedTextureBytes(
|
|
10645
|
+
entry.address.width,
|
|
10646
|
+
entry.address.height
|
|
10647
|
+
);
|
|
10418
10648
|
entry.lastUsed = performance.now();
|
|
10419
10649
|
this.totalBytes += entry.bytes;
|
|
10420
10650
|
this.loaded += 1;
|
|
@@ -10437,14 +10667,7 @@ var TileTextureManager = class {
|
|
|
10437
10667
|
}
|
|
10438
10668
|
}
|
|
10439
10669
|
configureTexture(texture) {
|
|
10440
|
-
texture
|
|
10441
|
-
texture.wrapS = import_three15.ClampToEdgeWrapping;
|
|
10442
|
-
texture.wrapT = import_three15.ClampToEdgeWrapping;
|
|
10443
|
-
texture.magFilter = import_three15.LinearFilter;
|
|
10444
|
-
texture.minFilter = import_three15.LinearFilter;
|
|
10445
|
-
texture.generateMipmaps = false;
|
|
10446
|
-
texture.anisotropy = Math.min(4, this.options.anisotropy);
|
|
10447
|
-
texture.needsUpdate = true;
|
|
10670
|
+
configureMipmappedTexture(texture, this.options.anisotropy);
|
|
10448
10671
|
}
|
|
10449
10672
|
evict() {
|
|
10450
10673
|
if (this.totalBytes <= this.options.maxBytes) {
|
|
@@ -10483,9 +10706,9 @@ var TileTextureManager = class {
|
|
|
10483
10706
|
|
|
10484
10707
|
// src/tile/texture-manager-context.tsx
|
|
10485
10708
|
var import_fiber15 = require("@react-three/fiber");
|
|
10486
|
-
var
|
|
10709
|
+
var import_react37 = require("react");
|
|
10487
10710
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
10488
|
-
var TileTextureManagerContext = (0,
|
|
10711
|
+
var TileTextureManagerContext = (0, import_react37.createContext)(null);
|
|
10489
10712
|
function TileTextureManagerProvider({
|
|
10490
10713
|
children,
|
|
10491
10714
|
maxTextureMemoryMb = 128,
|
|
@@ -10493,7 +10716,7 @@ function TileTextureManagerProvider({
|
|
|
10493
10716
|
}) {
|
|
10494
10717
|
const gl = (0, import_fiber15.useThree)((state) => state.gl);
|
|
10495
10718
|
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
10496
|
-
const manager = (0,
|
|
10719
|
+
const manager = (0, import_react37.useMemo)(
|
|
10497
10720
|
() => new TileTextureManager({
|
|
10498
10721
|
anisotropy,
|
|
10499
10722
|
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
@@ -10502,24 +10725,24 @@ function TileTextureManagerProvider({
|
|
|
10502
10725
|
}),
|
|
10503
10726
|
[anisotropy, maxConcurrentLoads, maxTextureMemoryMb]
|
|
10504
10727
|
);
|
|
10505
|
-
(0,
|
|
10728
|
+
(0, import_react37.useEffect)(() => {
|
|
10506
10729
|
manager.resume();
|
|
10507
10730
|
return () => manager.dispose();
|
|
10508
10731
|
}, [manager]);
|
|
10509
10732
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TileTextureManagerContext.Provider, { value: manager, children });
|
|
10510
10733
|
}
|
|
10511
10734
|
function useSharedTileTextureManager() {
|
|
10512
|
-
return (0,
|
|
10735
|
+
return (0, import_react37.useContext)(TileTextureManagerContext);
|
|
10513
10736
|
}
|
|
10514
10737
|
|
|
10515
10738
|
// src/tile/texture-hooks.ts
|
|
10516
|
-
var
|
|
10739
|
+
var import_react38 = require("react");
|
|
10517
10740
|
var import_three16 = require("three");
|
|
10518
10741
|
function usePreviewTexture(url, anisotropy, onError) {
|
|
10519
|
-
const [texture, setTexture] = (0,
|
|
10520
|
-
const onErrorRef = (0,
|
|
10742
|
+
const [texture, setTexture] = (0, import_react38.useState)(null);
|
|
10743
|
+
const onErrorRef = (0, import_react38.useRef)(onError);
|
|
10521
10744
|
onErrorRef.current = onError;
|
|
10522
|
-
(0,
|
|
10745
|
+
(0, import_react38.useEffect)(() => {
|
|
10523
10746
|
if (!url) {
|
|
10524
10747
|
setTexture(null);
|
|
10525
10748
|
return;
|
|
@@ -10534,14 +10757,7 @@ function usePreviewTexture(url, anisotropy, onError) {
|
|
|
10534
10757
|
loadedTexture.dispose();
|
|
10535
10758
|
return;
|
|
10536
10759
|
}
|
|
10537
|
-
loadedTexture
|
|
10538
|
-
loadedTexture.wrapS = import_three16.ClampToEdgeWrapping;
|
|
10539
|
-
loadedTexture.wrapT = import_three16.ClampToEdgeWrapping;
|
|
10540
|
-
loadedTexture.magFilter = import_three16.LinearFilter;
|
|
10541
|
-
loadedTexture.minFilter = import_three16.LinearFilter;
|
|
10542
|
-
loadedTexture.generateMipmaps = false;
|
|
10543
|
-
loadedTexture.anisotropy = Math.min(4, anisotropy);
|
|
10544
|
-
loadedTexture.needsUpdate = true;
|
|
10760
|
+
configureMipmappedTexture(loadedTexture, anisotropy);
|
|
10545
10761
|
setTexture(loadedTexture);
|
|
10546
10762
|
},
|
|
10547
10763
|
void 0,
|
|
@@ -10556,7 +10772,7 @@ function usePreviewTexture(url, anisotropy, onError) {
|
|
|
10556
10772
|
active = false;
|
|
10557
10773
|
};
|
|
10558
10774
|
}, [anisotropy, url]);
|
|
10559
|
-
(0,
|
|
10775
|
+
(0, import_react38.useEffect)(
|
|
10560
10776
|
() => () => {
|
|
10561
10777
|
texture?.dispose();
|
|
10562
10778
|
},
|
|
@@ -10565,14 +10781,14 @@ function usePreviewTexture(url, anisotropy, onError) {
|
|
|
10565
10781
|
return texture;
|
|
10566
10782
|
}
|
|
10567
10783
|
function useManagedTexture(manager, key, url, address) {
|
|
10568
|
-
const [managedState, setManagedState] = (0,
|
|
10784
|
+
const [managedState, setManagedState] = (0, import_react38.useState)(() => ({
|
|
10569
10785
|
manager,
|
|
10570
10786
|
key,
|
|
10571
10787
|
url,
|
|
10572
10788
|
snapshot: manager.getSnapshot(key)
|
|
10573
10789
|
}));
|
|
10574
10790
|
const snapshot = managedState.manager === manager && managedState.key === key && managedState.url === url ? managedState.snapshot : manager.getSnapshot(key);
|
|
10575
|
-
(0,
|
|
10791
|
+
(0, import_react38.useEffect)(
|
|
10576
10792
|
() => manager.acquire(key, url, address, (nextSnapshot) => {
|
|
10577
10793
|
setManagedState({
|
|
10578
10794
|
manager,
|
|
@@ -10707,8 +10923,17 @@ function sphereTileGeometry(address, yawOffset2, radius = DEFAULT_PANORAMA_RADIU
|
|
|
10707
10923
|
geometry.computeBoundingSphere();
|
|
10708
10924
|
return geometry;
|
|
10709
10925
|
}
|
|
10710
|
-
function
|
|
10711
|
-
const
|
|
10926
|
+
function tanHalfFov(verticalFov) {
|
|
10927
|
+
const fov = Math.min(179, Math.max(1, verticalFov));
|
|
10928
|
+
return Math.tan(import_three17.MathUtils.degToRad(fov) * 0.5);
|
|
10929
|
+
}
|
|
10930
|
+
function preferredSphereLevel(levels, height, dpr, verticalFov, width = height) {
|
|
10931
|
+
const pixelHeight = Math.max(1, height) * dpr;
|
|
10932
|
+
const pixelWidth = Math.max(1, width) * dpr;
|
|
10933
|
+
const tanHalfV = tanHalfFov(verticalFov);
|
|
10934
|
+
const tanHalfH = pixelWidth / pixelHeight * tanHalfV;
|
|
10935
|
+
const edgeScale = 1 + Math.max(tanHalfV, tanHalfH) ** 2;
|
|
10936
|
+
const needed = pixelHeight * 0.5 / tanHalfV * Math.PI * edgeScale;
|
|
10712
10937
|
const index = levels.findIndex((level) => level.height >= needed);
|
|
10713
10938
|
return index < 0 ? levels.length - 1 : index;
|
|
10714
10939
|
}
|
|
@@ -10730,7 +10955,7 @@ function SpherePatch({
|
|
|
10730
10955
|
yawOffset: yawOffset2,
|
|
10731
10956
|
preview = false
|
|
10732
10957
|
}) {
|
|
10733
|
-
const geometry = (0,
|
|
10958
|
+
const geometry = (0, import_react39.useMemo)(
|
|
10734
10959
|
() => sphereTileGeometry(
|
|
10735
10960
|
address,
|
|
10736
10961
|
yawOffset2,
|
|
@@ -10738,7 +10963,7 @@ function SpherePatch({
|
|
|
10738
10963
|
),
|
|
10739
10964
|
[address, yawOffset2, preview]
|
|
10740
10965
|
);
|
|
10741
|
-
(0,
|
|
10966
|
+
(0, import_react39.useEffect)(() => () => geometry.dispose(), [geometry]);
|
|
10742
10967
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
10743
10968
|
"mesh",
|
|
10744
10969
|
{
|
|
@@ -10757,7 +10982,7 @@ function SpherePatch({
|
|
|
10757
10982
|
}
|
|
10758
10983
|
);
|
|
10759
10984
|
}
|
|
10760
|
-
var ManagedPatch = (0,
|
|
10985
|
+
var ManagedPatch = (0, import_react39.memo)(function ManagedPatch2({
|
|
10761
10986
|
address,
|
|
10762
10987
|
manager,
|
|
10763
10988
|
resolveUrl,
|
|
@@ -10771,7 +10996,7 @@ var ManagedPatch = (0, import_react38.memo)(function ManagedPatch2({
|
|
|
10771
10996
|
url,
|
|
10772
10997
|
address
|
|
10773
10998
|
);
|
|
10774
|
-
(0,
|
|
10999
|
+
(0, import_react39.useEffect)(() => {
|
|
10775
11000
|
if (snapshot.texture) ready();
|
|
10776
11001
|
}, [snapshot.texture, ready]);
|
|
10777
11002
|
return snapshot.texture ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
@@ -10809,7 +11034,7 @@ function SphereTileSource({
|
|
|
10809
11034
|
anisotropy,
|
|
10810
11035
|
onPreviewError
|
|
10811
11036
|
);
|
|
10812
|
-
const callbacks = (0,
|
|
11037
|
+
const callbacks = (0, import_react39.useRef)({
|
|
10813
11038
|
onReady,
|
|
10814
11039
|
onLoadProgress,
|
|
10815
11040
|
onTileError,
|
|
@@ -10821,7 +11046,7 @@ function SphereTileSource({
|
|
|
10821
11046
|
1,
|
|
10822
11047
|
Number.isFinite(maxTextureMemoryMb) ? maxTextureMemoryMb : 128
|
|
10823
11048
|
) * 1024 * 1024;
|
|
10824
|
-
const ownedManager = (0,
|
|
11049
|
+
const ownedManager = (0, import_react39.useMemo)(
|
|
10825
11050
|
() => new TileTextureManager({
|
|
10826
11051
|
anisotropy,
|
|
10827
11052
|
maxBytes: ownedBudget,
|
|
@@ -10842,17 +11067,17 @@ function SphereTileSource({
|
|
|
10842
11067
|
);
|
|
10843
11068
|
const manager = sharedManager ?? ownedManager;
|
|
10844
11069
|
const budget = manager.memoryBudgetBytes;
|
|
10845
|
-
const readyRef = (0,
|
|
10846
|
-
const ready = (0,
|
|
11070
|
+
const readyRef = (0, import_react39.useRef)(false);
|
|
11071
|
+
const ready = (0, import_react39.useCallback)(() => {
|
|
10847
11072
|
if (!readyRef.current) {
|
|
10848
11073
|
readyRef.current = true;
|
|
10849
11074
|
callbacks.current.onReady?.();
|
|
10850
11075
|
}
|
|
10851
11076
|
}, []);
|
|
10852
|
-
(0,
|
|
11077
|
+
(0, import_react39.useEffect)(() => {
|
|
10853
11078
|
if (preview) ready();
|
|
10854
11079
|
}, [preview, ready]);
|
|
10855
|
-
(0,
|
|
11080
|
+
(0, import_react39.useEffect)(() => {
|
|
10856
11081
|
manager.resume();
|
|
10857
11082
|
return () => {
|
|
10858
11083
|
if (manager === ownedManager) {
|
|
@@ -10862,14 +11087,14 @@ function SphereTileSource({
|
|
|
10862
11087
|
queueMicrotask(() => manager.releaseUnused());
|
|
10863
11088
|
};
|
|
10864
11089
|
}, [manager, ownedManager]);
|
|
10865
|
-
const resolveUrl = (0,
|
|
11090
|
+
const resolveUrl = (0, import_react39.useMemo)(
|
|
10866
11091
|
() => (address) => resolveAssetUrl(
|
|
10867
11092
|
baseUrl,
|
|
10868
11093
|
resolveTileUrl ? resolveTileUrl(address) : resolveSphereTemplateUrl(urlTemplate, address, indexBase)
|
|
10869
11094
|
),
|
|
10870
11095
|
[baseUrl, resolveTileUrl, urlTemplate, indexBase]
|
|
10871
11096
|
);
|
|
10872
|
-
const candidates = (0,
|
|
11097
|
+
const candidates = (0, import_react39.useMemo)(
|
|
10873
11098
|
() => config.levels.map(
|
|
10874
11099
|
(level, index) => sphereTileAddresses(level, index, config.tileSize).map((address) => ({
|
|
10875
11100
|
address,
|
|
@@ -10878,17 +11103,17 @@ function SphereTileSource({
|
|
|
10878
11103
|
),
|
|
10879
11104
|
[config, yawOffset2]
|
|
10880
11105
|
);
|
|
10881
|
-
const previewAddress = (0,
|
|
11106
|
+
const previewAddress = (0, import_react39.useMemo)(
|
|
10882
11107
|
() => sphereTileAddresses({ width: 2, height: 1 }, 0, 2)[0],
|
|
10883
11108
|
[]
|
|
10884
11109
|
);
|
|
10885
|
-
const [layers, setLayers] = (0,
|
|
11110
|
+
const [layers, setLayers] = (0, import_react39.useState)([]);
|
|
10886
11111
|
const detailReporter = useSceneDetailReporter();
|
|
10887
|
-
const detailReporterRef = (0,
|
|
11112
|
+
const detailReporterRef = (0, import_react39.useRef)(detailReporter);
|
|
10888
11113
|
detailReporterRef.current = detailReporter;
|
|
10889
|
-
const detailTokenRef = (0,
|
|
10890
|
-
const targetKeysRef = (0,
|
|
10891
|
-
const scratch = (0,
|
|
11114
|
+
const detailTokenRef = (0, import_react39.useRef)("");
|
|
11115
|
+
const targetKeysRef = (0, import_react39.useRef)([]);
|
|
11116
|
+
const scratch = (0, import_react39.useMemo)(
|
|
10892
11117
|
() => ({
|
|
10893
11118
|
camera: new import_three18.PerspectiveCamera(),
|
|
10894
11119
|
frustum: new import_three18.Frustum(),
|
|
@@ -10936,7 +11161,13 @@ function SphereTileSource({
|
|
|
10936
11161
|
scratch.camera.matrixWorldInverse
|
|
10937
11162
|
);
|
|
10938
11163
|
scratch.frustum.setFromProjectionMatrix(scratch.matrix);
|
|
10939
|
-
let level = loadMode === "preview" ? -1 : loadMode === "base" ? 0 : preferredSphereLevel(
|
|
11164
|
+
let level = loadMode === "preview" ? -1 : loadMode === "base" ? 0 : preferredSphereLevel(
|
|
11165
|
+
config.levels,
|
|
11166
|
+
size.height,
|
|
11167
|
+
dpr,
|
|
11168
|
+
camera.fov,
|
|
11169
|
+
size.width
|
|
11170
|
+
);
|
|
10940
11171
|
const next = [];
|
|
10941
11172
|
let residentBytes = 0;
|
|
10942
11173
|
for (let index = 0; index <= level; index++) {
|
|
@@ -10944,7 +11175,7 @@ function SphereTileSource({
|
|
|
10944
11175
|
({ bounds }) => scratch.frustum.intersectsBox(bounds)
|
|
10945
11176
|
).map(({ address }) => address);
|
|
10946
11177
|
const bytes = addresses.reduce(
|
|
10947
|
-
(total, address) => total + address.width
|
|
11178
|
+
(total, address) => total + mipmappedTextureBytes(address.width, address.height),
|
|
10948
11179
|
0
|
|
10949
11180
|
);
|
|
10950
11181
|
if (residentBytes + bytes > budget) {
|
|
@@ -11003,14 +11234,14 @@ function SphereTileSource({
|
|
|
11003
11234
|
}
|
|
11004
11235
|
function SphereTile({ multires, ...props }) {
|
|
11005
11236
|
const token = typeof multires === "string" ? multires : JSON.stringify(multires);
|
|
11006
|
-
const config = (0,
|
|
11237
|
+
const config = (0, import_react39.useMemo)(() => parseSphereMultires(multires), [token]);
|
|
11007
11238
|
const sourceKey = `${props.baseUrl}\0${token}\0${props.previewUrl}\0${props.urlTemplate ?? ""}\0${props.indexBase ?? 1}`;
|
|
11008
11239
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SphereTileSource, { ...props, config }, sourceKey);
|
|
11009
11240
|
}
|
|
11010
11241
|
|
|
11011
11242
|
// src/tile/tile.tsx
|
|
11012
11243
|
var import_fiber17 = require("@react-three/fiber");
|
|
11013
|
-
var
|
|
11244
|
+
var import_react40 = require("react");
|
|
11014
11245
|
var import_three20 = require("three");
|
|
11015
11246
|
|
|
11016
11247
|
// src/tile/face-layout.ts
|
|
@@ -11106,8 +11337,19 @@ function makeTileAddress(face, level, faceSize, tileSize, col, row) {
|
|
|
11106
11337
|
function tileKey(address) {
|
|
11107
11338
|
return `${address.level}/${address.face}/${address.row}/${address.col}`;
|
|
11108
11339
|
}
|
|
11109
|
-
function
|
|
11110
|
-
const
|
|
11340
|
+
function tanHalfFov2(verticalFov) {
|
|
11341
|
+
const fov = Math.min(179, Math.max(1, verticalFov));
|
|
11342
|
+
return Math.tan(import_three19.MathUtils.degToRad(fov) * 0.5);
|
|
11343
|
+
}
|
|
11344
|
+
function getPreferredLevel(levels, viewportHeight, pixelRatio, verticalFov, currentLevel, viewportWidth = viewportHeight) {
|
|
11345
|
+
const height = Math.max(1, viewportHeight) * pixelRatio;
|
|
11346
|
+
const width = Math.max(1, viewportWidth) * pixelRatio;
|
|
11347
|
+
const tanHalfV = tanHalfFov2(verticalFov);
|
|
11348
|
+
const requiredFaceSize = Math.max(
|
|
11349
|
+
height / tanHalfV,
|
|
11350
|
+
height * tanHalfV,
|
|
11351
|
+
width * width * tanHalfV / height
|
|
11352
|
+
);
|
|
11111
11353
|
let preferredLevel = levels.length;
|
|
11112
11354
|
for (let index = 0; index < levels.length; index += 1) {
|
|
11113
11355
|
if (levels[index] >= requiredFaceSize) {
|
|
@@ -11163,7 +11405,7 @@ function PreviewFace({
|
|
|
11163
11405
|
texture,
|
|
11164
11406
|
faceOrder
|
|
11165
11407
|
}) {
|
|
11166
|
-
const geometry = (0,
|
|
11408
|
+
const geometry = (0, import_react40.useMemo)(() => {
|
|
11167
11409
|
const nextGeometry = new import_three20.PlaneGeometry(
|
|
11168
11410
|
PREVIEW_RADIUS * 2,
|
|
11169
11411
|
PREVIEW_RADIUS * 2
|
|
@@ -11178,7 +11420,7 @@ function PreviewFace({
|
|
|
11178
11420
|
uv.needsUpdate = true;
|
|
11179
11421
|
return nextGeometry;
|
|
11180
11422
|
}, [face, faceOrder]);
|
|
11181
|
-
(0,
|
|
11423
|
+
(0, import_react40.useEffect)(
|
|
11182
11424
|
() => () => {
|
|
11183
11425
|
geometry.dispose();
|
|
11184
11426
|
},
|
|
@@ -11218,7 +11460,7 @@ function PreviewCube({
|
|
|
11218
11460
|
face
|
|
11219
11461
|
));
|
|
11220
11462
|
}
|
|
11221
|
-
var TileMesh = (0,
|
|
11463
|
+
var TileMesh = (0, import_react40.memo)(function TileMesh2({
|
|
11222
11464
|
address,
|
|
11223
11465
|
manager,
|
|
11224
11466
|
renderOrder,
|
|
@@ -11251,7 +11493,7 @@ var TileMesh = (0, import_react39.memo)(function TileMesh2({
|
|
|
11251
11493
|
}
|
|
11252
11494
|
) });
|
|
11253
11495
|
});
|
|
11254
|
-
var TileLayerMeshes = (0,
|
|
11496
|
+
var TileLayerMeshes = (0, import_react40.memo)(function TileLayerMeshes2({
|
|
11255
11497
|
layer,
|
|
11256
11498
|
manager,
|
|
11257
11499
|
resolveUrl
|
|
@@ -11423,10 +11665,10 @@ function Tile({
|
|
|
11423
11665
|
onLevelChange
|
|
11424
11666
|
}) {
|
|
11425
11667
|
const { camera, gl, size } = (0, import_fiber17.useThree)();
|
|
11426
|
-
const multiresConfig = (0,
|
|
11668
|
+
const multiresConfig = (0, import_react40.useMemo)(() => parseMultires(multires), [multires]);
|
|
11427
11669
|
const { levels, tileSize } = multiresConfig;
|
|
11428
11670
|
const multiresToken = `${tileSize}:${levels.join(",")}`;
|
|
11429
|
-
const candidatesByLevel = (0,
|
|
11671
|
+
const candidatesByLevel = (0, import_react40.useMemo)(
|
|
11430
11672
|
() => buildTileCandidates(levels, tileSize),
|
|
11431
11673
|
[levels, tileSize]
|
|
11432
11674
|
);
|
|
@@ -11438,13 +11680,13 @@ function Tile({
|
|
|
11438
11680
|
onPreviewError
|
|
11439
11681
|
);
|
|
11440
11682
|
const sharedManager = useSharedTileTextureManager();
|
|
11441
|
-
const progressRef = (0,
|
|
11442
|
-
const errorRef = (0,
|
|
11443
|
-
const levelChangeRef = (0,
|
|
11683
|
+
const progressRef = (0, import_react40.useRef)(onLoadProgress);
|
|
11684
|
+
const errorRef = (0, import_react40.useRef)(onTileError);
|
|
11685
|
+
const levelChangeRef = (0, import_react40.useRef)(onLevelChange);
|
|
11444
11686
|
progressRef.current = onLoadProgress;
|
|
11445
11687
|
errorRef.current = onTileError;
|
|
11446
11688
|
levelChangeRef.current = onLevelChange;
|
|
11447
|
-
const ownedManager = (0,
|
|
11689
|
+
const ownedManager = (0, import_react40.useMemo)(
|
|
11448
11690
|
() => new TileTextureManager({
|
|
11449
11691
|
anisotropy,
|
|
11450
11692
|
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
@@ -11465,7 +11707,7 @@ function Tile({
|
|
|
11465
11707
|
]
|
|
11466
11708
|
);
|
|
11467
11709
|
const manager = sharedManager ?? ownedManager;
|
|
11468
|
-
(0,
|
|
11710
|
+
(0, import_react40.useEffect)(() => {
|
|
11469
11711
|
manager.resume();
|
|
11470
11712
|
return () => {
|
|
11471
11713
|
if (manager === ownedManager) {
|
|
@@ -11475,11 +11717,11 @@ function Tile({
|
|
|
11475
11717
|
queueMicrotask(() => manager.releaseUnused());
|
|
11476
11718
|
};
|
|
11477
11719
|
}, [manager, ownedManager]);
|
|
11478
|
-
const readyRef = (0,
|
|
11479
|
-
(0,
|
|
11720
|
+
const readyRef = (0, import_react40.useRef)(false);
|
|
11721
|
+
(0, import_react40.useEffect)(() => {
|
|
11480
11722
|
readyRef.current = false;
|
|
11481
11723
|
}, [effectivePreviewUrl]);
|
|
11482
|
-
(0,
|
|
11724
|
+
(0, import_react40.useEffect)(() => {
|
|
11483
11725
|
if (!previewTexture || readyRef.current) {
|
|
11484
11726
|
return;
|
|
11485
11727
|
}
|
|
@@ -11487,37 +11729,37 @@ function Tile({
|
|
|
11487
11729
|
onReady?.();
|
|
11488
11730
|
}, [onReady, previewTexture]);
|
|
11489
11731
|
const template = urlTemplate ?? buildDefaultTileUrlTemplate();
|
|
11490
|
-
const resolveUrl = (0,
|
|
11732
|
+
const resolveUrl = (0, import_react40.useMemo)(
|
|
11491
11733
|
() => (address) => {
|
|
11492
11734
|
const relativePath = resolveTileUrl ? resolveTileUrl(address) : resolveTemplateUrl(template, address);
|
|
11493
11735
|
return resolveRelativeTileUrl(baseUrl, relativePath);
|
|
11494
11736
|
},
|
|
11495
11737
|
[baseUrl, resolveTileUrl, template]
|
|
11496
11738
|
);
|
|
11497
|
-
const [layers, setLayers] = (0,
|
|
11498
|
-
const layerTokenRef = (0,
|
|
11499
|
-
const currentLevelRef = (0,
|
|
11500
|
-
const lastUpdateAtRef = (0,
|
|
11501
|
-
const visibilityDirtyRef = (0,
|
|
11502
|
-
const lastVisibilityQuaternionRef = (0,
|
|
11503
|
-
const lastVisibilityFovRef = (0,
|
|
11504
|
-
const lastViewportRef = (0,
|
|
11505
|
-
const frustumRef = (0,
|
|
11506
|
-
const projectionMatrixRef = (0,
|
|
11507
|
-
const visibilityCameraRef = (0,
|
|
11508
|
-
const trackedLoadModeRef = (0,
|
|
11509
|
-
const targetKeysRef = (0,
|
|
11510
|
-
const detailTokenRef = (0,
|
|
11739
|
+
const [layers, setLayers] = (0, import_react40.useState)([]);
|
|
11740
|
+
const layerTokenRef = (0, import_react40.useRef)("");
|
|
11741
|
+
const currentLevelRef = (0, import_react40.useRef)(1);
|
|
11742
|
+
const lastUpdateAtRef = (0, import_react40.useRef)(-Infinity);
|
|
11743
|
+
const visibilityDirtyRef = (0, import_react40.useRef)(true);
|
|
11744
|
+
const lastVisibilityQuaternionRef = (0, import_react40.useRef)(camera.quaternion.clone());
|
|
11745
|
+
const lastVisibilityFovRef = (0, import_react40.useRef)(Number.NaN);
|
|
11746
|
+
const lastViewportRef = (0, import_react40.useRef)({ width: 0, height: 0, dpr: 0 });
|
|
11747
|
+
const frustumRef = (0, import_react40.useRef)(new import_three20.Frustum());
|
|
11748
|
+
const projectionMatrixRef = (0, import_react40.useRef)(new import_three20.Matrix4());
|
|
11749
|
+
const visibilityCameraRef = (0, import_react40.useRef)(new import_three20.PerspectiveCamera());
|
|
11750
|
+
const trackedLoadModeRef = (0, import_react40.useRef)(loadMode);
|
|
11751
|
+
const targetKeysRef = (0, import_react40.useRef)([]);
|
|
11752
|
+
const detailTokenRef = (0, import_react40.useRef)("");
|
|
11511
11753
|
const detailReporter = useSceneDetailReporter();
|
|
11512
|
-
const detailReporterRef = (0,
|
|
11754
|
+
const detailReporterRef = (0, import_react40.useRef)(detailReporter);
|
|
11513
11755
|
detailReporterRef.current = detailReporter;
|
|
11514
|
-
(0,
|
|
11756
|
+
(0, import_react40.useEffect)(() => {
|
|
11515
11757
|
currentLevelRef.current = 1;
|
|
11516
11758
|
layerTokenRef.current = "";
|
|
11517
11759
|
visibilityDirtyRef.current = true;
|
|
11518
11760
|
setLayers([]);
|
|
11519
11761
|
}, [manager, multiresToken]);
|
|
11520
|
-
(0,
|
|
11762
|
+
(0, import_react40.useEffect)(() => {
|
|
11521
11763
|
if (loadMode !== "preview") {
|
|
11522
11764
|
return;
|
|
11523
11765
|
}
|
|
@@ -11567,7 +11809,8 @@ function Tile({
|
|
|
11567
11809
|
size.height,
|
|
11568
11810
|
pixelRatio,
|
|
11569
11811
|
camera.fov,
|
|
11570
|
-
currentLevelRef.current
|
|
11812
|
+
currentLevelRef.current,
|
|
11813
|
+
size.width
|
|
11571
11814
|
);
|
|
11572
11815
|
if (targetLevel !== currentLevelRef.current) {
|
|
11573
11816
|
currentLevelRef.current = targetLevel;
|
|
@@ -11693,9 +11936,9 @@ function SnapshotCapture({
|
|
|
11693
11936
|
onCaptured
|
|
11694
11937
|
}) {
|
|
11695
11938
|
const { camera, gl, scene, size } = (0, import_fiber18.useThree)();
|
|
11696
|
-
const capturedRequestRef = (0,
|
|
11697
|
-
const renderTargetRef = (0,
|
|
11698
|
-
(0,
|
|
11939
|
+
const capturedRequestRef = (0, import_react41.useRef)(0);
|
|
11940
|
+
const renderTargetRef = (0, import_react41.useRef)(null);
|
|
11941
|
+
(0, import_react41.useEffect)(
|
|
11699
11942
|
() => () => {
|
|
11700
11943
|
renderTargetRef.current?.dispose();
|
|
11701
11944
|
renderTargetRef.current = null;
|
|
@@ -11753,43 +11996,43 @@ function ScenesController({
|
|
|
11753
11996
|
transitionWaitForDetailMs,
|
|
11754
11997
|
phaseRef: externalPhaseRef
|
|
11755
11998
|
}) {
|
|
11756
|
-
const controlsRef = (0,
|
|
11999
|
+
const controlsRef = (0, import_react41.useContext)(PanoramaViewContext);
|
|
11757
12000
|
const manager = useSharedTileTextureManager();
|
|
11758
|
-
const transition = (0,
|
|
12001
|
+
const transition = (0, import_react41.useMemo)(
|
|
11759
12002
|
() => resolveTransition(transitionInput),
|
|
11760
12003
|
[transitionInput]
|
|
11761
12004
|
);
|
|
11762
|
-
const sceneMap = (0,
|
|
12005
|
+
const sceneMap = (0, import_react41.useMemo)(
|
|
11763
12006
|
() => new Map(scenes.map((scene) => [scene.id, scene])),
|
|
11764
12007
|
[scenes]
|
|
11765
12008
|
);
|
|
11766
12009
|
const initialScene = sceneMap.get(activeSceneId) ?? null;
|
|
11767
|
-
const [slots, setSlots] = (0,
|
|
12010
|
+
const [slots, setSlots] = (0, import_react41.useState)([
|
|
11768
12011
|
initialScene,
|
|
11769
12012
|
null
|
|
11770
12013
|
]);
|
|
11771
|
-
const [activeSlot, setActiveSlot] = (0,
|
|
11772
|
-
const [liveSlot, setLiveSlot] = (0,
|
|
11773
|
-
const [pendingSlot, setPendingSlot] = (0,
|
|
11774
|
-
const [phase, setPhase] = (0,
|
|
11775
|
-
const [captureRequestId, setCaptureRequestId] = (0,
|
|
11776
|
-
const [transitionRunId, setTransitionRunId] = (0,
|
|
11777
|
-
const [snapshot, setSnapshot] = (0,
|
|
11778
|
-
const [recoveryKey, setRecoveryKey] = (0,
|
|
11779
|
-
const requestedSceneIdRef = (0,
|
|
11780
|
-
const captureReasonRef = (0,
|
|
11781
|
-
const interactionReleaseRef = (0,
|
|
11782
|
-
const slotsRef = (0,
|
|
11783
|
-
const phaseRef = (0,
|
|
11784
|
-
const liveSlotRef = (0,
|
|
11785
|
-
const transitionFromRef = (0,
|
|
11786
|
-
const readySceneRef = (0,
|
|
11787
|
-
const waitRef = (0,
|
|
11788
|
-
const waitTimerRef = (0,
|
|
11789
|
-
const detailGenerationRef = (0,
|
|
11790
|
-
const [detailGeneration, setDetailGeneration] = (0,
|
|
11791
|
-
const mountedRef = (0,
|
|
11792
|
-
const waitForDetailMsRef = (0,
|
|
12014
|
+
const [activeSlot, setActiveSlot] = (0, import_react41.useState)(0);
|
|
12015
|
+
const [liveSlot, setLiveSlot] = (0, import_react41.useState)(0);
|
|
12016
|
+
const [pendingSlot, setPendingSlot] = (0, import_react41.useState)(null);
|
|
12017
|
+
const [phase, setPhase] = (0, import_react41.useState)(initialScene ? "idle" : "preloading");
|
|
12018
|
+
const [captureRequestId, setCaptureRequestId] = (0, import_react41.useState)(0);
|
|
12019
|
+
const [transitionRunId, setTransitionRunId] = (0, import_react41.useState)(0);
|
|
12020
|
+
const [snapshot, setSnapshot] = (0, import_react41.useState)(null);
|
|
12021
|
+
const [recoveryKey, setRecoveryKey] = (0, import_react41.useState)(0);
|
|
12022
|
+
const requestedSceneIdRef = (0, import_react41.useRef)(activeSceneId);
|
|
12023
|
+
const captureReasonRef = (0, import_react41.useRef)("start");
|
|
12024
|
+
const interactionReleaseRef = (0, import_react41.useRef)(null);
|
|
12025
|
+
const slotsRef = (0, import_react41.useRef)(slots);
|
|
12026
|
+
const phaseRef = (0, import_react41.useRef)(phase);
|
|
12027
|
+
const liveSlotRef = (0, import_react41.useRef)(liveSlot);
|
|
12028
|
+
const transitionFromRef = (0, import_react41.useRef)(initialScene);
|
|
12029
|
+
const readySceneRef = (0, import_react41.useRef)(null);
|
|
12030
|
+
const waitRef = (0, import_react41.useRef)(null);
|
|
12031
|
+
const waitTimerRef = (0, import_react41.useRef)(null);
|
|
12032
|
+
const detailGenerationRef = (0, import_react41.useRef)(0);
|
|
12033
|
+
const [detailGeneration, setDetailGeneration] = (0, import_react41.useState)(0);
|
|
12034
|
+
const mountedRef = (0, import_react41.useRef)(true);
|
|
12035
|
+
const waitForDetailMsRef = (0, import_react41.useRef)(0);
|
|
11793
12036
|
waitForDetailMsRef.current = normalizeTransitionWaitMs(transitionWaitForDetailMs);
|
|
11794
12037
|
slotsRef.current = slots;
|
|
11795
12038
|
phaseRef.current = phase;
|
|
@@ -11797,21 +12040,21 @@ function ScenesController({
|
|
|
11797
12040
|
externalPhaseRef.current = phase;
|
|
11798
12041
|
}
|
|
11799
12042
|
liveSlotRef.current = liveSlot;
|
|
11800
|
-
(0,
|
|
12043
|
+
(0, import_react41.useEffect)(() => {
|
|
11801
12044
|
const ready = readySceneRef.current;
|
|
11802
12045
|
if (ready) controlsRef?.current?.setSceneViewLimits(sceneMap.get(ready.id)?.viewLimits);
|
|
11803
12046
|
}, [controlsRef, sceneMap]);
|
|
11804
|
-
(0,
|
|
12047
|
+
(0, import_react41.useEffect)(() => () => {
|
|
11805
12048
|
controlsRef?.current?.setSceneViewLimits(void 0);
|
|
11806
12049
|
}, [controlsRef]);
|
|
11807
|
-
const releaseInteraction = (0,
|
|
12050
|
+
const releaseInteraction = (0, import_react41.useCallback)(() => {
|
|
11808
12051
|
interactionReleaseRef.current?.();
|
|
11809
12052
|
interactionReleaseRef.current = null;
|
|
11810
12053
|
}, []);
|
|
11811
|
-
const reportError = (0,
|
|
12054
|
+
const reportError = (0, import_react41.useCallback)((sceneId, error) => {
|
|
11812
12055
|
onTransitionError?.({ sceneId, error });
|
|
11813
12056
|
}, [onTransitionError]);
|
|
11814
|
-
const clearDetailWait = (0,
|
|
12057
|
+
const clearDetailWait = (0, import_react41.useCallback)((bumpGeneration) => {
|
|
11815
12058
|
if (waitTimerRef.current !== null) {
|
|
11816
12059
|
clearTimeout(waitTimerRef.current);
|
|
11817
12060
|
waitTimerRef.current = null;
|
|
@@ -11832,14 +12075,14 @@ function ScenesController({
|
|
|
11832
12075
|
detailGenerationRef.current = nextGeneration;
|
|
11833
12076
|
setDetailGeneration(nextGeneration);
|
|
11834
12077
|
}, []);
|
|
11835
|
-
(0,
|
|
12078
|
+
(0, import_react41.useEffect)(() => {
|
|
11836
12079
|
mountedRef.current = true;
|
|
11837
12080
|
return () => {
|
|
11838
12081
|
mountedRef.current = false;
|
|
11839
12082
|
clearDetailWait(false);
|
|
11840
12083
|
};
|
|
11841
12084
|
}, [clearDetailWait]);
|
|
11842
|
-
const startPreload = (0,
|
|
12085
|
+
const startPreload = (0, import_react41.useCallback)((scene) => {
|
|
11843
12086
|
clearDetailWait(true);
|
|
11844
12087
|
const nextSlot = 1 - liveSlotRef.current;
|
|
11845
12088
|
requestedSceneIdRef.current = scene.id;
|
|
@@ -11851,7 +12094,7 @@ function ScenesController({
|
|
|
11851
12094
|
setPendingSlot(nextSlot);
|
|
11852
12095
|
setPhase("preloading");
|
|
11853
12096
|
}, [clearDetailWait]);
|
|
11854
|
-
(0,
|
|
12097
|
+
(0, import_react41.useEffect)(() => {
|
|
11855
12098
|
const requested = sceneMap.get(activeSceneId);
|
|
11856
12099
|
if (!requested) {
|
|
11857
12100
|
reportError(activeSceneId, new Error(`Unknown panorama scene: ${activeSceneId}`));
|
|
@@ -11877,13 +12120,13 @@ function ScenesController({
|
|
|
11877
12120
|
}
|
|
11878
12121
|
startPreload(requested);
|
|
11879
12122
|
}, [activeSceneId, clearDetailWait, pendingSlot, reportError, sceneMap, startPreload]);
|
|
11880
|
-
const notifySceneReady = (0,
|
|
12123
|
+
const notifySceneReady = (0, import_react41.useCallback)((scene) => {
|
|
11881
12124
|
if (!scene || readySceneRef.current === scene) return;
|
|
11882
12125
|
readySceneRef.current = scene;
|
|
11883
12126
|
controlsRef?.current?.setSceneViewLimits(sceneMap.get(scene.id)?.viewLimits);
|
|
11884
12127
|
onSceneReady?.(scene.id);
|
|
11885
12128
|
}, [controlsRef, onSceneReady, sceneMap]);
|
|
11886
|
-
const handleReady = (0,
|
|
12129
|
+
const handleReady = (0, import_react41.useCallback)((slot) => {
|
|
11887
12130
|
if (slot === liveSlotRef.current && pendingSlot === null && phaseRef.current === "idle") {
|
|
11888
12131
|
notifySceneReady(slotsRef.current[slot]);
|
|
11889
12132
|
return;
|
|
@@ -11919,7 +12162,7 @@ function ScenesController({
|
|
|
11919
12162
|
setPhase("capturing");
|
|
11920
12163
|
setCaptureRequestId((current) => current + 1);
|
|
11921
12164
|
}, [controlsRef, notifySceneReady, onTransitionEnd, pendingSlot, transition.preset]);
|
|
11922
|
-
const finishTransition = (0,
|
|
12165
|
+
const finishTransition = (0, import_react41.useCallback)(() => {
|
|
11923
12166
|
const nextSlot = pendingSlot;
|
|
11924
12167
|
const previousScene = transitionFromRef.current;
|
|
11925
12168
|
const nextScene = nextSlot === null ? null : slotsRef.current[nextSlot];
|
|
@@ -11944,11 +12187,11 @@ function ScenesController({
|
|
|
11944
12187
|
});
|
|
11945
12188
|
}
|
|
11946
12189
|
}, [onTransitionEnd, pendingSlot, releaseInteraction, snapshot, transition.preset]);
|
|
11947
|
-
const finishTransitionRef = (0,
|
|
12190
|
+
const finishTransitionRef = (0, import_react41.useRef)(finishTransition);
|
|
11948
12191
|
finishTransitionRef.current = finishTransition;
|
|
11949
|
-
const transitionRef = (0,
|
|
12192
|
+
const transitionRef = (0, import_react41.useRef)(transition);
|
|
11950
12193
|
transitionRef.current = transition;
|
|
11951
|
-
const consumeDetailSignal = (0,
|
|
12194
|
+
const consumeDetailSignal = (0, import_react41.useCallback)((signal) => {
|
|
11952
12195
|
const decision = acceptDetailWait(waitRef.current, signal);
|
|
11953
12196
|
waitRef.current = decision.wait;
|
|
11954
12197
|
if (!decision.start) {
|
|
@@ -11968,7 +12211,7 @@ function ScenesController({
|
|
|
11968
12211
|
setPhase("transitioning");
|
|
11969
12212
|
setTransitionRunId((current) => current + 1);
|
|
11970
12213
|
}, []);
|
|
11971
|
-
const handleCaptured = (0,
|
|
12214
|
+
const handleCaptured = (0, import_react41.useCallback)((nextSnapshot) => {
|
|
11972
12215
|
if (captureReasonRef.current === "interrupt") {
|
|
11973
12216
|
setSnapshot((current) => {
|
|
11974
12217
|
current?.dispose();
|
|
@@ -12066,15 +12309,15 @@ function ScenesController({
|
|
|
12066
12309
|
startPreload,
|
|
12067
12310
|
transition.preset
|
|
12068
12311
|
]);
|
|
12069
|
-
const snapshotRef = (0,
|
|
12312
|
+
const snapshotRef = (0, import_react41.useRef)(snapshot);
|
|
12070
12313
|
snapshotRef.current = snapshot;
|
|
12071
|
-
(0,
|
|
12314
|
+
(0, import_react41.useEffect)(() => () => {
|
|
12072
12315
|
releaseInteraction();
|
|
12073
12316
|
snapshotRef.current?.dispose();
|
|
12074
12317
|
snapshotRef.current = null;
|
|
12075
12318
|
}, [releaseInteraction]);
|
|
12076
12319
|
const { gl } = (0, import_fiber18.useThree)();
|
|
12077
|
-
(0,
|
|
12320
|
+
(0, import_react41.useEffect)(() => {
|
|
12078
12321
|
const canvas = gl.domElement;
|
|
12079
12322
|
const onContextLost = (event) => {
|
|
12080
12323
|
event.preventDefault();
|
|
@@ -12102,7 +12345,7 @@ function ScenesController({
|
|
|
12102
12345
|
const snapshotVisible = snapshot !== null && (phase === "transitioning" || phase === "recapturing" || phase === "preloading");
|
|
12103
12346
|
const slotSceneKey = `${slots[0]?.id ?? ""}
|
|
12104
12347
|
${slots[1]?.id ?? ""}`;
|
|
12105
|
-
const detailReporters = (0,
|
|
12348
|
+
const detailReporters = (0, import_react41.useMemo)(() => {
|
|
12106
12349
|
const [firstSceneId = "", secondSceneId = ""] = slotSceneKey.split("\n");
|
|
12107
12350
|
const sceneIds = [firstSceneId, secondSceneId];
|
|
12108
12351
|
return sceneIds.map((sceneId) => ({
|
|
@@ -12119,7 +12362,7 @@ ${slots[1]?.id ?? ""}`;
|
|
|
12119
12362
|
}
|
|
12120
12363
|
}));
|
|
12121
12364
|
}, [consumeDetailSignal, detailGeneration, slotSceneKey]);
|
|
12122
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
12365
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react41.Fragment, { children: [
|
|
12123
12366
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12124
12367
|
SnapshotCapture,
|
|
12125
12368
|
{
|
|
@@ -12178,11 +12421,11 @@ function Scenes({
|
|
|
12178
12421
|
...rest
|
|
12179
12422
|
}) {
|
|
12180
12423
|
const isControlled = controlledId !== void 0;
|
|
12181
|
-
const [internalId, setInternalId] = (0,
|
|
12424
|
+
const [internalId, setInternalId] = (0, import_react41.useState)(
|
|
12182
12425
|
() => controlledId ?? defaultActiveSceneId ?? scenes[0]?.id ?? ""
|
|
12183
12426
|
);
|
|
12184
12427
|
const resolvedId = isControlled ? controlledId : internalId;
|
|
12185
|
-
const requestSceneChange = (0,
|
|
12428
|
+
const requestSceneChange = (0, import_react41.useCallback)(
|
|
12186
12429
|
(id) => {
|
|
12187
12430
|
if (isControlled) {
|
|
12188
12431
|
onActiveSceneIdChange?.(id);
|
|
@@ -12192,13 +12435,13 @@ function Scenes({
|
|
|
12192
12435
|
},
|
|
12193
12436
|
[isControlled, onActiveSceneIdChange]
|
|
12194
12437
|
);
|
|
12195
|
-
const scenesRef = (0,
|
|
12438
|
+
const scenesRef = (0, import_react41.useRef)(scenes);
|
|
12196
12439
|
scenesRef.current = scenes;
|
|
12197
|
-
const resolvedIdRef = (0,
|
|
12440
|
+
const resolvedIdRef = (0, import_react41.useRef)(resolvedId);
|
|
12198
12441
|
resolvedIdRef.current = resolvedId;
|
|
12199
|
-
const host = (0,
|
|
12200
|
-
const phaseRef = (0,
|
|
12201
|
-
(0,
|
|
12442
|
+
const host = (0, import_react41.useContext)(ScenesHostContext);
|
|
12443
|
+
const phaseRef = (0, import_react41.useRef)("idle");
|
|
12444
|
+
(0, import_react41.useEffect)(() => {
|
|
12202
12445
|
if (!host) {
|
|
12203
12446
|
return;
|
|
12204
12447
|
}
|
|
@@ -12268,12 +12511,12 @@ function Scenes({
|
|
|
12268
12511
|
|
|
12269
12512
|
// src/hotspot/image-hotspot.tsx
|
|
12270
12513
|
var import_fiber22 = require("@react-three/fiber");
|
|
12271
|
-
var
|
|
12514
|
+
var import_react46 = require("react");
|
|
12272
12515
|
var import_three27 = require("three");
|
|
12273
12516
|
|
|
12274
12517
|
// src/hotspot/hotspot-anchor.tsx
|
|
12275
12518
|
var import_fiber21 = require("@react-three/fiber");
|
|
12276
|
-
var
|
|
12519
|
+
var import_react45 = require("react");
|
|
12277
12520
|
var import_three25 = require("three");
|
|
12278
12521
|
|
|
12279
12522
|
// src/hotspot/drag-session.ts
|
|
@@ -12365,18 +12608,18 @@ function suppressFollowingClick(target) {
|
|
|
12365
12608
|
}
|
|
12366
12609
|
|
|
12367
12610
|
// src/hotspot/hotspot-tooltip.tsx
|
|
12368
|
-
var
|
|
12611
|
+
var import_react43 = require("react");
|
|
12369
12612
|
|
|
12370
12613
|
// src/webvr/stereo-html.tsx
|
|
12371
12614
|
var import_fiber19 = require("@react-three/fiber");
|
|
12372
|
-
var
|
|
12615
|
+
var import_react42 = require("react");
|
|
12373
12616
|
var import_client = require("react-dom/client");
|
|
12374
12617
|
var import_three22 = require("three");
|
|
12375
12618
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
12376
12619
|
function useFallbackStereoView() {
|
|
12377
|
-
const runtime = (0,
|
|
12620
|
+
const runtime = (0, import_react42.useContext)(WebVRRuntimeContext);
|
|
12378
12621
|
const host = runtime?.host ?? null;
|
|
12379
|
-
const fallback = (0,
|
|
12622
|
+
const fallback = (0, import_react42.useSyncExternalStore)(
|
|
12380
12623
|
(onStoreChange) => host ? subscribeWebVRHost(host, onStoreChange) : () => void 0,
|
|
12381
12624
|
() => isFallbackStereoMode(host?.snapshot.mode ?? null),
|
|
12382
12625
|
() => false
|
|
@@ -12392,9 +12635,9 @@ function ProjectedHtml({
|
|
|
12392
12635
|
eye
|
|
12393
12636
|
}) {
|
|
12394
12637
|
const { camera, gl, events, size } = (0, import_fiber19.useThree)();
|
|
12395
|
-
const group = (0,
|
|
12396
|
-
const overlay = (0,
|
|
12397
|
-
const scratch = (0,
|
|
12638
|
+
const group = (0, import_react42.useRef)(null);
|
|
12639
|
+
const overlay = (0, import_react42.useRef)(null);
|
|
12640
|
+
const scratch = (0, import_react42.useRef)(new import_three22.Vector3());
|
|
12398
12641
|
const target = events.connected || gl.domElement.parentElement;
|
|
12399
12642
|
const updatePosition = () => {
|
|
12400
12643
|
const anchor = group.current;
|
|
@@ -12422,7 +12665,7 @@ function ProjectedHtml({
|
|
|
12422
12665
|
)
|
|
12423
12666
|
);
|
|
12424
12667
|
};
|
|
12425
|
-
(0,
|
|
12668
|
+
(0, import_react42.useLayoutEffect)(() => {
|
|
12426
12669
|
if (!target) return;
|
|
12427
12670
|
const element = document.createElement("div");
|
|
12428
12671
|
Object.assign(element.style, {
|
|
@@ -12440,7 +12683,7 @@ function ProjectedHtml({
|
|
|
12440
12683
|
queueMicrotask(() => root.unmount());
|
|
12441
12684
|
};
|
|
12442
12685
|
}, [target]);
|
|
12443
|
-
(0,
|
|
12686
|
+
(0, import_react42.useLayoutEffect)(() => {
|
|
12444
12687
|
overlay.current?.root.render(
|
|
12445
12688
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
12446
12689
|
"div",
|
|
@@ -12457,9 +12700,9 @@ function ProjectedHtml({
|
|
|
12457
12700
|
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("group", { ref: group });
|
|
12458
12701
|
}
|
|
12459
12702
|
function PanoHtml(props) {
|
|
12460
|
-
const runtime = (0,
|
|
12703
|
+
const runtime = (0, import_react42.useContext)(WebVRRuntimeContext);
|
|
12461
12704
|
const host = runtime?.host ?? null;
|
|
12462
|
-
const mode = (0,
|
|
12705
|
+
const mode = (0, import_react42.useSyncExternalStore)(
|
|
12463
12706
|
(onStoreChange) => host ? subscribeWebVRHost(host, onStoreChange) : () => void 0,
|
|
12464
12707
|
() => host?.snapshot.mode ?? null,
|
|
12465
12708
|
() => null
|
|
@@ -12548,16 +12791,16 @@ function HotspotTooltip({
|
|
|
12548
12791
|
offset = DEFAULT_HOTSPOT_TOOLTIP_OFFSET,
|
|
12549
12792
|
appearance
|
|
12550
12793
|
}) {
|
|
12551
|
-
const [imageFailed, setImageFailed] = (0,
|
|
12552
|
-
(0,
|
|
12794
|
+
const [imageFailed, setImageFailed] = (0, import_react43.useState)(false);
|
|
12795
|
+
(0, import_react43.useEffect)(() => {
|
|
12553
12796
|
setImageFailed(false);
|
|
12554
12797
|
}, [content.image]);
|
|
12555
12798
|
const showImage = Boolean(content.image) && !imageFailed;
|
|
12556
|
-
const resolvedAppearance = (0,
|
|
12799
|
+
const resolvedAppearance = (0, import_react43.useMemo)(
|
|
12557
12800
|
() => resolveHotspotTooltipAppearance(appearance),
|
|
12558
12801
|
[appearance]
|
|
12559
12802
|
);
|
|
12560
|
-
const bubbleStyle = (0,
|
|
12803
|
+
const bubbleStyle = (0, import_react43.useMemo)(
|
|
12561
12804
|
() => ({
|
|
12562
12805
|
background: resolvedAppearance.background,
|
|
12563
12806
|
border: resolvedAppearance.border,
|
|
@@ -12653,7 +12896,7 @@ function selectionFrameScale(worldScaleX, worldScaleY, cameraSpaceDepth, fovDegr
|
|
|
12653
12896
|
// src/hotspot/hotspot-stroke-line.tsx
|
|
12654
12897
|
var import_drei = require("@react-three/drei");
|
|
12655
12898
|
var import_fiber20 = require("@react-three/fiber");
|
|
12656
|
-
var
|
|
12899
|
+
var import_react44 = require("react");
|
|
12657
12900
|
var import_three24 = require("three");
|
|
12658
12901
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
12659
12902
|
var LINE_WORLD_POSITION = new import_three24.Vector3();
|
|
@@ -12686,10 +12929,10 @@ function HotspotStrokeLine({
|
|
|
12686
12929
|
dashSize,
|
|
12687
12930
|
gapSize
|
|
12688
12931
|
}) {
|
|
12689
|
-
const lineRef = (0,
|
|
12932
|
+
const lineRef = (0, import_react44.useRef)(null);
|
|
12690
12933
|
const { camera, size } = (0, import_fiber20.useThree)();
|
|
12691
12934
|
const dash = resolveDash(dashSize, gapSize);
|
|
12692
|
-
(0,
|
|
12935
|
+
(0, import_react44.useLayoutEffect)(() => {
|
|
12693
12936
|
if (!dash.dashed) {
|
|
12694
12937
|
return;
|
|
12695
12938
|
}
|
|
@@ -13099,27 +13342,27 @@ function HotspotAnchor({
|
|
|
13099
13342
|
onPositionChange,
|
|
13100
13343
|
onDragEnd
|
|
13101
13344
|
}) {
|
|
13102
|
-
const controlsRef = (0,
|
|
13103
|
-
const hotspotTargetRegistry = (0,
|
|
13104
|
-
const eventBus = (0,
|
|
13345
|
+
const controlsRef = (0, import_react45.useContext)(PanoramaViewContext);
|
|
13346
|
+
const hotspotTargetRegistry = (0, import_react45.useContext)(HotspotTargetRegistryContext);
|
|
13347
|
+
const eventBus = (0, import_react45.useContext)(PanoEventBusContext);
|
|
13105
13348
|
const cursorApi = usePanoCursor();
|
|
13106
13349
|
const { camera, gl, size } = (0, import_fiber21.useThree)();
|
|
13107
|
-
const groupRef = (0,
|
|
13108
|
-
const selectionFrameRef = (0,
|
|
13109
|
-
const tooltipAnchorRef = (0,
|
|
13110
|
-
const dragStateRef = (0,
|
|
13111
|
-
const updateDragRef = (0,
|
|
13112
|
-
const endDragRef = (0,
|
|
13113
|
-
const suppressNextClickRef = (0,
|
|
13114
|
-
const [hovered, setHovered] = (0,
|
|
13115
|
-
const [dragging, setDragging] = (0,
|
|
13116
|
-
const [pinned, setPinned] = (0,
|
|
13117
|
-
const tooltipContent = (0,
|
|
13350
|
+
const groupRef = (0, import_react45.useRef)(null);
|
|
13351
|
+
const selectionFrameRef = (0, import_react45.useRef)(null);
|
|
13352
|
+
const tooltipAnchorRef = (0, import_react45.useRef)(null);
|
|
13353
|
+
const dragStateRef = (0, import_react45.useRef)(null);
|
|
13354
|
+
const updateDragRef = (0, import_react45.useRef)(() => void 0);
|
|
13355
|
+
const endDragRef = (0, import_react45.useRef)(() => void 0);
|
|
13356
|
+
const suppressNextClickRef = (0, import_react45.useRef)(false);
|
|
13357
|
+
const [hovered, setHovered] = (0, import_react45.useState)(false);
|
|
13358
|
+
const [dragging, setDragging] = (0, import_react45.useState)(false);
|
|
13359
|
+
const [pinned, setPinned] = (0, import_react45.useState)(false);
|
|
13360
|
+
const tooltipContent = (0, import_react45.useMemo)(
|
|
13118
13361
|
() => resolveHotspotTooltipContent(tooltip),
|
|
13119
13362
|
[tooltip]
|
|
13120
13363
|
);
|
|
13121
13364
|
const normalizedPosition = normalizePanoPosition(position);
|
|
13122
|
-
(0,
|
|
13365
|
+
(0, import_react45.useEffect)(() => {
|
|
13123
13366
|
if (!hotspotTargetRegistry) {
|
|
13124
13367
|
return;
|
|
13125
13368
|
}
|
|
@@ -13136,24 +13379,24 @@ function HotspotAnchor({
|
|
|
13136
13379
|
scaledWidth,
|
|
13137
13380
|
scaledHeight
|
|
13138
13381
|
);
|
|
13139
|
-
const worldPosition = (0,
|
|
13382
|
+
const worldPosition = (0, import_react45.useMemo)(
|
|
13140
13383
|
() => panoPositionToVector3(normalizedPosition, resolvedDistance),
|
|
13141
13384
|
[normalizedPosition.pitch, normalizedPosition.yaw, resolvedDistance]
|
|
13142
13385
|
);
|
|
13143
|
-
const surfaceQuaternion3 = (0,
|
|
13386
|
+
const surfaceQuaternion3 = (0, import_react45.useMemo)(
|
|
13144
13387
|
() => createSurfaceQuaternion(normalizedPosition),
|
|
13145
13388
|
[normalizedPosition.pitch, normalizedPosition.yaw]
|
|
13146
13389
|
);
|
|
13147
13390
|
const worldWidth = angularSizeToWorldSize(scaledWidth, resolvedDistance);
|
|
13148
13391
|
const worldHeight = angularSizeToWorldSize(scaledHeight, resolvedDistance);
|
|
13149
|
-
const focusGeometry = (0,
|
|
13392
|
+
const focusGeometry = (0, import_react45.useMemo)(() => {
|
|
13150
13393
|
const planeGeometry = new import_three25.PlaneGeometry(1, 1);
|
|
13151
13394
|
const geometry = new import_three25.EdgesGeometry(planeGeometry);
|
|
13152
13395
|
planeGeometry.dispose();
|
|
13153
13396
|
return geometry;
|
|
13154
13397
|
}, []);
|
|
13155
|
-
const eventHovered = (0,
|
|
13156
|
-
(0,
|
|
13398
|
+
const eventHovered = (0, import_react45.useRef)(false);
|
|
13399
|
+
(0, import_react45.useEffect)(() => {
|
|
13157
13400
|
if (!visible || !interactive || pointerEvents === "none") eventHovered.current = false;
|
|
13158
13401
|
}, [visible, interactive, pointerEvents]);
|
|
13159
13402
|
const acceptsPointer = acceptsHotspotPointerEvents(interactive, pointerEvents);
|
|
@@ -13177,7 +13420,7 @@ function HotspotAnchor({
|
|
|
13177
13420
|
});
|
|
13178
13421
|
const tooltipOpen = visible && tooltipContent !== null && isTooltipOpen(tooltipTrigger, hovered, focused, pinned);
|
|
13179
13422
|
const cursorClaimId = hotspotCursorClaimId(id);
|
|
13180
|
-
(0,
|
|
13423
|
+
(0, import_react45.useEffect)(
|
|
13181
13424
|
() => () => {
|
|
13182
13425
|
const dragState = dragStateRef.current;
|
|
13183
13426
|
dragState?.stopTracking();
|
|
@@ -13186,7 +13429,7 @@ function HotspotAnchor({
|
|
|
13186
13429
|
},
|
|
13187
13430
|
[]
|
|
13188
13431
|
);
|
|
13189
|
-
(0,
|
|
13432
|
+
(0, import_react45.useEffect)(() => {
|
|
13190
13433
|
if (!cursorApi) {
|
|
13191
13434
|
return;
|
|
13192
13435
|
}
|
|
@@ -13208,14 +13451,14 @@ function HotspotAnchor({
|
|
|
13208
13451
|
hovered,
|
|
13209
13452
|
visible
|
|
13210
13453
|
]);
|
|
13211
|
-
(0,
|
|
13454
|
+
(0, import_react45.useEffect)(
|
|
13212
13455
|
() => () => {
|
|
13213
13456
|
cursorApi?.release(cursorClaimId);
|
|
13214
13457
|
},
|
|
13215
13458
|
[cursorApi, cursorClaimId]
|
|
13216
13459
|
);
|
|
13217
|
-
(0,
|
|
13218
|
-
(0,
|
|
13460
|
+
(0, import_react45.useEffect)(() => () => focusGeometry.dispose(), [focusGeometry]);
|
|
13461
|
+
(0, import_react45.useEffect)(() => {
|
|
13219
13462
|
if (tooltipTrigger !== "click") {
|
|
13220
13463
|
setPinned(false);
|
|
13221
13464
|
return;
|
|
@@ -13224,12 +13467,12 @@ function HotspotAnchor({
|
|
|
13224
13467
|
setPinned(false);
|
|
13225
13468
|
});
|
|
13226
13469
|
}, [eventBus, tooltipTrigger]);
|
|
13227
|
-
(0,
|
|
13470
|
+
(0, import_react45.useEffect)(() => {
|
|
13228
13471
|
if (tooltipTrigger !== "hover") {
|
|
13229
13472
|
setHovered(false);
|
|
13230
13473
|
}
|
|
13231
13474
|
}, [tooltipTrigger]);
|
|
13232
|
-
(0,
|
|
13475
|
+
(0, import_react45.useEffect)(() => {
|
|
13233
13476
|
if (acceptsPointer) {
|
|
13234
13477
|
return;
|
|
13235
13478
|
}
|
|
@@ -13243,7 +13486,7 @@ function HotspotAnchor({
|
|
|
13243
13486
|
dragStateRef.current = null;
|
|
13244
13487
|
setDragging(false);
|
|
13245
13488
|
}, [acceptsPointer]);
|
|
13246
|
-
(0,
|
|
13489
|
+
(0, import_react45.useLayoutEffect)(() => {
|
|
13247
13490
|
const group = groupRef.current;
|
|
13248
13491
|
if (!group) {
|
|
13249
13492
|
return;
|
|
@@ -13664,12 +13907,12 @@ function HotspotPlane({
|
|
|
13664
13907
|
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
13665
13908
|
function useHotspotImageTexture(src, onLoad, onError) {
|
|
13666
13909
|
const gl = (0, import_fiber22.useThree)((state) => state.gl);
|
|
13667
|
-
const [texture, setTexture] = (0,
|
|
13668
|
-
const onLoadRef = (0,
|
|
13669
|
-
const onErrorRef = (0,
|
|
13910
|
+
const [texture, setTexture] = (0, import_react46.useState)(null);
|
|
13911
|
+
const onLoadRef = (0, import_react46.useRef)(onLoad);
|
|
13912
|
+
const onErrorRef = (0, import_react46.useRef)(onError);
|
|
13670
13913
|
onLoadRef.current = onLoad;
|
|
13671
13914
|
onErrorRef.current = onError;
|
|
13672
|
-
(0,
|
|
13915
|
+
(0, import_react46.useEffect)(() => {
|
|
13673
13916
|
let active = true;
|
|
13674
13917
|
setTexture(null);
|
|
13675
13918
|
if (!src) {
|
|
@@ -13707,7 +13950,7 @@ function useHotspotImageTexture(src, onLoad, onError) {
|
|
|
13707
13950
|
active = false;
|
|
13708
13951
|
};
|
|
13709
13952
|
}, [gl, src]);
|
|
13710
|
-
(0,
|
|
13953
|
+
(0, import_react46.useEffect)(
|
|
13711
13954
|
() => () => {
|
|
13712
13955
|
texture?.dispose();
|
|
13713
13956
|
},
|
|
@@ -13729,7 +13972,7 @@ function ImageHotspot({
|
|
|
13729
13972
|
}
|
|
13730
13973
|
|
|
13731
13974
|
// src/hotspot/graphic-hotspot.tsx
|
|
13732
|
-
var
|
|
13975
|
+
var import_react47 = require("react");
|
|
13733
13976
|
var import_three28 = require("three");
|
|
13734
13977
|
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
13735
13978
|
var GRAPHIC_TEXTURE_SIZE = 512;
|
|
@@ -13920,12 +14163,12 @@ function createGraphicTexture(graphic, aspectWidth, aspectHeight) {
|
|
|
13920
14163
|
return texture;
|
|
13921
14164
|
}
|
|
13922
14165
|
function useGraphicTexture(graphic, aspectWidth, aspectHeight, onLoad, onError) {
|
|
13923
|
-
const [texture, setTexture] = (0,
|
|
13924
|
-
const onLoadRef = (0,
|
|
13925
|
-
const onErrorRef = (0,
|
|
14166
|
+
const [texture, setTexture] = (0, import_react47.useState)(null);
|
|
14167
|
+
const onLoadRef = (0, import_react47.useRef)(onLoad);
|
|
14168
|
+
const onErrorRef = (0, import_react47.useRef)(onError);
|
|
13926
14169
|
onLoadRef.current = onLoad;
|
|
13927
14170
|
onErrorRef.current = onError;
|
|
13928
|
-
(0,
|
|
14171
|
+
(0, import_react47.useEffect)(() => {
|
|
13929
14172
|
let nextTexture = null;
|
|
13930
14173
|
try {
|
|
13931
14174
|
nextTexture = createGraphicTexture(graphic, aspectWidth, aspectHeight);
|
|
@@ -13964,7 +14207,7 @@ function GraphicHotspot(props) {
|
|
|
13964
14207
|
|
|
13965
14208
|
// src/hotspot/sequence-hotspot.tsx
|
|
13966
14209
|
var import_fiber23 = require("@react-three/fiber");
|
|
13967
|
-
var
|
|
14210
|
+
var import_react48 = require("react");
|
|
13968
14211
|
var import_three29 = require("three");
|
|
13969
14212
|
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
13970
14213
|
var DEFAULT_SEQUENCE_FPS = 12;
|
|
@@ -13981,12 +14224,12 @@ function useSpriteTexture({
|
|
|
13981
14224
|
onLoadProgress
|
|
13982
14225
|
}) {
|
|
13983
14226
|
const gl = (0, import_fiber23.useThree)((state) => state.gl);
|
|
13984
|
-
const [texture, setTexture] = (0,
|
|
13985
|
-
const onErrorRef = (0,
|
|
13986
|
-
const onLoadProgressRef = (0,
|
|
14227
|
+
const [texture, setTexture] = (0, import_react48.useState)(null);
|
|
14228
|
+
const onErrorRef = (0, import_react48.useRef)(onError);
|
|
14229
|
+
const onLoadProgressRef = (0, import_react48.useRef)(onLoadProgress);
|
|
13987
14230
|
onErrorRef.current = onError;
|
|
13988
14231
|
onLoadProgressRef.current = onLoadProgress;
|
|
13989
|
-
(0,
|
|
14232
|
+
(0, import_react48.useEffect)(() => {
|
|
13990
14233
|
let active = true;
|
|
13991
14234
|
setTexture(null);
|
|
13992
14235
|
if (!src) {
|
|
@@ -14027,7 +14270,7 @@ function useSpriteTexture({
|
|
|
14027
14270
|
active = false;
|
|
14028
14271
|
};
|
|
14029
14272
|
}, [gl, id, src]);
|
|
14030
|
-
(0,
|
|
14273
|
+
(0, import_react48.useEffect)(
|
|
14031
14274
|
() => () => {
|
|
14032
14275
|
texture?.dispose();
|
|
14033
14276
|
},
|
|
@@ -14056,24 +14299,24 @@ function SequenceHotspot({
|
|
|
14056
14299
|
const texture = useSpriteTexture({ id, src, onError, onLoadProgress });
|
|
14057
14300
|
const frameCount = resolveFrameCount(requestedFrameCount);
|
|
14058
14301
|
const safeFps = resolveFps(fps);
|
|
14059
|
-
const [frameIndex, setFrameIndex] = (0,
|
|
14060
|
-
const elapsedRef = (0,
|
|
14061
|
-
const frameIndexRef = (0,
|
|
14062
|
-
const endedRef = (0,
|
|
14063
|
-
const lastPlaybackStateRef = (0,
|
|
14064
|
-
const onFrameChangeRef = (0,
|
|
14065
|
-
const onPlaybackStateChangeRef = (0,
|
|
14066
|
-
const onEndedRef = (0,
|
|
14302
|
+
const [frameIndex, setFrameIndex] = (0, import_react48.useState)(0);
|
|
14303
|
+
const elapsedRef = (0, import_react48.useRef)(0);
|
|
14304
|
+
const frameIndexRef = (0, import_react48.useRef)(0);
|
|
14305
|
+
const endedRef = (0, import_react48.useRef)(false);
|
|
14306
|
+
const lastPlaybackStateRef = (0, import_react48.useRef)(null);
|
|
14307
|
+
const onFrameChangeRef = (0, import_react48.useRef)(onFrameChange);
|
|
14308
|
+
const onPlaybackStateChangeRef = (0, import_react48.useRef)(onPlaybackStateChange);
|
|
14309
|
+
const onEndedRef = (0, import_react48.useRef)(onEnded);
|
|
14067
14310
|
onFrameChangeRef.current = onFrameChange;
|
|
14068
14311
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
14069
14312
|
onEndedRef.current = onEnded;
|
|
14070
|
-
(0,
|
|
14313
|
+
(0, import_react48.useEffect)(() => {
|
|
14071
14314
|
elapsedRef.current = 0;
|
|
14072
14315
|
frameIndexRef.current = 0;
|
|
14073
14316
|
endedRef.current = false;
|
|
14074
14317
|
setFrameIndex(0);
|
|
14075
14318
|
}, [frameCount, frameDirection, src]);
|
|
14076
|
-
(0,
|
|
14319
|
+
(0, import_react48.useEffect)(() => {
|
|
14077
14320
|
if (!texture) {
|
|
14078
14321
|
return;
|
|
14079
14322
|
}
|
|
@@ -14087,13 +14330,13 @@ function SequenceHotspot({
|
|
|
14087
14330
|
);
|
|
14088
14331
|
texture.needsUpdate = true;
|
|
14089
14332
|
}, [frameCount, frameDirection, frameIndex, texture]);
|
|
14090
|
-
(0,
|
|
14333
|
+
(0, import_react48.useEffect)(() => {
|
|
14091
14334
|
if (!texture) {
|
|
14092
14335
|
return;
|
|
14093
14336
|
}
|
|
14094
14337
|
onFrameChangeRef.current?.({ id, index: 0, src });
|
|
14095
14338
|
}, [id, src, texture]);
|
|
14096
|
-
(0,
|
|
14339
|
+
(0, import_react48.useEffect)(() => {
|
|
14097
14340
|
if (!texture) {
|
|
14098
14341
|
return;
|
|
14099
14342
|
}
|
|
@@ -14147,7 +14390,7 @@ function SequenceHotspot({
|
|
|
14147
14390
|
|
|
14148
14391
|
// src/hotspot/video-hotspot.tsx
|
|
14149
14392
|
var import_fiber24 = require("@react-three/fiber");
|
|
14150
|
-
var
|
|
14393
|
+
var import_react49 = require("react");
|
|
14151
14394
|
var import_three30 = require("three");
|
|
14152
14395
|
|
|
14153
14396
|
// src/video/inline-playback.ts
|
|
@@ -14210,10 +14453,10 @@ function clampVolume2(volume) {
|
|
|
14210
14453
|
}
|
|
14211
14454
|
function usePosterTexture(id, poster, onError) {
|
|
14212
14455
|
const gl = (0, import_fiber24.useThree)((state) => state.gl);
|
|
14213
|
-
const [texture, setTexture] = (0,
|
|
14214
|
-
const onErrorRef = (0,
|
|
14456
|
+
const [texture, setTexture] = (0, import_react49.useState)(null);
|
|
14457
|
+
const onErrorRef = (0, import_react49.useRef)(onError);
|
|
14215
14458
|
onErrorRef.current = onError;
|
|
14216
|
-
(0,
|
|
14459
|
+
(0, import_react49.useEffect)(() => {
|
|
14217
14460
|
let active = true;
|
|
14218
14461
|
setTexture(null);
|
|
14219
14462
|
if (!poster) {
|
|
@@ -14250,7 +14493,7 @@ function usePosterTexture(id, poster, onError) {
|
|
|
14250
14493
|
active = false;
|
|
14251
14494
|
};
|
|
14252
14495
|
}, [gl, id, poster]);
|
|
14253
|
-
(0,
|
|
14496
|
+
(0, import_react49.useEffect)(
|
|
14254
14497
|
() => () => {
|
|
14255
14498
|
texture?.dispose();
|
|
14256
14499
|
},
|
|
@@ -14269,14 +14512,14 @@ function useVideoResource({
|
|
|
14269
14512
|
src
|
|
14270
14513
|
}) {
|
|
14271
14514
|
const gl = (0, import_fiber24.useThree)((state) => state.gl);
|
|
14272
|
-
const [resource, setResource] = (0,
|
|
14273
|
-
const onEndedRef = (0,
|
|
14274
|
-
const onErrorRef = (0,
|
|
14275
|
-
const onPlaybackStateChangeRef = (0,
|
|
14515
|
+
const [resource, setResource] = (0, import_react49.useState)(null);
|
|
14516
|
+
const onEndedRef = (0, import_react49.useRef)(onEnded);
|
|
14517
|
+
const onErrorRef = (0, import_react49.useRef)(onError);
|
|
14518
|
+
const onPlaybackStateChangeRef = (0, import_react49.useRef)(onPlaybackStateChange);
|
|
14276
14519
|
onEndedRef.current = onEnded;
|
|
14277
14520
|
onErrorRef.current = onError;
|
|
14278
14521
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
14279
|
-
(0,
|
|
14522
|
+
(0, import_react49.useEffect)(() => {
|
|
14280
14523
|
if (!src) {
|
|
14281
14524
|
setResource(null);
|
|
14282
14525
|
return;
|
|
@@ -14346,7 +14589,7 @@ function useVideoResource({
|
|
|
14346
14589
|
texture.dispose();
|
|
14347
14590
|
};
|
|
14348
14591
|
}, [crossOrigin, gl, id, playsInline, poster, src]);
|
|
14349
|
-
(0,
|
|
14592
|
+
(0, import_react49.useLayoutEffect)(() => {
|
|
14350
14593
|
if (!resource) {
|
|
14351
14594
|
return;
|
|
14352
14595
|
}
|
|
@@ -14389,11 +14632,11 @@ function VideoHotspot({
|
|
|
14389
14632
|
src
|
|
14390
14633
|
});
|
|
14391
14634
|
const posterTexture = usePosterTexture(id, poster, onError);
|
|
14392
|
-
const onPlaybackErrorRef = (0,
|
|
14393
|
-
const onPlaybackStateChangeRef = (0,
|
|
14635
|
+
const onPlaybackErrorRef = (0, import_react49.useRef)(onPlaybackError);
|
|
14636
|
+
const onPlaybackStateChangeRef = (0, import_react49.useRef)(onPlaybackStateChange);
|
|
14394
14637
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
14395
14638
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
14396
|
-
(0,
|
|
14639
|
+
(0, import_react49.useLayoutEffect)(() => {
|
|
14397
14640
|
if (!resource) {
|
|
14398
14641
|
return;
|
|
14399
14642
|
}
|
|
@@ -14403,7 +14646,7 @@ function VideoHotspot({
|
|
|
14403
14646
|
applyInlineVideoPlayback(resource.video, playsInline);
|
|
14404
14647
|
resource.video.preload = preload;
|
|
14405
14648
|
}, [loop, muted, playsInline, preload, resource, volume]);
|
|
14406
|
-
(0,
|
|
14649
|
+
(0, import_react49.useEffect)(() => {
|
|
14407
14650
|
if (!resource) {
|
|
14408
14651
|
return;
|
|
14409
14652
|
}
|
|
@@ -14431,7 +14674,7 @@ function VideoHotspot({
|
|
|
14431
14674
|
|
|
14432
14675
|
// src/hotspot/audio-hotspot.tsx
|
|
14433
14676
|
var import_fiber25 = require("@react-three/fiber");
|
|
14434
|
-
var
|
|
14677
|
+
var import_react50 = require("react");
|
|
14435
14678
|
var import_three32 = require("three");
|
|
14436
14679
|
|
|
14437
14680
|
// src/hotspot/audio-spatial.ts
|
|
@@ -14543,8 +14786,8 @@ function createSpeakerTexture(state) {
|
|
|
14543
14786
|
return texture;
|
|
14544
14787
|
}
|
|
14545
14788
|
function useSpeakerTextures(enabled) {
|
|
14546
|
-
const [textures, setTextures] = (0,
|
|
14547
|
-
(0,
|
|
14789
|
+
const [textures, setTextures] = (0, import_react50.useState)({ playing: null, stopped: null });
|
|
14790
|
+
(0, import_react50.useEffect)(() => {
|
|
14548
14791
|
if (!enabled) {
|
|
14549
14792
|
setTextures({ playing: null, stopped: null });
|
|
14550
14793
|
return;
|
|
@@ -14561,10 +14804,10 @@ function useSpeakerTextures(enabled) {
|
|
|
14561
14804
|
}
|
|
14562
14805
|
function useIconTexture(icon, enabled, onError, id) {
|
|
14563
14806
|
const gl = (0, import_fiber25.useThree)((state) => state.gl);
|
|
14564
|
-
const [texture, setTexture] = (0,
|
|
14565
|
-
const onErrorRef = (0,
|
|
14807
|
+
const [texture, setTexture] = (0, import_react50.useState)(null);
|
|
14808
|
+
const onErrorRef = (0, import_react50.useRef)(onError);
|
|
14566
14809
|
onErrorRef.current = onError;
|
|
14567
|
-
(0,
|
|
14810
|
+
(0, import_react50.useEffect)(() => {
|
|
14568
14811
|
let active = true;
|
|
14569
14812
|
setTexture(null);
|
|
14570
14813
|
if (!enabled || !icon) {
|
|
@@ -14601,7 +14844,7 @@ function useIconTexture(icon, enabled, onError, id) {
|
|
|
14601
14844
|
active = false;
|
|
14602
14845
|
};
|
|
14603
14846
|
}, [enabled, gl, icon, id]);
|
|
14604
|
-
(0,
|
|
14847
|
+
(0, import_react50.useEffect)(
|
|
14605
14848
|
() => () => {
|
|
14606
14849
|
texture?.dispose();
|
|
14607
14850
|
},
|
|
@@ -14621,13 +14864,13 @@ function useAudioHowl({
|
|
|
14621
14864
|
src,
|
|
14622
14865
|
format
|
|
14623
14866
|
}) {
|
|
14624
|
-
const [howl, setHowl] = (0,
|
|
14625
|
-
const playingRef = (0,
|
|
14626
|
-
const loopRef = (0,
|
|
14627
|
-
const onEndedRef = (0,
|
|
14628
|
-
const onErrorRef = (0,
|
|
14629
|
-
const onPlaybackErrorRef = (0,
|
|
14630
|
-
const onPlaybackStateChangeRef = (0,
|
|
14867
|
+
const [howl, setHowl] = (0, import_react50.useState)(null);
|
|
14868
|
+
const playingRef = (0, import_react50.useRef)(playing);
|
|
14869
|
+
const loopRef = (0, import_react50.useRef)(loop ?? false);
|
|
14870
|
+
const onEndedRef = (0, import_react50.useRef)(onEnded);
|
|
14871
|
+
const onErrorRef = (0, import_react50.useRef)(onError);
|
|
14872
|
+
const onPlaybackErrorRef = (0, import_react50.useRef)(onPlaybackError);
|
|
14873
|
+
const onPlaybackStateChangeRef = (0, import_react50.useRef)(onPlaybackStateChange);
|
|
14631
14874
|
playingRef.current = playing;
|
|
14632
14875
|
loopRef.current = loop ?? false;
|
|
14633
14876
|
onEndedRef.current = onEnded;
|
|
@@ -14636,7 +14879,7 @@ function useAudioHowl({
|
|
|
14636
14879
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
14637
14880
|
const sourcesKey = sourceList(src).join("\0");
|
|
14638
14881
|
const formatsKey = sourceList(format).join("\0");
|
|
14639
|
-
(0,
|
|
14882
|
+
(0, import_react50.useEffect)(() => {
|
|
14640
14883
|
const sources = sourcesKey.length > 0 ? sourcesKey.split("\0") : [];
|
|
14641
14884
|
if (sources.length === 0) {
|
|
14642
14885
|
setHowl(null);
|
|
@@ -14674,7 +14917,7 @@ function useAudioHowl({
|
|
|
14674
14917
|
handle.dispose();
|
|
14675
14918
|
};
|
|
14676
14919
|
}, [crossOrigin, id, sourcesKey, formatsKey]);
|
|
14677
|
-
(0,
|
|
14920
|
+
(0, import_react50.useEffect)(() => {
|
|
14678
14921
|
howl?.loop(loop ?? false);
|
|
14679
14922
|
}, [howl, loop]);
|
|
14680
14923
|
return howl;
|
|
@@ -14720,15 +14963,15 @@ function AudioHotspot({
|
|
|
14720
14963
|
const stoppedIconTexture = useIconTexture(icon, marker, onError, id);
|
|
14721
14964
|
const playingIconTexture = useIconTexture(playingIcon, marker, onError, id);
|
|
14722
14965
|
const markerTexture = playing ? playingIconTexture ?? stoppedIconTexture ?? speakerTextures.playing : stoppedIconTexture ?? speakerTextures.stopped;
|
|
14723
|
-
const playingRef = (0,
|
|
14966
|
+
const playingRef = (0, import_react50.useRef)(playing);
|
|
14724
14967
|
playingRef.current = playing;
|
|
14725
|
-
const mutedRef = (0,
|
|
14726
|
-
const volumeRef = (0,
|
|
14727
|
-
const rangeRef = (0,
|
|
14968
|
+
const mutedRef = (0, import_react50.useRef)(muted);
|
|
14969
|
+
const volumeRef = (0, import_react50.useRef)(volume);
|
|
14970
|
+
const rangeRef = (0, import_react50.useRef)(range);
|
|
14728
14971
|
mutedRef.current = muted;
|
|
14729
14972
|
volumeRef.current = volume;
|
|
14730
14973
|
rangeRef.current = range;
|
|
14731
|
-
(0,
|
|
14974
|
+
(0, import_react50.useEffect)(() => {
|
|
14732
14975
|
if (!howl) {
|
|
14733
14976
|
return;
|
|
14734
14977
|
}
|
|
@@ -14738,7 +14981,7 @@ function AudioHotspot({
|
|
|
14738
14981
|
}
|
|
14739
14982
|
howl.play();
|
|
14740
14983
|
}, [howl, playing]);
|
|
14741
|
-
(0,
|
|
14984
|
+
(0, import_react50.useEffect)(() => {
|
|
14742
14985
|
if (!howl || !pauseWhenHidden) {
|
|
14743
14986
|
return;
|
|
14744
14987
|
}
|
|
@@ -14773,7 +15016,7 @@ function AudioHotspot({
|
|
|
14773
15016
|
}
|
|
14774
15017
|
|
|
14775
15018
|
// src/hotspot/text-hotspot.tsx
|
|
14776
|
-
var
|
|
15019
|
+
var import_react51 = require("react");
|
|
14777
15020
|
var import_fiber26 = require("@react-three/fiber");
|
|
14778
15021
|
var import_three33 = require("three");
|
|
14779
15022
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
@@ -15072,7 +15315,7 @@ function useRasterLongSide(width, height, scale, scaleMode, referenceFov) {
|
|
|
15072
15315
|
Math.max(layout.canvasWidth, layout.canvasHeight)
|
|
15073
15316
|
);
|
|
15074
15317
|
};
|
|
15075
|
-
const [rasterLong, setRasterLong] = (0,
|
|
15318
|
+
const [rasterLong, setRasterLong] = (0, import_react51.useState)(measure);
|
|
15076
15319
|
const measured = measure();
|
|
15077
15320
|
if (measured !== rasterLong) {
|
|
15078
15321
|
setRasterLong(measured);
|
|
@@ -15085,12 +15328,12 @@ function useRasterLongSide(width, height, scale, scaleMode, referenceFov) {
|
|
|
15085
15328
|
}
|
|
15086
15329
|
function useTextTexture(text, width, height, style, scale, scaleMode, referenceFov, onLoad, onError) {
|
|
15087
15330
|
const rasterLong = useRasterLongSide(width, height, scale, scaleMode, referenceFov);
|
|
15088
|
-
const [texture, setTexture] = (0,
|
|
15089
|
-
const onLoadRef = (0,
|
|
15090
|
-
const onErrorRef = (0,
|
|
15331
|
+
const [texture, setTexture] = (0, import_react51.useState)(null);
|
|
15332
|
+
const onLoadRef = (0, import_react51.useRef)(onLoad);
|
|
15333
|
+
const onErrorRef = (0, import_react51.useRef)(onError);
|
|
15091
15334
|
onLoadRef.current = onLoad;
|
|
15092
15335
|
onErrorRef.current = onError;
|
|
15093
|
-
(0,
|
|
15336
|
+
(0, import_react51.useEffect)(() => {
|
|
15094
15337
|
let cancelled = false;
|
|
15095
15338
|
let nextTexture = null;
|
|
15096
15339
|
const run = async () => {
|
|
@@ -15316,7 +15559,7 @@ function IframeHotspot({
|
|
|
15316
15559
|
}
|
|
15317
15560
|
|
|
15318
15561
|
// src/hotspot/polygon-hotspot.tsx
|
|
15319
|
-
var
|
|
15562
|
+
var import_react52 = require("react");
|
|
15320
15563
|
var import_three35 = require("three");
|
|
15321
15564
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
15322
15565
|
var POLYGON_RADIUS = 990;
|
|
@@ -15574,24 +15817,24 @@ function PolygonHotspot({
|
|
|
15574
15817
|
onInvalid,
|
|
15575
15818
|
...anchorProps
|
|
15576
15819
|
}) {
|
|
15577
|
-
const issues = (0,
|
|
15820
|
+
const issues = (0, import_react52.useMemo)(() => validatePolygonVertices(vertices), [vertices]);
|
|
15578
15821
|
const valid = issues.length === 0;
|
|
15579
|
-
const center = (0,
|
|
15580
|
-
const fillGeometry = (0,
|
|
15822
|
+
const center = (0, import_react52.useMemo)(() => valid ? polygonCenter(vertices) : null, [valid, vertices]);
|
|
15823
|
+
const fillGeometry = (0, import_react52.useMemo)(
|
|
15581
15824
|
() => valid && center ? makeFillGeometry(vertices, center) : null,
|
|
15582
15825
|
[center, valid, vertices]
|
|
15583
15826
|
);
|
|
15584
|
-
const strokePoints = (0,
|
|
15827
|
+
const strokePoints = (0, import_react52.useMemo)(
|
|
15585
15828
|
() => valid && center ? makeStrokePositions(vertices, center) : null,
|
|
15586
15829
|
[center, valid, vertices]
|
|
15587
15830
|
);
|
|
15588
15831
|
const resolvedStrokeOpacity = Math.max(0, Math.min(strokeOpacity, 1));
|
|
15589
|
-
const startVerticesRef = (0,
|
|
15832
|
+
const startVerticesRef = (0, import_react52.useRef)(null);
|
|
15590
15833
|
const issuesKey = issues.map((issue) => issue.code).join(",");
|
|
15591
|
-
(0,
|
|
15834
|
+
(0, import_react52.useEffect)(() => {
|
|
15592
15835
|
if (!valid) onInvalid?.(issues);
|
|
15593
15836
|
}, [issues, issuesKey, onInvalid, valid]);
|
|
15594
|
-
(0,
|
|
15837
|
+
(0, import_react52.useEffect)(() => () => fillGeometry?.dispose(), [fillGeometry]);
|
|
15595
15838
|
if (!valid || !center || !fillGeometry || !strokePoints || strokePoints.length < 2) {
|
|
15596
15839
|
return null;
|
|
15597
15840
|
}
|
|
@@ -15671,7 +15914,7 @@ function PolygonHotspot({
|
|
|
15671
15914
|
}
|
|
15672
15915
|
|
|
15673
15916
|
// src/hotspot/polyline-hotspot.tsx
|
|
15674
|
-
var
|
|
15917
|
+
var import_react53 = require("react");
|
|
15675
15918
|
var import_three36 = require("three");
|
|
15676
15919
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
15677
15920
|
var POLYLINE_RADIUS = 990;
|
|
@@ -15790,16 +16033,16 @@ function PolylineHotspot({
|
|
|
15790
16033
|
onInvalid,
|
|
15791
16034
|
...anchorProps
|
|
15792
16035
|
}) {
|
|
15793
|
-
const issues = (0,
|
|
16036
|
+
const issues = (0, import_react53.useMemo)(() => validatePolylineVertices(vertices), [vertices]);
|
|
15794
16037
|
const valid = issues.length === 0;
|
|
15795
|
-
const center = (0,
|
|
15796
|
-
const linePoints = (0,
|
|
16038
|
+
const center = (0, import_react53.useMemo)(() => valid ? polylineCenter(vertices) : null, [valid, vertices]);
|
|
16039
|
+
const linePoints = (0, import_react53.useMemo)(
|
|
15797
16040
|
() => valid && center ? makeLinePositions(vertices, center) : null,
|
|
15798
16041
|
[center, valid, vertices]
|
|
15799
16042
|
);
|
|
15800
16043
|
const opacity = Math.max(0, Math.min(strokeOpacity, 1));
|
|
15801
|
-
const startVerticesRef = (0,
|
|
15802
|
-
(0,
|
|
16044
|
+
const startVerticesRef = (0, import_react53.useRef)(null);
|
|
16045
|
+
(0, import_react53.useEffect)(() => {
|
|
15803
16046
|
if (!valid) onInvalid?.(issues);
|
|
15804
16047
|
}, [issues, onInvalid, valid]);
|
|
15805
16048
|
if (!valid || !center || !linePoints || linePoints.length < 2) return null;
|
|
@@ -15992,7 +16235,7 @@ function ProjectHotspot({
|
|
|
15992
16235
|
renderHotspot,
|
|
15993
16236
|
execute
|
|
15994
16237
|
}) {
|
|
15995
|
-
const [playing, setPlaying] = (0,
|
|
16238
|
+
const [playing, setPlaying] = (0, import_react54.useState)(
|
|
15996
16239
|
"playing" in hotspot ? hotspot.playing ?? false : false
|
|
15997
16240
|
);
|
|
15998
16241
|
const togglePlayback = () => setPlaying((value) => !value);
|
|
@@ -16048,21 +16291,21 @@ function ProjectScenes({
|
|
|
16048
16291
|
renderHotspot,
|
|
16049
16292
|
...options
|
|
16050
16293
|
}) {
|
|
16051
|
-
const controls = (0,
|
|
16294
|
+
const controls = (0, import_react54.useContext)(PanoramaViewContext);
|
|
16052
16295
|
if (!controls)
|
|
16053
16296
|
throw new Error("<ProjectScenes> must be rendered inside <PanoViewer>.");
|
|
16054
|
-
const [selection, setSelection] = (0,
|
|
16297
|
+
const [selection, setSelection] = (0, import_react54.useState)({
|
|
16055
16298
|
project,
|
|
16056
16299
|
id: project.initialSceneId
|
|
16057
16300
|
});
|
|
16058
16301
|
if (selection.project !== project)
|
|
16059
16302
|
setSelection({ project, id: project.initialSceneId });
|
|
16060
16303
|
const currentId = activeSceneId ?? (selection.project === project ? selection.id : project.initialSceneId);
|
|
16061
|
-
const entries = (0,
|
|
16304
|
+
const entries = (0, import_react54.useMemo)(
|
|
16062
16305
|
() => new Map(project.scenes.map((entry) => [entry.scene.id, entry])),
|
|
16063
16306
|
[project]
|
|
16064
16307
|
);
|
|
16065
|
-
const scenes = (0,
|
|
16308
|
+
const scenes = (0, import_react54.useMemo)(
|
|
16066
16309
|
() => project.scenes.map((entry) => entry.scene),
|
|
16067
16310
|
[project]
|
|
16068
16311
|
);
|
|
@@ -16115,7 +16358,7 @@ function ProjectScenes({
|
|
|
16115
16358
|
}
|
|
16116
16359
|
|
|
16117
16360
|
// src/background-audio.tsx
|
|
16118
|
-
var
|
|
16361
|
+
var import_react55 = require("react");
|
|
16119
16362
|
var DEFAULT_FADE_MS = 400;
|
|
16120
16363
|
function resolveFadeMs(value) {
|
|
16121
16364
|
if (!Number.isFinite(value)) {
|
|
@@ -16157,31 +16400,31 @@ function BackgroundAudio({
|
|
|
16157
16400
|
onEnded,
|
|
16158
16401
|
onError
|
|
16159
16402
|
}) {
|
|
16160
|
-
const controlsRef = (0,
|
|
16403
|
+
const controlsRef = (0, import_react55.useContext)(PanoramaViewContext);
|
|
16161
16404
|
if (!controlsRef) {
|
|
16162
16405
|
throw new Error("<BackgroundAudio> must be rendered inside <PanoViewer>.");
|
|
16163
16406
|
}
|
|
16164
16407
|
const isControlled = controlledPlaying !== void 0;
|
|
16165
|
-
const [internalPlaying, setInternalPlaying] = (0,
|
|
16408
|
+
const [internalPlaying, setInternalPlaying] = (0, import_react55.useState)(defaultPlaying);
|
|
16166
16409
|
const playing = isControlled ? controlledPlaying : internalPlaying;
|
|
16167
16410
|
const urls = resolveBackgroundAudioUrls(src, sources, sceneId);
|
|
16168
16411
|
usePanoMediaActivationIntent(playing && urls.length > 0);
|
|
16169
16412
|
const trackKey = urls.join("\0");
|
|
16170
|
-
const currentRef = (0,
|
|
16171
|
-
const outgoingRef = (0,
|
|
16172
|
-
const fadingInRef = (0,
|
|
16173
|
-
const isFirstTrackRef = (0,
|
|
16174
|
-
const playingRef = (0,
|
|
16175
|
-
const loopRef = (0,
|
|
16176
|
-
const mutedRef = (0,
|
|
16177
|
-
const volumeRef = (0,
|
|
16178
|
-
const mutedPropRef = (0,
|
|
16179
|
-
const volumePropRef = (0,
|
|
16180
|
-
const fadeMsRef = (0,
|
|
16181
|
-
const onPlaybackStateChangeRef = (0,
|
|
16182
|
-
const onPlaybackErrorRef = (0,
|
|
16183
|
-
const onEndedRef = (0,
|
|
16184
|
-
const onErrorRef = (0,
|
|
16413
|
+
const currentRef = (0, import_react55.useRef)(null);
|
|
16414
|
+
const outgoingRef = (0, import_react55.useRef)([]);
|
|
16415
|
+
const fadingInRef = (0, import_react55.useRef)(false);
|
|
16416
|
+
const isFirstTrackRef = (0, import_react55.useRef)(true);
|
|
16417
|
+
const playingRef = (0, import_react55.useRef)(playing);
|
|
16418
|
+
const loopRef = (0, import_react55.useRef)(loop);
|
|
16419
|
+
const mutedRef = (0, import_react55.useRef)(muted);
|
|
16420
|
+
const volumeRef = (0, import_react55.useRef)(volume);
|
|
16421
|
+
const mutedPropRef = (0, import_react55.useRef)(muted);
|
|
16422
|
+
const volumePropRef = (0, import_react55.useRef)(volume);
|
|
16423
|
+
const fadeMsRef = (0, import_react55.useRef)(resolveFadeMs(fadeMs));
|
|
16424
|
+
const onPlaybackStateChangeRef = (0, import_react55.useRef)(onPlaybackStateChange);
|
|
16425
|
+
const onPlaybackErrorRef = (0, import_react55.useRef)(onPlaybackError);
|
|
16426
|
+
const onEndedRef = (0, import_react55.useRef)(onEnded);
|
|
16427
|
+
const onErrorRef = (0, import_react55.useRef)(onError);
|
|
16185
16428
|
playingRef.current = playing;
|
|
16186
16429
|
loopRef.current = loop;
|
|
16187
16430
|
fadeMsRef.current = resolveFadeMs(fadeMs);
|
|
@@ -16197,7 +16440,7 @@ function BackgroundAudio({
|
|
|
16197
16440
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
16198
16441
|
onEndedRef.current = onEnded;
|
|
16199
16442
|
onErrorRef.current = onError;
|
|
16200
|
-
const snapshotRef = (0,
|
|
16443
|
+
const snapshotRef = (0, import_react55.useRef)({
|
|
16201
16444
|
ready: false,
|
|
16202
16445
|
playing: false,
|
|
16203
16446
|
blocked: false,
|
|
@@ -16205,7 +16448,7 @@ function BackgroundAudio({
|
|
|
16205
16448
|
muted,
|
|
16206
16449
|
volume
|
|
16207
16450
|
});
|
|
16208
|
-
const snapshotListenersRef = (0,
|
|
16451
|
+
const snapshotListenersRef = (0, import_react55.useRef)(/* @__PURE__ */ new Set());
|
|
16209
16452
|
const notifySnapshot = (patch) => {
|
|
16210
16453
|
const prev = snapshotRef.current;
|
|
16211
16454
|
snapshotRef.current = { ...prev, ...patch };
|
|
@@ -16213,9 +16456,9 @@ function BackgroundAudio({
|
|
|
16213
16456
|
listener();
|
|
16214
16457
|
}
|
|
16215
16458
|
};
|
|
16216
|
-
const isControlledRef = (0,
|
|
16459
|
+
const isControlledRef = (0, import_react55.useRef)(isControlled);
|
|
16217
16460
|
isControlledRef.current = isControlled;
|
|
16218
|
-
const controller = (0,
|
|
16461
|
+
const controller = (0, import_react55.useMemo)(
|
|
16219
16462
|
() => ({
|
|
16220
16463
|
subscribe: (onStoreChange) => {
|
|
16221
16464
|
snapshotListenersRef.current.add(onStoreChange);
|
|
@@ -16273,8 +16516,8 @@ function BackgroundAudio({
|
|
|
16273
16516
|
}),
|
|
16274
16517
|
[]
|
|
16275
16518
|
);
|
|
16276
|
-
const bgmHost = (0,
|
|
16277
|
-
(0,
|
|
16519
|
+
const bgmHost = (0, import_react55.useContext)(BackgroundAudioHostContext);
|
|
16520
|
+
(0, import_react55.useEffect)(() => {
|
|
16278
16521
|
if (!bgmHost) {
|
|
16279
16522
|
return;
|
|
16280
16523
|
}
|
|
@@ -16287,7 +16530,7 @@ function BackgroundAudio({
|
|
|
16287
16530
|
}
|
|
16288
16531
|
};
|
|
16289
16532
|
}, [bgmHost, controller]);
|
|
16290
|
-
(0,
|
|
16533
|
+
(0, import_react55.useEffect)(() => {
|
|
16291
16534
|
return () => {
|
|
16292
16535
|
fadingInRef.current = false;
|
|
16293
16536
|
isFirstTrackRef.current = true;
|
|
@@ -16299,7 +16542,7 @@ function BackgroundAudio({
|
|
|
16299
16542
|
outgoingRef.current = [];
|
|
16300
16543
|
};
|
|
16301
16544
|
}, []);
|
|
16302
|
-
(0,
|
|
16545
|
+
(0, import_react55.useEffect)(() => {
|
|
16303
16546
|
const previous = currentRef.current;
|
|
16304
16547
|
if (previous?.key === trackKey && previous.crossOrigin === crossOrigin) {
|
|
16305
16548
|
return;
|
|
@@ -16402,7 +16645,7 @@ function BackgroundAudio({
|
|
|
16402
16645
|
retire(previous);
|
|
16403
16646
|
}
|
|
16404
16647
|
}, [crossOrigin, trackKey]);
|
|
16405
|
-
(0,
|
|
16648
|
+
(0, import_react55.useEffect)(() => {
|
|
16406
16649
|
const howl = currentRef.current?.handle.howl;
|
|
16407
16650
|
if (!howl) {
|
|
16408
16651
|
return;
|
|
@@ -16422,7 +16665,7 @@ function BackgroundAudio({
|
|
|
16422
16665
|
howl.play();
|
|
16423
16666
|
}
|
|
16424
16667
|
}, [playing, trackKey]);
|
|
16425
|
-
(0,
|
|
16668
|
+
(0, import_react55.useEffect)(() => {
|
|
16426
16669
|
const slot = currentRef.current;
|
|
16427
16670
|
if (!slot) {
|
|
16428
16671
|
return;
|
|
@@ -16437,7 +16680,7 @@ function BackgroundAudio({
|
|
|
16437
16680
|
volume: clampAudioVolume(volumeRef.current)
|
|
16438
16681
|
});
|
|
16439
16682
|
}, [loop, muted, trackKey, volume]);
|
|
16440
|
-
(0,
|
|
16683
|
+
(0, import_react55.useEffect)(() => {
|
|
16441
16684
|
if (!pauseWhenHidden) {
|
|
16442
16685
|
return;
|
|
16443
16686
|
}
|
|
@@ -16463,7 +16706,7 @@ function BackgroundAudio({
|
|
|
16463
16706
|
}
|
|
16464
16707
|
|
|
16465
16708
|
// src/pano-filter/pano-filter.tsx
|
|
16466
|
-
var
|
|
16709
|
+
var import_react56 = require("react");
|
|
16467
16710
|
function PanoFilter({
|
|
16468
16711
|
preset = "none",
|
|
16469
16712
|
intensity,
|
|
@@ -16471,11 +16714,11 @@ function PanoFilter({
|
|
|
16471
16714
|
colorMatrix,
|
|
16472
16715
|
colorMatrixScope
|
|
16473
16716
|
}) {
|
|
16474
|
-
const host = (0,
|
|
16717
|
+
const host = (0, import_react56.useContext)(PanoFilterHostContext);
|
|
16475
16718
|
if (!host) {
|
|
16476
16719
|
throw new Error("<PanoFilter> must be rendered inside <PanoViewer>.");
|
|
16477
16720
|
}
|
|
16478
|
-
const snapshot = (0,
|
|
16721
|
+
const snapshot = (0, import_react56.useMemo)(
|
|
16479
16722
|
() => resolvePanoFilterSnapshot({
|
|
16480
16723
|
preset,
|
|
16481
16724
|
intensity,
|
|
@@ -16485,13 +16728,13 @@ function PanoFilter({
|
|
|
16485
16728
|
}),
|
|
16486
16729
|
[enabled, intensity, preset, colorMatrix, colorMatrixScope]
|
|
16487
16730
|
);
|
|
16488
|
-
(0,
|
|
16731
|
+
(0, import_react56.useEffect)(() => {
|
|
16489
16732
|
claimPanoFilter(host);
|
|
16490
16733
|
return () => {
|
|
16491
16734
|
releasePanoFilter(host);
|
|
16492
16735
|
};
|
|
16493
16736
|
}, [host]);
|
|
16494
|
-
(0,
|
|
16737
|
+
(0, import_react56.useEffect)(() => {
|
|
16495
16738
|
setPanoFilterSnapshot(host, snapshot);
|
|
16496
16739
|
}, [host, snapshot]);
|
|
16497
16740
|
return null;
|
|
@@ -16499,7 +16742,7 @@ function PanoFilter({
|
|
|
16499
16742
|
|
|
16500
16743
|
// src/gyro.tsx
|
|
16501
16744
|
var import_fiber27 = require("@react-three/fiber");
|
|
16502
|
-
var
|
|
16745
|
+
var import_react57 = require("react");
|
|
16503
16746
|
var import_three37 = require("three");
|
|
16504
16747
|
var deviceOrientationPermissionState = "unknown";
|
|
16505
16748
|
function isMobileDevice() {
|
|
@@ -16517,7 +16760,7 @@ function resolveFriction(value) {
|
|
|
16517
16760
|
function resolveSoftstart(value) {
|
|
16518
16761
|
return Math.max(finiteOr(value, 0.5), 0);
|
|
16519
16762
|
}
|
|
16520
|
-
var Gyro = (0,
|
|
16763
|
+
var Gyro = (0, import_react57.forwardRef)(function Gyro2({
|
|
16521
16764
|
enabled = false,
|
|
16522
16765
|
camroll = true,
|
|
16523
16766
|
absolute = false,
|
|
@@ -16532,35 +16775,35 @@ var Gyro = (0, import_react56.forwardRef)(function Gyro2({
|
|
|
16532
16775
|
onDisable,
|
|
16533
16776
|
onDenied
|
|
16534
16777
|
}, ref) {
|
|
16535
|
-
const controlsRef = (0,
|
|
16536
|
-
const eventBus = (0,
|
|
16778
|
+
const controlsRef = (0, import_react57.useContext)(PanoramaViewContext);
|
|
16779
|
+
const eventBus = (0, import_react57.useContext)(PanoEventBusContext);
|
|
16537
16780
|
const { gl } = (0, import_fiber27.useThree)();
|
|
16538
|
-
const [internallyDisabled, setInternallyDisabled] = (0,
|
|
16539
|
-
const [available, setAvailableState] = (0,
|
|
16540
|
-
const availableRef = (0,
|
|
16541
|
-
const availabilityReportedRef = (0,
|
|
16542
|
-
const activeRef = (0,
|
|
16543
|
-
const permissionRef = (0,
|
|
16544
|
-
const absoluteEventSourceRef = (0,
|
|
16545
|
-
const rawQuaternionRef = (0,
|
|
16546
|
-
const hasRawQuaternionRef = (0,
|
|
16547
|
-
const calibrationRef = (0,
|
|
16548
|
-
const hasCalibrationRef = (0,
|
|
16549
|
-
const calibratedQuaternionRef = (0,
|
|
16550
|
-
const absoluteOffsetRef = (0,
|
|
16551
|
-
const screenAngleRef = (0,
|
|
16552
|
-
const startPoseRef = (0,
|
|
16553
|
-
const enabledAtRef = (0,
|
|
16554
|
-
const filteredPoseRef = (0,
|
|
16555
|
-
const lastAppliedPoseRef = (0,
|
|
16556
|
-
const lastSamplePoseRef = (0,
|
|
16557
|
-
const lastSampleAtRef = (0,
|
|
16558
|
-
const previousYawRef = (0,
|
|
16559
|
-
const absoluteRef = (0,
|
|
16560
|
-
const northRef = (0,
|
|
16781
|
+
const [internallyDisabled, setInternallyDisabled] = (0, import_react57.useState)(false);
|
|
16782
|
+
const [available, setAvailableState] = (0, import_react57.useState)(false);
|
|
16783
|
+
const availableRef = (0, import_react57.useRef)(false);
|
|
16784
|
+
const availabilityReportedRef = (0, import_react57.useRef)(null);
|
|
16785
|
+
const activeRef = (0, import_react57.useRef)(false);
|
|
16786
|
+
const permissionRef = (0, import_react57.useRef)(deviceOrientationPermissionState);
|
|
16787
|
+
const absoluteEventSourceRef = (0, import_react57.useRef)(null);
|
|
16788
|
+
const rawQuaternionRef = (0, import_react57.useRef)(new import_three37.Quaternion());
|
|
16789
|
+
const hasRawQuaternionRef = (0, import_react57.useRef)(false);
|
|
16790
|
+
const calibrationRef = (0, import_react57.useRef)(new import_three37.Quaternion());
|
|
16791
|
+
const hasCalibrationRef = (0, import_react57.useRef)(false);
|
|
16792
|
+
const calibratedQuaternionRef = (0, import_react57.useRef)(new import_three37.Quaternion());
|
|
16793
|
+
const absoluteOffsetRef = (0, import_react57.useRef)({ yaw: 0, pitch: 0 });
|
|
16794
|
+
const screenAngleRef = (0, import_react57.useRef)(getScreenOrientationAngle());
|
|
16795
|
+
const startPoseRef = (0, import_react57.useRef)(null);
|
|
16796
|
+
const enabledAtRef = (0, import_react57.useRef)(0);
|
|
16797
|
+
const filteredPoseRef = (0, import_react57.useRef)(null);
|
|
16798
|
+
const lastAppliedPoseRef = (0, import_react57.useRef)(null);
|
|
16799
|
+
const lastSamplePoseRef = (0, import_react57.useRef)(null);
|
|
16800
|
+
const lastSampleAtRef = (0, import_react57.useRef)(null);
|
|
16801
|
+
const previousYawRef = (0, import_react57.useRef)(void 0);
|
|
16802
|
+
const absoluteRef = (0, import_react57.useRef)(absolute);
|
|
16803
|
+
const northRef = (0, import_react57.useRef)(north);
|
|
16561
16804
|
absoluteRef.current = absolute;
|
|
16562
16805
|
northRef.current = north;
|
|
16563
|
-
const callbacksRef = (0,
|
|
16806
|
+
const callbacksRef = (0, import_react57.useRef)({
|
|
16564
16807
|
onAvailable,
|
|
16565
16808
|
onUnavailable,
|
|
16566
16809
|
onEnable,
|
|
@@ -16577,7 +16820,7 @@ var Gyro = (0, import_react56.forwardRef)(function Gyro2({
|
|
|
16577
16820
|
if (!controlsRef) {
|
|
16578
16821
|
throw new Error("<Gyro> must be rendered inside <PanoViewer>.");
|
|
16579
16822
|
}
|
|
16580
|
-
const emit = (0,
|
|
16823
|
+
const emit = (0, import_react57.useCallback)(
|
|
16581
16824
|
(type) => {
|
|
16582
16825
|
eventBus?.emit(type, void 0);
|
|
16583
16826
|
switch (type) {
|
|
@@ -16604,7 +16847,7 @@ var Gyro = (0, import_react56.forwardRef)(function Gyro2({
|
|
|
16604
16847
|
},
|
|
16605
16848
|
[eventBus]
|
|
16606
16849
|
);
|
|
16607
|
-
const setAvailable = (0,
|
|
16850
|
+
const setAvailable = (0, import_react57.useCallback)(
|
|
16608
16851
|
(nextAvailable) => {
|
|
16609
16852
|
availableRef.current = nextAvailable;
|
|
16610
16853
|
setAvailableState(nextAvailable);
|
|
@@ -16616,7 +16859,7 @@ var Gyro = (0, import_react56.forwardRef)(function Gyro2({
|
|
|
16616
16859
|
},
|
|
16617
16860
|
[emit]
|
|
16618
16861
|
);
|
|
16619
|
-
const requestPermission = (0,
|
|
16862
|
+
const requestPermission = (0, import_react57.useCallback)(async () => {
|
|
16620
16863
|
if (!availableRef.current) {
|
|
16621
16864
|
return false;
|
|
16622
16865
|
}
|
|
@@ -16649,7 +16892,7 @@ var Gyro = (0, import_react56.forwardRef)(function Gyro2({
|
|
|
16649
16892
|
emit("gyrodenied");
|
|
16650
16893
|
return false;
|
|
16651
16894
|
}, [emit, setAvailable]);
|
|
16652
|
-
const deactivate = (0,
|
|
16895
|
+
const deactivate = (0, import_react57.useCallback)(() => {
|
|
16653
16896
|
if (activeRef.current) {
|
|
16654
16897
|
activeRef.current = false;
|
|
16655
16898
|
controlsRef.current?.setGyroActive(false);
|
|
@@ -16664,7 +16907,7 @@ var Gyro = (0, import_react56.forwardRef)(function Gyro2({
|
|
|
16664
16907
|
lastSampleAtRef.current = null;
|
|
16665
16908
|
previousYawRef.current = void 0;
|
|
16666
16909
|
}, [controlsRef, emit]);
|
|
16667
|
-
const anchorToView = (0,
|
|
16910
|
+
const anchorToView = (0, import_react57.useCallback)(
|
|
16668
16911
|
(yaw, pitch) => {
|
|
16669
16912
|
if (!hasRawQuaternionRef.current) {
|
|
16670
16913
|
return;
|
|
@@ -16694,7 +16937,7 @@ var Gyro = (0, import_react56.forwardRef)(function Gyro2({
|
|
|
16694
16937
|
},
|
|
16695
16938
|
[]
|
|
16696
16939
|
);
|
|
16697
|
-
const resetSensor = (0,
|
|
16940
|
+
const resetSensor = (0, import_react57.useCallback)(
|
|
16698
16941
|
(yaw, pitch) => {
|
|
16699
16942
|
if (!hasRawQuaternionRef.current) {
|
|
16700
16943
|
return;
|
|
@@ -16715,7 +16958,7 @@ var Gyro = (0, import_react56.forwardRef)(function Gyro2({
|
|
|
16715
16958
|
},
|
|
16716
16959
|
[anchorToView, controlsRef]
|
|
16717
16960
|
);
|
|
16718
|
-
(0,
|
|
16961
|
+
(0, import_react57.useImperativeHandle)(
|
|
16719
16962
|
ref,
|
|
16720
16963
|
() => ({
|
|
16721
16964
|
resetSensor,
|
|
@@ -16725,19 +16968,19 @@ var Gyro = (0, import_react56.forwardRef)(function Gyro2({
|
|
|
16725
16968
|
}),
|
|
16726
16969
|
[requestPermission, resetSensor]
|
|
16727
16970
|
);
|
|
16728
|
-
(0,
|
|
16971
|
+
(0, import_react57.useEffect)(() => {
|
|
16729
16972
|
if (!enabled) {
|
|
16730
16973
|
setInternallyDisabled(false);
|
|
16731
16974
|
}
|
|
16732
16975
|
}, [enabled]);
|
|
16733
|
-
(0,
|
|
16976
|
+
(0, import_react57.useEffect)(() => {
|
|
16734
16977
|
const supported = typeof window !== "undefined" && window.isSecureContext && typeof DeviceOrientationEvent !== "undefined" && (desktopSupport || isMobileDevice());
|
|
16735
16978
|
setAvailable(supported);
|
|
16736
16979
|
}, [desktopSupport, setAvailable]);
|
|
16737
|
-
(0,
|
|
16980
|
+
(0, import_react57.useEffect)(() => {
|
|
16738
16981
|
controlsRef.current?.setGyroTouchMode(touchMode);
|
|
16739
16982
|
}, [controlsRef, touchMode]);
|
|
16740
|
-
(0,
|
|
16983
|
+
(0, import_react57.useEffect)(() => {
|
|
16741
16984
|
if (!enabled || internallyDisabled || touchMode !== "disablegyro") {
|
|
16742
16985
|
return;
|
|
16743
16986
|
}
|
|
@@ -16751,7 +16994,7 @@ var Gyro = (0, import_react56.forwardRef)(function Gyro2({
|
|
|
16751
16994
|
gl.domElement.removeEventListener("pointerdown", onPointerDown);
|
|
16752
16995
|
};
|
|
16753
16996
|
}, [enabled, gl, internallyDisabled, touchMode]);
|
|
16754
|
-
(0,
|
|
16997
|
+
(0, import_react57.useEffect)(() => {
|
|
16755
16998
|
if (!enabled || internallyDisabled || !available) {
|
|
16756
16999
|
deactivate();
|
|
16757
17000
|
return;
|
|
@@ -16974,7 +17217,7 @@ var Gyro = (0, import_react56.forwardRef)(function Gyro2({
|
|
|
16974
17217
|
|
|
16975
17218
|
// src/webvr/webvr.tsx
|
|
16976
17219
|
var import_fiber30 = require("@react-three/fiber");
|
|
16977
|
-
var
|
|
17220
|
+
var import_react62 = require("react");
|
|
16978
17221
|
|
|
16979
17222
|
// src/webvr/detect.ts
|
|
16980
17223
|
function isMobileVRDevice() {
|
|
@@ -16995,6 +17238,184 @@ async function detectWebVRCapabilities() {
|
|
|
16995
17238
|
return { webxr, mobile, sensor };
|
|
16996
17239
|
}
|
|
16997
17240
|
|
|
17241
|
+
// src/webvr/dpdb.ts
|
|
17242
|
+
var DEFAULT_WEBVR_DATABASE_URL = "https://storage.googleapis.com/cardboard-dpdb/dpdb.json";
|
|
17243
|
+
var SCREENSIZE_MIN = 3;
|
|
17244
|
+
var SCREENSIZE_MAX = 20;
|
|
17245
|
+
var cache = /* @__PURE__ */ new Map();
|
|
17246
|
+
function normalizeDatabaseUrl(value) {
|
|
17247
|
+
if (value === null || value === "") {
|
|
17248
|
+
return null;
|
|
17249
|
+
}
|
|
17250
|
+
if (value === void 0) {
|
|
17251
|
+
return DEFAULT_WEBVR_DATABASE_URL;
|
|
17252
|
+
}
|
|
17253
|
+
const trimmed = value.trim();
|
|
17254
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
17255
|
+
}
|
|
17256
|
+
function physicalResolution(screenWidth, screenHeight, devicePixelRatio) {
|
|
17257
|
+
const ratio = Number.isFinite(devicePixelRatio) && devicePixelRatio > 0 ? devicePixelRatio : 1;
|
|
17258
|
+
return [
|
|
17259
|
+
Math.round(Math.max(0, screenWidth) * ratio),
|
|
17260
|
+
Math.round(Math.max(0, screenHeight) * ratio)
|
|
17261
|
+
];
|
|
17262
|
+
}
|
|
17263
|
+
function resolutionsMatch(rule, physical) {
|
|
17264
|
+
const [rw, rh] = rule;
|
|
17265
|
+
const [pw, ph] = physical;
|
|
17266
|
+
return rw === pw && rh === ph || rw === ph && rh === pw;
|
|
17267
|
+
}
|
|
17268
|
+
function ruleMatches(rule, input, physical) {
|
|
17269
|
+
if (typeof rule.ua === "string") {
|
|
17270
|
+
return input.userAgent.includes(rule.ua);
|
|
17271
|
+
}
|
|
17272
|
+
if (Array.isArray(rule.res) && rule.res.length === 2 && typeof rule.res[0] === "number" && typeof rule.res[1] === "number") {
|
|
17273
|
+
return resolutionsMatch(
|
|
17274
|
+
[rule.res[0], rule.res[1]],
|
|
17275
|
+
physical
|
|
17276
|
+
);
|
|
17277
|
+
}
|
|
17278
|
+
return false;
|
|
17279
|
+
}
|
|
17280
|
+
function deviceMatches(device, input) {
|
|
17281
|
+
const rules = device.rules;
|
|
17282
|
+
if (!Array.isArray(rules) || rules.length === 0) {
|
|
17283
|
+
return false;
|
|
17284
|
+
}
|
|
17285
|
+
const physical = physicalResolution(
|
|
17286
|
+
input.screenWidth,
|
|
17287
|
+
input.screenHeight,
|
|
17288
|
+
input.devicePixelRatio
|
|
17289
|
+
);
|
|
17290
|
+
return rules.some(
|
|
17291
|
+
(rule) => rule !== null && typeof rule === "object" && ruleMatches(rule, input, physical)
|
|
17292
|
+
);
|
|
17293
|
+
}
|
|
17294
|
+
function diagonalInchesFromDpi(dpi, physicalWidth, physicalHeight) {
|
|
17295
|
+
const shortPx = Math.min(physicalWidth, physicalHeight);
|
|
17296
|
+
const longPx = Math.max(physicalWidth, physicalHeight);
|
|
17297
|
+
if (!(shortPx > 0 && longPx > 0)) {
|
|
17298
|
+
return null;
|
|
17299
|
+
}
|
|
17300
|
+
let dpiX;
|
|
17301
|
+
let dpiY;
|
|
17302
|
+
if (typeof dpi === "number") {
|
|
17303
|
+
if (!(Number.isFinite(dpi) && dpi > 0)) {
|
|
17304
|
+
return null;
|
|
17305
|
+
}
|
|
17306
|
+
dpiX = dpi;
|
|
17307
|
+
dpiY = dpi;
|
|
17308
|
+
} else if (Array.isArray(dpi) && dpi.length >= 1) {
|
|
17309
|
+
const first = dpi[0];
|
|
17310
|
+
const second = dpi.length >= 2 ? dpi[1] : first;
|
|
17311
|
+
if (typeof first !== "number" || typeof second !== "number" || !(Number.isFinite(first) && first > 0) || !(Number.isFinite(second) && second > 0)) {
|
|
17312
|
+
return null;
|
|
17313
|
+
}
|
|
17314
|
+
dpiX = first;
|
|
17315
|
+
dpiY = second;
|
|
17316
|
+
} else {
|
|
17317
|
+
return null;
|
|
17318
|
+
}
|
|
17319
|
+
const widthIn = shortPx / dpiX;
|
|
17320
|
+
const heightIn = longPx / dpiY;
|
|
17321
|
+
const diagonal = Math.sqrt(widthIn * widthIn + heightIn * heightIn);
|
|
17322
|
+
if (!Number.isFinite(diagonal) || diagonal < SCREENSIZE_MIN || diagonal > SCREENSIZE_MAX) {
|
|
17323
|
+
return null;
|
|
17324
|
+
}
|
|
17325
|
+
return Math.round(diagonal * 10) / 10;
|
|
17326
|
+
}
|
|
17327
|
+
function matchDpdbDevice(document2, input) {
|
|
17328
|
+
const devices = document2.devices;
|
|
17329
|
+
if (!Array.isArray(devices)) {
|
|
17330
|
+
return null;
|
|
17331
|
+
}
|
|
17332
|
+
const physical = physicalResolution(
|
|
17333
|
+
input.screenWidth,
|
|
17334
|
+
input.screenHeight,
|
|
17335
|
+
input.devicePixelRatio
|
|
17336
|
+
);
|
|
17337
|
+
for (const device of devices) {
|
|
17338
|
+
if (!deviceMatches(device, input)) {
|
|
17339
|
+
continue;
|
|
17340
|
+
}
|
|
17341
|
+
if (device.dpi === void 0) {
|
|
17342
|
+
continue;
|
|
17343
|
+
}
|
|
17344
|
+
const screensizeInches = diagonalInchesFromDpi(
|
|
17345
|
+
device.dpi,
|
|
17346
|
+
physical[0],
|
|
17347
|
+
physical[1]
|
|
17348
|
+
);
|
|
17349
|
+
if (screensizeInches === null) {
|
|
17350
|
+
continue;
|
|
17351
|
+
}
|
|
17352
|
+
return { device, screensizeInches };
|
|
17353
|
+
}
|
|
17354
|
+
return null;
|
|
17355
|
+
}
|
|
17356
|
+
function readDpdbMatchInput(globalObject = globalThis) {
|
|
17357
|
+
const navigatorObject = globalObject.navigator;
|
|
17358
|
+
const screenObject = globalObject.screen;
|
|
17359
|
+
if (!navigatorObject || !screenObject) {
|
|
17360
|
+
return null;
|
|
17361
|
+
}
|
|
17362
|
+
const width = screenObject.width;
|
|
17363
|
+
const height = screenObject.height;
|
|
17364
|
+
if (typeof width !== "number" || typeof height !== "number" || !(width > 0 && height > 0)) {
|
|
17365
|
+
return null;
|
|
17366
|
+
}
|
|
17367
|
+
const dpr = typeof globalObject.devicePixelRatio === "number" ? globalObject.devicePixelRatio : 1;
|
|
17368
|
+
return {
|
|
17369
|
+
userAgent: navigatorObject.userAgent ?? "",
|
|
17370
|
+
screenWidth: width,
|
|
17371
|
+
screenHeight: height,
|
|
17372
|
+
devicePixelRatio: dpr
|
|
17373
|
+
};
|
|
17374
|
+
}
|
|
17375
|
+
async function fetchDpdbDocument(url) {
|
|
17376
|
+
try {
|
|
17377
|
+
const response = await fetch(url, {
|
|
17378
|
+
credentials: "omit",
|
|
17379
|
+
mode: "cors"
|
|
17380
|
+
});
|
|
17381
|
+
if (!response.ok) {
|
|
17382
|
+
return null;
|
|
17383
|
+
}
|
|
17384
|
+
const data = await response.json();
|
|
17385
|
+
if (data === null || typeof data !== "object" || !("devices" in data) || !Array.isArray(data.devices)) {
|
|
17386
|
+
return null;
|
|
17387
|
+
}
|
|
17388
|
+
return data;
|
|
17389
|
+
} catch {
|
|
17390
|
+
return null;
|
|
17391
|
+
}
|
|
17392
|
+
}
|
|
17393
|
+
function loadDpdbDocument(url) {
|
|
17394
|
+
const existing = cache.get(url);
|
|
17395
|
+
if (existing) {
|
|
17396
|
+
return existing;
|
|
17397
|
+
}
|
|
17398
|
+
const pending = fetchDpdbDocument(url).then((document2) => {
|
|
17399
|
+
if (!document2) {
|
|
17400
|
+
cache.delete(url);
|
|
17401
|
+
}
|
|
17402
|
+
return document2;
|
|
17403
|
+
});
|
|
17404
|
+
cache.set(url, pending);
|
|
17405
|
+
return pending;
|
|
17406
|
+
}
|
|
17407
|
+
async function resolveScreensizeFromDpdb(databaseUrl, input = readDpdbMatchInput()) {
|
|
17408
|
+
const url = normalizeDatabaseUrl(databaseUrl);
|
|
17409
|
+
if (!url || !input) {
|
|
17410
|
+
return null;
|
|
17411
|
+
}
|
|
17412
|
+
const document2 = await loadDpdbDocument(url);
|
|
17413
|
+
if (!document2) {
|
|
17414
|
+
return null;
|
|
17415
|
+
}
|
|
17416
|
+
return matchDpdbDevice(document2, input)?.screensizeInches ?? null;
|
|
17417
|
+
}
|
|
17418
|
+
|
|
16998
17419
|
// src/webvr/presentation.ts
|
|
16999
17420
|
var PRESENTATION_PROPERTIES = [
|
|
17000
17421
|
"background",
|
|
@@ -17152,7 +17573,7 @@ function subscribeWebVRPresentationExit(element, onExit) {
|
|
|
17152
17573
|
|
|
17153
17574
|
// src/webvr/reticle.tsx
|
|
17154
17575
|
var import_fiber28 = require("@react-three/fiber");
|
|
17155
|
-
var
|
|
17576
|
+
var import_react58 = require("react");
|
|
17156
17577
|
var import_three38 = require("three");
|
|
17157
17578
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
17158
17579
|
var CENTER_NDC = new import_three38.Vector2(0, 0);
|
|
@@ -17240,13 +17661,13 @@ function WebVRReticle({
|
|
|
17240
17661
|
scale = RETICLE_SCALE,
|
|
17241
17662
|
visible
|
|
17242
17663
|
}) {
|
|
17243
|
-
const groupRef = (0,
|
|
17244
|
-
const ringMeshRef = (0,
|
|
17245
|
-
const directionRef = (0,
|
|
17246
|
-
const raycasterRef = (0,
|
|
17247
|
-
const hoveredRef = (0,
|
|
17248
|
-
const dwellRef = (0,
|
|
17249
|
-
const clickedRef = (0,
|
|
17664
|
+
const groupRef = (0, import_react58.useRef)(null);
|
|
17665
|
+
const ringMeshRef = (0, import_react58.useRef)(null);
|
|
17666
|
+
const directionRef = (0, import_react58.useRef)(new import_three38.Vector3());
|
|
17667
|
+
const raycasterRef = (0, import_react58.useRef)(new import_three38.Raycaster());
|
|
17668
|
+
const hoveredRef = (0, import_react58.useRef)(null);
|
|
17669
|
+
const dwellRef = (0, import_react58.useRef)(0);
|
|
17670
|
+
const clickedRef = (0, import_react58.useRef)(false);
|
|
17250
17671
|
const { camera, gl, scene } = (0, import_fiber28.useThree)();
|
|
17251
17672
|
(0, import_fiber28.useFrame)((_, deltaSeconds) => {
|
|
17252
17673
|
const group = groupRef.current;
|
|
@@ -17409,9 +17830,43 @@ function WebVRReticle({
|
|
|
17409
17830
|
|
|
17410
17831
|
// src/webvr/stereo.tsx
|
|
17411
17832
|
var import_fiber29 = require("@react-three/fiber");
|
|
17412
|
-
var
|
|
17833
|
+
var import_react59 = require("react");
|
|
17413
17834
|
var import_three39 = require("three");
|
|
17414
17835
|
|
|
17836
|
+
// src/webvr/lens-center.ts
|
|
17837
|
+
function physicalScreenFromDiagonal(screensizeInches, displayAspect) {
|
|
17838
|
+
if (!(Number.isFinite(screensizeInches) && screensizeInches > 0 && Number.isFinite(displayAspect) && displayAspect > 0)) {
|
|
17839
|
+
return null;
|
|
17840
|
+
}
|
|
17841
|
+
const diagonalMm = screensizeInches * 25.4;
|
|
17842
|
+
const heightMm = diagonalMm / Math.sqrt(displayAspect * displayAspect + 1);
|
|
17843
|
+
const widthMm = heightMm * displayAspect;
|
|
17844
|
+
if (!(heightMm > 0 && widthMm > 0)) {
|
|
17845
|
+
return null;
|
|
17846
|
+
}
|
|
17847
|
+
return { widthMm, heightMm };
|
|
17848
|
+
}
|
|
17849
|
+
function computeStereoLensCenters(profile, screensize, displayAspect) {
|
|
17850
|
+
const zero = { left: { x: 0, y: 0 }, right: { x: 0, y: 0 } };
|
|
17851
|
+
if (screensize === "auto") {
|
|
17852
|
+
return zero;
|
|
17853
|
+
}
|
|
17854
|
+
const screen = physicalScreenFromDiagonal(screensize, displayAspect);
|
|
17855
|
+
if (!screen) {
|
|
17856
|
+
return zero;
|
|
17857
|
+
}
|
|
17858
|
+
const halfEyeWidthMm = screen.widthMm / 4;
|
|
17859
|
+
const ipdMm = Number.isFinite(profile.ipdMm) ? profile.ipdMm : 60;
|
|
17860
|
+
const x = halfEyeWidthMm > 0 ? (halfEyeWidthMm - ipdMm / 2) / halfEyeWidthMm : 0;
|
|
17861
|
+
const trayDistanceMm = typeof profile.trayDistanceMm === "number" && Number.isFinite(profile.trayDistanceMm) && profile.trayDistanceMm > 0 ? profile.trayDistanceMm : 0;
|
|
17862
|
+
const y = trayDistanceMm > 0 && screen.heightMm > 0 ? 2 * trayDistanceMm / screen.heightMm - 1 : 0;
|
|
17863
|
+
const clampUnit = (value) => Math.max(-1, Math.min(1, Number.isFinite(value) ? value : 0));
|
|
17864
|
+
return {
|
|
17865
|
+
left: { x: clampUnit(x), y: clampUnit(y) },
|
|
17866
|
+
right: { x: clampUnit(-x), y: clampUnit(y) }
|
|
17867
|
+
};
|
|
17868
|
+
}
|
|
17869
|
+
|
|
17415
17870
|
// src/webvr/stereo-disparity.ts
|
|
17416
17871
|
var WEBVR_PANORAMA_VIRTUAL_DISTANCE_M = 2;
|
|
17417
17872
|
function panoramaStereoHalfAngle(ipdMm, virtualDistanceM = WEBVR_PANORAMA_VIRTUAL_DISTANCE_M) {
|
|
@@ -17427,19 +17882,32 @@ function panoramaStereoToeInYaw(eye, halfAngleRad) {
|
|
|
17427
17882
|
}
|
|
17428
17883
|
|
|
17429
17884
|
// src/webvr/stereo-layout.ts
|
|
17430
|
-
|
|
17885
|
+
var DEFAULT_WEBVR_OVERSAMPLING = 1;
|
|
17886
|
+
var MIN_WEBVR_OVERSAMPLING = 0.5;
|
|
17887
|
+
var MAX_WEBVR_OVERSAMPLING = 2;
|
|
17888
|
+
function clampWebVROversampling(value) {
|
|
17889
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
17890
|
+
return DEFAULT_WEBVR_OVERSAMPLING;
|
|
17891
|
+
}
|
|
17892
|
+
return Math.max(
|
|
17893
|
+
MIN_WEBVR_OVERSAMPLING,
|
|
17894
|
+
Math.min(MAX_WEBVR_OVERSAMPLING, value)
|
|
17895
|
+
);
|
|
17896
|
+
}
|
|
17897
|
+
function computeStereoLayout(logicalWidth, logicalHeight, pixelRatio, oversampling = DEFAULT_WEBVR_OVERSAMPLING) {
|
|
17431
17898
|
const fullWidth = Math.max(2, Math.floor(logicalWidth));
|
|
17432
17899
|
const fullHeight = Math.max(1, Math.floor(logicalHeight));
|
|
17433
17900
|
const leftWidth = Math.max(1, Math.floor(fullWidth / 2));
|
|
17434
17901
|
const rightWidth = Math.max(1, fullWidth - leftWidth);
|
|
17435
17902
|
const ratio = Number.isFinite(pixelRatio) && pixelRatio > 0 ? pixelRatio : 1;
|
|
17903
|
+
const scale = clampWebVROversampling(oversampling);
|
|
17436
17904
|
return {
|
|
17437
17905
|
fullWidth,
|
|
17438
17906
|
fullHeight,
|
|
17439
17907
|
left: { width: leftWidth, height: fullHeight, offsetX: 0 },
|
|
17440
17908
|
right: { width: rightWidth, height: fullHeight, offsetX: leftWidth },
|
|
17441
|
-
renderTargetWidth: Math.max(1, Math.floor(leftWidth * ratio)),
|
|
17442
|
-
renderTargetHeight: Math.max(1, Math.floor(fullHeight * ratio)),
|
|
17909
|
+
renderTargetWidth: Math.max(1, Math.floor(leftWidth * ratio * scale)),
|
|
17910
|
+
renderTargetHeight: Math.max(1, Math.floor(fullHeight * ratio * scale)),
|
|
17443
17911
|
stereoAspect: leftWidth / fullWidth
|
|
17444
17912
|
};
|
|
17445
17913
|
}
|
|
@@ -17456,12 +17924,13 @@ void main() {
|
|
|
17456
17924
|
var fragmentShader = `
|
|
17457
17925
|
uniform sampler2D sourceTexture;
|
|
17458
17926
|
uniform vec2 distortion;
|
|
17927
|
+
uniform vec2 lensCenter;
|
|
17459
17928
|
varying vec2 vUv;
|
|
17460
17929
|
void main() {
|
|
17461
|
-
vec2 centered = vUv * 2.0 - 1.0;
|
|
17930
|
+
vec2 centered = vUv * 2.0 - 1.0 - lensCenter;
|
|
17462
17931
|
float radius2 = dot(centered, centered);
|
|
17463
17932
|
float scale = 1.0 + distortion.x * radius2 + distortion.y * radius2 * radius2;
|
|
17464
|
-
vec2 sourceUv = centered * scale * 0.5 + 0.5;
|
|
17933
|
+
vec2 sourceUv = (centered * scale + lensCenter) * 0.5 + 0.5;
|
|
17465
17934
|
if (sourceUv.x < 0.0 || sourceUv.x > 1.0 || sourceUv.y < 0.0 || sourceUv.y > 1.0) {
|
|
17466
17935
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
|
17467
17936
|
} else {
|
|
@@ -17481,6 +17950,7 @@ function createDistortionResources() {
|
|
|
17481
17950
|
fragmentShader,
|
|
17482
17951
|
uniforms: {
|
|
17483
17952
|
distortion: { value: new import_three39.Vector2() },
|
|
17953
|
+
lensCenter: { value: new import_three39.Vector2() },
|
|
17484
17954
|
sourceTexture: { value: target.texture }
|
|
17485
17955
|
},
|
|
17486
17956
|
vertexShader
|
|
@@ -17497,12 +17967,27 @@ function createDistortionResources() {
|
|
|
17497
17967
|
target
|
|
17498
17968
|
};
|
|
17499
17969
|
}
|
|
17500
|
-
function
|
|
17970
|
+
function applyEyeViewOffset(eyeCamera, eye, center) {
|
|
17971
|
+
const fullWidth = eye.width;
|
|
17972
|
+
const fullHeight = eye.height;
|
|
17973
|
+
const offsetX = ((center.x + 1) / 2 - 0.5) * fullWidth;
|
|
17974
|
+
const offsetY = (0.5 - (center.y + 1) / 2) * fullHeight;
|
|
17975
|
+
eyeCamera.setViewOffset(
|
|
17976
|
+
fullWidth,
|
|
17977
|
+
fullHeight,
|
|
17978
|
+
offsetX,
|
|
17979
|
+
offsetY,
|
|
17980
|
+
fullWidth,
|
|
17981
|
+
fullHeight
|
|
17982
|
+
);
|
|
17983
|
+
}
|
|
17984
|
+
function syncStereoCameras(stereo, camera, profile, screensize, oversampling, size, gl) {
|
|
17501
17985
|
gl.getSize(size);
|
|
17502
17986
|
const layout = computeStereoLayout(
|
|
17503
17987
|
size.x,
|
|
17504
17988
|
size.y,
|
|
17505
|
-
gl.getPixelRatio()
|
|
17989
|
+
gl.getPixelRatio(),
|
|
17990
|
+
oversampling
|
|
17506
17991
|
);
|
|
17507
17992
|
const screenToLensMm = profile.screenToLensMm ?? 42;
|
|
17508
17993
|
const displayAspect = layout.fullWidth / layout.fullHeight;
|
|
@@ -17521,35 +18006,41 @@ function syncStereoCameras(stereo, camera, profile, screensize, size, gl) {
|
|
|
17521
18006
|
TOE_IN.makeRotationY(panoramaStereoToeInYaw("right", halfAngle));
|
|
17522
18007
|
stereo.cameraR.matrix.multiply(TOE_IN);
|
|
17523
18008
|
stereo.cameraR.matrixWorldNeedsUpdate = true;
|
|
18009
|
+
const centers = computeStereoLensCenters(profile, screensize, displayAspect);
|
|
18010
|
+
applyEyeViewOffset(stereo.cameraL, layout.left, centers.left);
|
|
18011
|
+
applyEyeViewOffset(stereo.cameraR, layout.right, centers.right);
|
|
17524
18012
|
stereo.cameraL.updateMatrixWorld(true);
|
|
17525
18013
|
stereo.cameraR.updateMatrixWorld(true);
|
|
17526
|
-
return layout;
|
|
18014
|
+
return { layout, centers };
|
|
17527
18015
|
}
|
|
17528
18016
|
function WebVRStereoRenderer({
|
|
17529
18017
|
mode,
|
|
18018
|
+
oversampling = 1,
|
|
17530
18019
|
profile,
|
|
17531
18020
|
screensize
|
|
17532
18021
|
}) {
|
|
17533
18022
|
const { camera, gl } = (0, import_fiber29.useThree)();
|
|
17534
|
-
const runtime = (0,
|
|
17535
|
-
const fallbackStereoRef = (0,
|
|
18023
|
+
const runtime = (0, import_react59.useContext)(WebVRRuntimeContext);
|
|
18024
|
+
const fallbackStereoRef = (0, import_react59.useRef)(null);
|
|
17536
18025
|
if (!fallbackStereoRef.current) {
|
|
17537
18026
|
fallbackStereoRef.current = new import_three39.StereoCamera();
|
|
17538
18027
|
}
|
|
17539
18028
|
const stereo = runtime?.stereoView.stereo ?? fallbackStereoRef.current;
|
|
17540
|
-
const stereoRef = (0,
|
|
18029
|
+
const stereoRef = (0, import_react59.useRef)(stereo);
|
|
17541
18030
|
stereoRef.current = stereo;
|
|
17542
|
-
const resources = (0,
|
|
17543
|
-
const sizeRef = (0,
|
|
17544
|
-
const viewportRef = (0,
|
|
17545
|
-
const scissorRef = (0,
|
|
17546
|
-
const originalFovRef = (0,
|
|
17547
|
-
const stereoActiveRef = (0,
|
|
17548
|
-
const profileRef = (0,
|
|
17549
|
-
const screensizeRef = (0,
|
|
18031
|
+
const resources = (0, import_react59.useMemo)(createDistortionResources, []);
|
|
18032
|
+
const sizeRef = (0, import_react59.useRef)(new import_three39.Vector2());
|
|
18033
|
+
const viewportRef = (0, import_react59.useRef)(new import_three39.Vector4());
|
|
18034
|
+
const scissorRef = (0, import_react59.useRef)(new import_three39.Vector4());
|
|
18035
|
+
const originalFovRef = (0, import_react59.useRef)(null);
|
|
18036
|
+
const stereoActiveRef = (0, import_react59.useRef)(false);
|
|
18037
|
+
const profileRef = (0, import_react59.useRef)(profile);
|
|
18038
|
+
const screensizeRef = (0, import_react59.useRef)(screensize);
|
|
18039
|
+
const oversamplingRef = (0, import_react59.useRef)(clampWebVROversampling(oversampling));
|
|
17550
18040
|
profileRef.current = profile;
|
|
17551
18041
|
screensizeRef.current = screensize;
|
|
17552
|
-
(
|
|
18042
|
+
oversamplingRef.current = clampWebVROversampling(oversampling);
|
|
18043
|
+
(0, import_react59.useEffect)(
|
|
17553
18044
|
() => () => {
|
|
17554
18045
|
resources.geometry.dispose();
|
|
17555
18046
|
resources.material.dispose();
|
|
@@ -17557,7 +18048,7 @@ function WebVRStereoRenderer({
|
|
|
17557
18048
|
},
|
|
17558
18049
|
[resources]
|
|
17559
18050
|
);
|
|
17560
|
-
(0,
|
|
18051
|
+
(0, import_react59.useEffect)(() => {
|
|
17561
18052
|
const originalRender = gl.render.bind(gl);
|
|
17562
18053
|
gl.render = (sceneToRender, cameraToRender) => {
|
|
17563
18054
|
if (!stereoActiveRef.current || !(cameraToRender instanceof import_three39.PerspectiveCamera)) {
|
|
@@ -17569,11 +18060,12 @@ function WebVRStereoRenderer({
|
|
|
17569
18060
|
if (originalFovRef.current === null) {
|
|
17570
18061
|
originalFovRef.current = cameraToRender.fov;
|
|
17571
18062
|
}
|
|
17572
|
-
const layout = syncStereoCameras(
|
|
18063
|
+
const { layout, centers } = syncStereoCameras(
|
|
17573
18064
|
stereoRef.current,
|
|
17574
18065
|
cameraToRender,
|
|
17575
18066
|
currentProfile,
|
|
17576
18067
|
currentScreensize,
|
|
18068
|
+
oversamplingRef.current,
|
|
17577
18069
|
sizeRef.current,
|
|
17578
18070
|
gl
|
|
17579
18071
|
);
|
|
@@ -17585,7 +18077,7 @@ function WebVRStereoRenderer({
|
|
|
17585
18077
|
gl.getScissor(scissorRef.current);
|
|
17586
18078
|
gl.autoClear = true;
|
|
17587
18079
|
gl.setScissorTest(true);
|
|
17588
|
-
const renderEye = (eyeCamera, eye) => {
|
|
18080
|
+
const renderEye = (eyeCamera, eye, center) => {
|
|
17589
18081
|
if (hasDistortion) {
|
|
17590
18082
|
if (resources.target.width !== layout.renderTargetWidth || resources.target.height !== layout.renderTargetHeight) {
|
|
17591
18083
|
resources.target.setSize(
|
|
@@ -17602,6 +18094,7 @@ function WebVRStereoRenderer({
|
|
|
17602
18094
|
currentProfile.k1,
|
|
17603
18095
|
currentProfile.k2
|
|
17604
18096
|
);
|
|
18097
|
+
resources.material.uniforms.lensCenter?.value.set(center.x, center.y);
|
|
17605
18098
|
originalRender(resources.scene, resources.camera);
|
|
17606
18099
|
return;
|
|
17607
18100
|
}
|
|
@@ -17610,8 +18103,8 @@ function WebVRStereoRenderer({
|
|
|
17610
18103
|
gl.setScissor(eye.offsetX, 0, eye.width, eye.height);
|
|
17611
18104
|
originalRender(sceneToRender, eyeCamera);
|
|
17612
18105
|
};
|
|
17613
|
-
renderEye(stereoRef.current.cameraL, layout.left);
|
|
17614
|
-
renderEye(stereoRef.current.cameraR, layout.right);
|
|
18106
|
+
renderEye(stereoRef.current.cameraL, layout.left, centers.left);
|
|
18107
|
+
renderEye(stereoRef.current.cameraR, layout.right, centers.right);
|
|
17615
18108
|
gl.setRenderTarget(previousTarget);
|
|
17616
18109
|
gl.setViewport(viewportRef.current);
|
|
17617
18110
|
gl.setScissor(scissorRef.current);
|
|
@@ -17622,7 +18115,7 @@ function WebVRStereoRenderer({
|
|
|
17622
18115
|
gl.render = originalRender;
|
|
17623
18116
|
};
|
|
17624
18117
|
}, [gl, resources]);
|
|
17625
|
-
(0,
|
|
18118
|
+
(0, import_react59.useEffect)(
|
|
17626
18119
|
() => () => {
|
|
17627
18120
|
if (runtime) {
|
|
17628
18121
|
runtime.stereoView.active = false;
|
|
@@ -17642,6 +18135,7 @@ function WebVRStereoRenderer({
|
|
|
17642
18135
|
camera,
|
|
17643
18136
|
profileRef.current,
|
|
17644
18137
|
screensizeRef.current,
|
|
18138
|
+
oversamplingRef.current,
|
|
17645
18139
|
sizeRef.current,
|
|
17646
18140
|
gl
|
|
17647
18141
|
);
|
|
@@ -17657,7 +18151,7 @@ function WebVRStereoRenderer({
|
|
|
17657
18151
|
}
|
|
17658
18152
|
|
|
17659
18153
|
// src/webvr/pointerlock.ts
|
|
17660
|
-
var
|
|
18154
|
+
var import_react60 = require("react");
|
|
17661
18155
|
var POINTER_LOCK_CURSOR_ID = "webvr:pointerlock";
|
|
17662
18156
|
async function requestWebVRPointerLock(element) {
|
|
17663
18157
|
if (typeof document === "undefined") {
|
|
@@ -17690,11 +18184,11 @@ function exitWebVRPointerLock(element) {
|
|
|
17690
18184
|
}
|
|
17691
18185
|
function useWebVRPointerLock(enabled, element) {
|
|
17692
18186
|
const cursor = usePanoCursor();
|
|
17693
|
-
const cursorRef = (0,
|
|
17694
|
-
const enabledRef = (0,
|
|
18187
|
+
const cursorRef = (0, import_react60.useRef)(cursor);
|
|
18188
|
+
const enabledRef = (0, import_react60.useRef)(enabled);
|
|
17695
18189
|
cursorRef.current = cursor;
|
|
17696
18190
|
enabledRef.current = enabled;
|
|
17697
|
-
(0,
|
|
18191
|
+
(0, import_react60.useEffect)(() => {
|
|
17698
18192
|
if (!enabled || !element) {
|
|
17699
18193
|
return;
|
|
17700
18194
|
}
|
|
@@ -17724,7 +18218,7 @@ function useWebVRPointerLock(enabled, element) {
|
|
|
17724
18218
|
}
|
|
17725
18219
|
|
|
17726
18220
|
// src/webvr/wakelock.ts
|
|
17727
|
-
var
|
|
18221
|
+
var import_react61 = require("react");
|
|
17728
18222
|
|
|
17729
18223
|
// src/webvr/wakelock-fallback.ts
|
|
17730
18224
|
var WEBVR_WAKELOCK_FALLBACK_VIDEO_BASE64 = "AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAbBbW9vdgAAAGxtdmhkAAAAAAAAAAAAAAAAAAAD6AAAD4AAAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAxt0cmFrAAAAXHRraGQAAAADAAAAAAAAAAAAAAABAAAAAAAAAggAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAABAAAAAQAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAAIIAAAEAAABAAAAAAKTbWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAAAyAAAAGgBVxAAAAAAALWhkbHIAAAAAAAAAAHZpZGUAAAAAAAAAAAAAAABWaWRlb0hhbmRsZXIAAAACPm1pbmYAAAAUdm1oZAAAAAEAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAf5zdGJsAAAAvnN0c2QAAAAAAAAAAQAAAK5hdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAABAAEABIAAAASAAAAAAAAAABFUxhdmM2Mi4xMS4xMDAgbGlieDI2NAAAAAAAAAAAAAAAGP//AAAANGF2Y0MBZAAK/+EAF2dkAAqs2V7ARAAAAwAEAAADAMg8SJZYAQAGaOvjyyLA/fj4AAAAABBwYXNwAAAAAQAAAAEAAAAUYnRydAAAAAAAADQ5AAAAAAAAABhzdHRzAAAAAAAAAAEAAAANAAACAAAAABRzdHNzAAAAAAAAAAEAAAABAAAAeGN0dHMAAAAAAAAADQAAAAEAAAQAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAKHN0c2MAAAAAAAAAAgAAAAEAAAADAAAAAQAAAAUAAAABAAAAAQAAAEhzdHN6AAAAAAAAAAAAAAANAAACxQAAAAwAAAAMAAAADAAAAAwAAAASAAAADgAAAAwAAAAMAAAAEgAAAA4AAAAMAAAADAAAACRzdGNvAAAAAAAAAAUAAAcGAAAJ5wAAChUAAAo/AAAKbwAAAtF0cmFrAAAAXHRraGQAAAADAAAAAAAAAAAAAAACAAAAAAAAD4AAAAAAAAAAAAAAAAEBAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAA+AAAAEAAABAAAAAAJJbWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAAAfQAAAgABVxAAAAAAALWhkbHIAAAAAAAAAAHNvdW4AAAAAAAAAAAAAAABTb3VuZEhhbmRsZXIAAAAB9G1pbmYAAAAQc21oZAAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAABuHN0YmwAAAB+c3RzZAAAAAAAAAABAAAAbm1wNGEAAAAAAAAAAQAAAAAAAAAAAAEAEAAAAAAfQAAAAAAANmVzZHMAAAAAA4CAgCUAAgAEgICAF0AVAAAAAAAfQAAAARsFgICABRWIVuUABoCAgAECAAAAFGJ0cnQAAAAAAAAfQAAAARsAAAAYc3R0cwAAAAAAAAABAAAAIAAABAAAAAAoc3RzYwAAAAAAAAACAAAAAQAAAAEAAAABAAAABgAAABsAAAABAAAAlHN0c3oAAAAAAAAAAAAAACAAAAAVAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAChzdGNvAAAAAAAAAAYAAAbxAAAJ4wAAChEAAAo7AAAKawAACnsAAAAac2dwZAEAAAByb2xsAAAAAgAAAAH//wAAABxzYmdwAAAAAHJvbGwAAAABAAAAIAAAAAEAAABhdWR0YQAAAFltZXRhAAAAAAAAACFoZGxyAAAAAAAAAABtZGlyYXBwbAAAAAAAAAAAAAAAACxpbHN0AAAAJKl0b28AAAAcZGF0YQAAAAEAAAAATGF2ZjYyLjMuMTAwAAAACGZyZWUAAAP+bWRhdN4CAExhdmM2Mi4xMS4xMDAAAjBADgAAAq4GBf//qtxF6b3m2Ui3lizYINkj7u94MjY0IC0gY29yZSAxNjUgcjMyMjIgYjM1NjA1YSAtIEguMjY0L01QRUctNCBBVkMgY29kZWMgLSBDb3B5bGVmdCAyMDAzLTIwMjUgLSBodHRwOi8vd3d3LnZpZGVvbGFuLm9yZy94MjY0Lmh0bWwgLSBvcHRpb25zOiBjYWJhYz0xIHJlZj0zIGRlYmxvY2s9MTowOjAgYW5hbHlzZT0weDM6MHgxMTMgbWU9aGV4IHN1Ym1lPTcgcHN5PTEgcHN5X3JkPTEuMDA6MC4wMCBtaXhlZF9yZWY9MSBtZV9yYW5nZT0xNiBjaHJvbWFfbWU9MSB0cmVsbGlzPTEgOHg4ZGN0PTEgY3FtPTAgZGVhZHpvbmU9MjEsMTEgZmFzdF9wc2tpcD0xIGNocm9tYV9xcF9vZmZzZXQ9LTIgdGhyZWFkcz0xIGxvb2thaGVhZF90aHJlYWRzPTEgc2xpY2VkX3RocmVhZHM9MCBucj0wIGRlY2ltYXRlPTEgaW50ZXJsYWNlZD0wIGJsdXJheV9jb21wYXQ9MCBjb25zdHJhaW5lZF9pbnRyYT0wIGJmcmFtZXM9MyBiX3B5cmFtaWQ9MiBiX2FkYXB0PTEgYl9iaWFzPTAgZGlyZWN0PTEgd2VpZ2h0Yj0xIG9wZW5fZ29wPTAgd2VpZ2h0cD0yIGtleWludD0yNTAga2V5aW50X21pbj0yNSBzY2VuZWN1dD00MCBpbnRyYV9yZWZyZXNoPTAgcmNfbG9va2FoZWFkPTQwIHJjPWNyZiBtYnRyZWU9MSBjcmY9MjMuMCBxY29tcD0wLjYwIHFwbWluPTAgcXBtYXg9NjkgcXBzdGVwPTQgaXBfcmF0aW89MS40MCBhcT0xOjEuMDAAgAAAAA9liIQAO//+906/AptUwmEAAAAIQZokbEN//uAAAAAIQZ5CeIX/wYEBGCAHAAAACAGeYXRCv8SAAAAACAGeY2pCv8SBAAAADkGaaEmoQWiZTAhn//7hARggBwAAAApBnoZFESwv/8GBAAAACAGepXRCv8SBAAAACAGep2pCv8SAARggBwAAAA5BmqxJqEFsmUwIV//+wAAAAApBnspFFSwv/8GBAAAACAGe6XRCv8SAARggBwAAAAgBnutqQr/EgAEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBw==";
|
|
@@ -17853,7 +18347,7 @@ function releaseWebVRWakeLock() {
|
|
|
17853
18347
|
stopFallbackVideo();
|
|
17854
18348
|
}
|
|
17855
18349
|
function useWebVRWakeLock(enabled) {
|
|
17856
|
-
(0,
|
|
18350
|
+
(0, import_react61.useEffect)(() => {
|
|
17857
18351
|
if (!enabled) {
|
|
17858
18352
|
return;
|
|
17859
18353
|
}
|
|
@@ -17871,6 +18365,42 @@ function useWebVRWakeLock(enabled) {
|
|
|
17871
18365
|
}, [enabled]);
|
|
17872
18366
|
}
|
|
17873
18367
|
|
|
18368
|
+
// src/webvr/xr-quality.ts
|
|
18369
|
+
function clampWebVRFoveation(value) {
|
|
18370
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
18371
|
+
return void 0;
|
|
18372
|
+
}
|
|
18373
|
+
return Math.max(0, Math.min(1, value));
|
|
18374
|
+
}
|
|
18375
|
+
function resolveWebVRFrameRateOption(frameRate) {
|
|
18376
|
+
if (frameRate === void 0) {
|
|
18377
|
+
return void 0;
|
|
18378
|
+
}
|
|
18379
|
+
if (frameRate === "low" || frameRate === "mid" || frameRate === "high") {
|
|
18380
|
+
return frameRate;
|
|
18381
|
+
}
|
|
18382
|
+
if (typeof frameRate !== "number" || !Number.isFinite(frameRate)) {
|
|
18383
|
+
return void 0;
|
|
18384
|
+
}
|
|
18385
|
+
const target = frameRate;
|
|
18386
|
+
return (rates) => {
|
|
18387
|
+
if (rates.length === 0) {
|
|
18388
|
+
return false;
|
|
18389
|
+
}
|
|
18390
|
+
let best = rates[0];
|
|
18391
|
+
let bestDelta = Math.abs(best - target);
|
|
18392
|
+
for (let i = 1; i < rates.length; i += 1) {
|
|
18393
|
+
const candidate = rates[i];
|
|
18394
|
+
const delta = Math.abs(candidate - target);
|
|
18395
|
+
if (delta < bestDelta) {
|
|
18396
|
+
best = candidate;
|
|
18397
|
+
bestDelta = delta;
|
|
18398
|
+
}
|
|
18399
|
+
}
|
|
18400
|
+
return best;
|
|
18401
|
+
};
|
|
18402
|
+
}
|
|
18403
|
+
|
|
17874
18404
|
// src/webvr/webvr.tsx
|
|
17875
18405
|
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
17876
18406
|
function initializeSettings(screensize, profile) {
|
|
@@ -17883,13 +18413,21 @@ function initializeSettings(screensize, profile) {
|
|
|
17883
18413
|
function getViewerElement(canvas) {
|
|
17884
18414
|
return canvas.closest("[data-pano-viewer]") ?? canvas.parentElement ?? canvas;
|
|
17885
18415
|
}
|
|
17886
|
-
var WebVR = (0,
|
|
18416
|
+
var WebVR = (0, import_react62.forwardRef)(function WebVR2({
|
|
17887
18417
|
chrome = true,
|
|
17888
18418
|
mobileVr = true,
|
|
17889
18419
|
desktopSupport = false,
|
|
17890
18420
|
fakeSupport = true,
|
|
17891
18421
|
screensize,
|
|
18422
|
+
databaseUrl,
|
|
17892
18423
|
profile,
|
|
18424
|
+
absolute = false,
|
|
18425
|
+
north = 0,
|
|
18426
|
+
friction = 0,
|
|
18427
|
+
touchSupport = false,
|
|
18428
|
+
oversampling = 1,
|
|
18429
|
+
foveation,
|
|
18430
|
+
frameRate,
|
|
17893
18431
|
cursor = true,
|
|
17894
18432
|
cursorDwellMs = DEFAULT_WEBVR_CURSOR_DWELL_MS,
|
|
17895
18433
|
wakelock = true,
|
|
@@ -17901,24 +18439,40 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
17901
18439
|
onDenied,
|
|
17902
18440
|
onUnknownDevice
|
|
17903
18441
|
}, ref) {
|
|
17904
|
-
const runtime = (0,
|
|
17905
|
-
const controlsRef = (0,
|
|
17906
|
-
const eventBus = (0,
|
|
18442
|
+
const runtime = (0, import_react62.useContext)(WebVRRuntimeContext);
|
|
18443
|
+
const controlsRef = (0, import_react62.useContext)(PanoramaViewContext);
|
|
18444
|
+
const eventBus = (0, import_react62.useContext)(PanoEventBusContext);
|
|
17907
18445
|
const gl = (0, import_fiber30.useThree)((state) => state.gl);
|
|
17908
|
-
const gyroRef = (0,
|
|
17909
|
-
const capabilitiesRef = (0,
|
|
18446
|
+
const gyroRef = (0, import_react62.useRef)(null);
|
|
18447
|
+
const capabilitiesRef = (0, import_react62.useRef)({
|
|
17910
18448
|
mobile: false,
|
|
17911
18449
|
sensor: false,
|
|
17912
18450
|
webxr: false
|
|
17913
18451
|
});
|
|
17914
|
-
const availableRef = (0,
|
|
17915
|
-
const modeRef = (0,
|
|
17916
|
-
const webXRSessionRef = (0,
|
|
17917
|
-
const
|
|
17918
|
-
const
|
|
18452
|
+
const availableRef = (0, import_react62.useRef)(false);
|
|
18453
|
+
const modeRef = (0, import_react62.useRef)(null);
|
|
18454
|
+
const webXRSessionRef = (0, import_react62.useRef)(null);
|
|
18455
|
+
const dpdbRequestIdRef = (0, import_react62.useRef)(0);
|
|
18456
|
+
const databaseUrlRef = (0, import_react62.useRef)(databaseUrl);
|
|
18457
|
+
databaseUrlRef.current = databaseUrl;
|
|
18458
|
+
const oversamplingRef = (0, import_react62.useRef)(clampWebVROversampling(oversampling));
|
|
18459
|
+
oversamplingRef.current = clampWebVROversampling(oversampling);
|
|
18460
|
+
const foveationRef = (0, import_react62.useRef)(clampWebVRFoveation(foveation));
|
|
18461
|
+
foveationRef.current = clampWebVRFoveation(foveation);
|
|
18462
|
+
const frameRateRef = (0, import_react62.useRef)(frameRate);
|
|
18463
|
+
frameRateRef.current = frameRate;
|
|
18464
|
+
const screensizePropRef = (0, import_react62.useRef)(screensize);
|
|
18465
|
+
screensizePropRef.current = screensize;
|
|
18466
|
+
const profilePropRef = (0, import_react62.useRef)(profile);
|
|
18467
|
+
profilePropRef.current = profile;
|
|
18468
|
+
const [mode, setMode] = (0, import_react62.useState)(null);
|
|
18469
|
+
const [settings, setSettings] = (0, import_react62.useState)(
|
|
17919
18470
|
() => initializeSettings(screensize, profile)
|
|
17920
18471
|
);
|
|
17921
|
-
const
|
|
18472
|
+
const [detectedScreensize, setDetectedScreensize] = (0, import_react62.useState)(
|
|
18473
|
+
null
|
|
18474
|
+
);
|
|
18475
|
+
const callbacksRef = (0, import_react62.useRef)({
|
|
17922
18476
|
onAvailable,
|
|
17923
18477
|
onDenied,
|
|
17924
18478
|
onEnterVR,
|
|
@@ -17938,22 +18492,48 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
17938
18492
|
throw new Error("<WebVR> must be rendered inside <PanoViewer>.");
|
|
17939
18493
|
}
|
|
17940
18494
|
const { host, xrStore } = runtime;
|
|
17941
|
-
const resolvedProfile = (0,
|
|
18495
|
+
const resolvedProfile = (0, import_react62.useMemo)(
|
|
17942
18496
|
() => resolveWebVRProfile(profile, settings.profileId),
|
|
17943
18497
|
[profile, settings.profileId]
|
|
17944
18498
|
);
|
|
17945
|
-
const
|
|
18499
|
+
const effectiveScreensize = settings.screensize === "auto" ? detectedScreensize ?? "auto" : settings.screensize;
|
|
18500
|
+
const resolvedOversampling = clampWebVROversampling(oversampling);
|
|
18501
|
+
const reportDenied = (0, import_react62.useCallback)(
|
|
17946
18502
|
(error) => {
|
|
17947
18503
|
eventBus.emit("vrdenied", { error });
|
|
17948
18504
|
callbacksRef.current.onDenied?.(error);
|
|
17949
18505
|
},
|
|
17950
18506
|
[eventBus]
|
|
17951
18507
|
);
|
|
17952
|
-
const reportUnknownDevice = (0,
|
|
18508
|
+
const reportUnknownDevice = (0, import_react62.useCallback)(() => {
|
|
17953
18509
|
eventBus.emit("vrunknowndevice", void 0);
|
|
17954
18510
|
callbacksRef.current.onUnknownDevice?.();
|
|
17955
18511
|
}, [eventBus]);
|
|
17956
|
-
const
|
|
18512
|
+
const clearDetectedScreensize = (0, import_react62.useCallback)(() => {
|
|
18513
|
+
dpdbRequestIdRef.current += 1;
|
|
18514
|
+
setDetectedScreensize(null);
|
|
18515
|
+
updateWebVRHost(host, { detectedScreensize: null });
|
|
18516
|
+
}, [host]);
|
|
18517
|
+
const resolveAutoScreensize = (0, import_react62.useCallback)(() => {
|
|
18518
|
+
const requestId = ++dpdbRequestIdRef.current;
|
|
18519
|
+
const url = normalizeDatabaseUrl(databaseUrlRef.current);
|
|
18520
|
+
if (!url) {
|
|
18521
|
+
reportUnknownDevice();
|
|
18522
|
+
return;
|
|
18523
|
+
}
|
|
18524
|
+
void resolveScreensizeFromDpdb(url).then((inches) => {
|
|
18525
|
+
if (requestId !== dpdbRequestIdRef.current) {
|
|
18526
|
+
return;
|
|
18527
|
+
}
|
|
18528
|
+
if (inches === null) {
|
|
18529
|
+
reportUnknownDevice();
|
|
18530
|
+
return;
|
|
18531
|
+
}
|
|
18532
|
+
setDetectedScreensize(inches);
|
|
18533
|
+
updateWebVRHost(host, { detectedScreensize: inches });
|
|
18534
|
+
});
|
|
18535
|
+
}, [host, reportUnknownDevice]);
|
|
18536
|
+
const activate = (0, import_react62.useCallback)(
|
|
17957
18537
|
(nextMode) => {
|
|
17958
18538
|
if (modeRef.current === nextMode) {
|
|
17959
18539
|
return;
|
|
@@ -17968,7 +18548,7 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
17968
18548
|
},
|
|
17969
18549
|
[controlsRef, eventBus]
|
|
17970
18550
|
);
|
|
17971
|
-
const deactivate = (0,
|
|
18551
|
+
const deactivate = (0, import_react62.useCallback)(
|
|
17972
18552
|
(expectedMode) => {
|
|
17973
18553
|
const previousMode = modeRef.current;
|
|
17974
18554
|
if (!previousMode || expectedMode && previousMode !== expectedMode) {
|
|
@@ -17976,6 +18556,7 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
17976
18556
|
}
|
|
17977
18557
|
modeRef.current = null;
|
|
17978
18558
|
setMode(null);
|
|
18559
|
+
clearDetectedScreensize();
|
|
17979
18560
|
if (previousMode === "fake") {
|
|
17980
18561
|
controlsRef.current?.setGyroActive(false);
|
|
17981
18562
|
}
|
|
@@ -17983,24 +18564,42 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
17983
18564
|
eventBus.emit("vrexit", { mode: previousMode });
|
|
17984
18565
|
callbacksRef.current.onExitVR?.(previousMode);
|
|
17985
18566
|
},
|
|
17986
|
-
[controlsRef, eventBus, gl.domElement]
|
|
18567
|
+
[clearDetectedScreensize, controlsRef, eventBus, gl.domElement]
|
|
17987
18568
|
);
|
|
17988
|
-
const requestPermission = (0,
|
|
18569
|
+
const requestPermission = (0, import_react62.useCallback)(async () => {
|
|
17989
18570
|
return await gyroRef.current?.requestPermission() ?? false;
|
|
17990
18571
|
}, []);
|
|
17991
|
-
const
|
|
18572
|
+
const applyWebXRQuality = (0, import_react62.useCallback)(() => {
|
|
18573
|
+
const scale = oversamplingRef.current;
|
|
18574
|
+
if (typeof gl.xr.setFramebufferScaleFactor === "function") {
|
|
18575
|
+
gl.xr.setFramebufferScaleFactor(scale);
|
|
18576
|
+
}
|
|
18577
|
+
const nextFoveation = foveationRef.current;
|
|
18578
|
+
if (nextFoveation !== void 0 && typeof gl.xr.setFoveation === "function") {
|
|
18579
|
+
gl.xr.setFoveation(nextFoveation);
|
|
18580
|
+
}
|
|
18581
|
+
const frameRateOption = resolveWebVRFrameRateOption(frameRateRef.current);
|
|
18582
|
+
if (frameRateOption !== void 0) {
|
|
18583
|
+
xrStore.setFrameRate(frameRateOption);
|
|
18584
|
+
}
|
|
18585
|
+
}, [gl.xr, xrStore]);
|
|
18586
|
+
const enterVR = (0, import_react62.useCallback)(async () => {
|
|
17992
18587
|
if (modeRef.current) {
|
|
17993
18588
|
return true;
|
|
17994
18589
|
}
|
|
17995
18590
|
const capabilities = capabilitiesRef.current;
|
|
17996
18591
|
if (capabilities.webxr) {
|
|
17997
18592
|
try {
|
|
18593
|
+
if (typeof gl.xr.setFramebufferScaleFactor === "function") {
|
|
18594
|
+
gl.xr.setFramebufferScaleFactor(oversamplingRef.current);
|
|
18595
|
+
}
|
|
17998
18596
|
await xrStore.enterVR();
|
|
17999
18597
|
const session2 = xrStore.getState().session;
|
|
18000
18598
|
if (!session2) {
|
|
18001
18599
|
throw new Error("The WebXR session did not start.");
|
|
18002
18600
|
}
|
|
18003
18601
|
webXRSessionRef.current = session2;
|
|
18602
|
+
applyWebXRQuality();
|
|
18004
18603
|
session2.addEventListener(
|
|
18005
18604
|
"end",
|
|
18006
18605
|
() => {
|
|
@@ -18030,10 +18629,10 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
18030
18629
|
reportDenied();
|
|
18031
18630
|
return false;
|
|
18032
18631
|
}
|
|
18632
|
+
activate("mobilevr");
|
|
18033
18633
|
if (settings.screensize === "auto") {
|
|
18034
|
-
|
|
18634
|
+
resolveAutoScreensize();
|
|
18035
18635
|
}
|
|
18036
|
-
activate("mobilevr");
|
|
18037
18636
|
return true;
|
|
18038
18637
|
}
|
|
18039
18638
|
if (fakeSupport) {
|
|
@@ -18052,21 +18651,23 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
18052
18651
|
return false;
|
|
18053
18652
|
}, [
|
|
18054
18653
|
activate,
|
|
18654
|
+
applyWebXRQuality,
|
|
18055
18655
|
deactivate,
|
|
18056
18656
|
desktopSupport,
|
|
18057
18657
|
eventBus,
|
|
18058
18658
|
fakeSupport,
|
|
18059
18659
|
gl.domElement,
|
|
18660
|
+
gl.xr,
|
|
18060
18661
|
mobileVr,
|
|
18061
18662
|
mousePointerLock,
|
|
18062
18663
|
reportDenied,
|
|
18063
|
-
reportUnknownDevice,
|
|
18064
18664
|
requestPermission,
|
|
18665
|
+
resolveAutoScreensize,
|
|
18065
18666
|
settings.screensize,
|
|
18066
18667
|
wakelock,
|
|
18067
18668
|
xrStore
|
|
18068
18669
|
]);
|
|
18069
|
-
const exitVR = (0,
|
|
18670
|
+
const exitVR = (0, import_react62.useCallback)(async () => {
|
|
18070
18671
|
if (modeRef.current === "webxr") {
|
|
18071
18672
|
const session2 = webXRSessionRef.current ?? xrStore.getState().session ?? null;
|
|
18072
18673
|
if (session2) {
|
|
@@ -18079,47 +18680,90 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
18079
18680
|
deactivate();
|
|
18080
18681
|
leaveWebVRPresentation();
|
|
18081
18682
|
}, [deactivate, xrStore]);
|
|
18082
|
-
const toggleVR = (0,
|
|
18683
|
+
const toggleVR = (0, import_react62.useCallback)(async () => {
|
|
18083
18684
|
if (modeRef.current) {
|
|
18084
18685
|
await exitVR();
|
|
18085
18686
|
return false;
|
|
18086
18687
|
}
|
|
18087
18688
|
return enterVR();
|
|
18088
18689
|
}, [enterVR, exitVR]);
|
|
18089
|
-
const updateSettings = (0,
|
|
18090
|
-
|
|
18091
|
-
|
|
18092
|
-
|
|
18093
|
-
|
|
18094
|
-
|
|
18095
|
-
|
|
18096
|
-
|
|
18097
|
-
|
|
18690
|
+
const updateSettings = (0, import_react62.useCallback)(
|
|
18691
|
+
(next) => {
|
|
18692
|
+
const normalized = {
|
|
18693
|
+
profileId: next.profileId,
|
|
18694
|
+
screensize: next.screensize === "auto" ? "auto" : Math.round(Math.max(3, Math.min(20, next.screensize)) * 10) / 10
|
|
18695
|
+
};
|
|
18696
|
+
setSettings(normalized);
|
|
18697
|
+
saveWebVRSettings(normalized);
|
|
18698
|
+
if (normalized.screensize === "auto") {
|
|
18699
|
+
if (modeRef.current === "mobilevr") {
|
|
18700
|
+
setDetectedScreensize(null);
|
|
18701
|
+
updateWebVRHost(host, { detectedScreensize: null });
|
|
18702
|
+
resolveAutoScreensize();
|
|
18703
|
+
}
|
|
18704
|
+
} else {
|
|
18705
|
+
clearDetectedScreensize();
|
|
18706
|
+
}
|
|
18707
|
+
},
|
|
18708
|
+
[clearDetectedScreensize, host, resolveAutoScreensize]
|
|
18709
|
+
);
|
|
18710
|
+
const resetSettings = (0, import_react62.useCallback)(() => {
|
|
18711
|
+
clearWebVRSettings();
|
|
18712
|
+
const next = resolveInitialWebVRSettings(
|
|
18713
|
+
screensizePropRef.current,
|
|
18714
|
+
profilePropRef.current
|
|
18715
|
+
);
|
|
18716
|
+
setSettings(next);
|
|
18717
|
+
if (next.screensize === "auto") {
|
|
18718
|
+
if (modeRef.current === "mobilevr") {
|
|
18719
|
+
setDetectedScreensize(null);
|
|
18720
|
+
updateWebVRHost(host, { detectedScreensize: null });
|
|
18721
|
+
resolveAutoScreensize();
|
|
18722
|
+
} else {
|
|
18723
|
+
clearDetectedScreensize();
|
|
18724
|
+
}
|
|
18725
|
+
} else {
|
|
18726
|
+
clearDetectedScreensize();
|
|
18727
|
+
}
|
|
18728
|
+
}, [clearDetectedScreensize, host, resolveAutoScreensize]);
|
|
18729
|
+
const controller = (0, import_react62.useMemo)(
|
|
18098
18730
|
() => ({
|
|
18099
18731
|
closeSetup: () => updateWebVRHost(host, { setupOpen: false }),
|
|
18100
18732
|
enterVR,
|
|
18101
18733
|
exitVR,
|
|
18102
18734
|
openSetup: () => updateWebVRHost(host, { setupOpen: true }),
|
|
18103
18735
|
requestPermission,
|
|
18736
|
+
resetSettings,
|
|
18104
18737
|
toggleVR,
|
|
18105
18738
|
updateSettings
|
|
18106
18739
|
}),
|
|
18107
|
-
[
|
|
18740
|
+
[
|
|
18741
|
+
enterVR,
|
|
18742
|
+
exitVR,
|
|
18743
|
+
host,
|
|
18744
|
+
requestPermission,
|
|
18745
|
+
resetSettings,
|
|
18746
|
+
toggleVR,
|
|
18747
|
+
updateSettings
|
|
18748
|
+
]
|
|
18108
18749
|
);
|
|
18109
|
-
(0,
|
|
18750
|
+
(0, import_react62.useImperativeHandle)(
|
|
18110
18751
|
ref,
|
|
18111
18752
|
() => ({
|
|
18112
18753
|
enterVR,
|
|
18113
18754
|
exitVR,
|
|
18114
18755
|
getMode: () => modeRef.current,
|
|
18756
|
+
getState: () => getWebVRState(host),
|
|
18115
18757
|
isAvailable: () => availableRef.current,
|
|
18116
18758
|
isEnabled: () => modeRef.current !== null,
|
|
18117
18759
|
requestPermission,
|
|
18760
|
+
resetSettings,
|
|
18761
|
+
subscribe: (onStoreChange) => subscribeWebVRHost(host, onStoreChange),
|
|
18118
18762
|
toggleVR
|
|
18119
18763
|
}),
|
|
18120
|
-
[enterVR, exitVR, requestPermission, toggleVR]
|
|
18764
|
+
[enterVR, exitVR, host, requestPermission, resetSettings, toggleVR]
|
|
18121
18765
|
);
|
|
18122
|
-
(0,
|
|
18766
|
+
(0, import_react62.useEffect)(() => {
|
|
18123
18767
|
let active = true;
|
|
18124
18768
|
void detectWebVRCapabilities().then((capabilities) => {
|
|
18125
18769
|
if (!active) {
|
|
@@ -18141,19 +18785,30 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
18141
18785
|
active = false;
|
|
18142
18786
|
};
|
|
18143
18787
|
}, [desktopSupport, eventBus, fakeSupport, host, mobileVr]);
|
|
18144
|
-
(0,
|
|
18788
|
+
(0, import_react62.useEffect)(() => {
|
|
18145
18789
|
host.controller = controller;
|
|
18146
18790
|
return () => {
|
|
18147
18791
|
if (host.controller === controller) {
|
|
18148
18792
|
host.controller = null;
|
|
18149
|
-
|
|
18793
|
+
dpdbRequestIdRef.current += 1;
|
|
18794
|
+
setDetectedScreensize(null);
|
|
18795
|
+
updateWebVRHost(host, {
|
|
18796
|
+
detectedScreensize: null,
|
|
18797
|
+
mode: null,
|
|
18798
|
+
setupOpen: false
|
|
18799
|
+
});
|
|
18150
18800
|
}
|
|
18151
18801
|
};
|
|
18152
18802
|
}, [controller, host]);
|
|
18153
|
-
(0,
|
|
18154
|
-
updateWebVRHost(host, {
|
|
18155
|
-
|
|
18156
|
-
|
|
18803
|
+
(0, import_react62.useEffect)(() => {
|
|
18804
|
+
updateWebVRHost(host, {
|
|
18805
|
+
chrome,
|
|
18806
|
+
detectedScreensize,
|
|
18807
|
+
mode,
|
|
18808
|
+
settings
|
|
18809
|
+
});
|
|
18810
|
+
}, [chrome, detectedScreensize, host, mode, settings]);
|
|
18811
|
+
(0, import_react62.useEffect)(() => {
|
|
18157
18812
|
if (mode !== "fake") {
|
|
18158
18813
|
return;
|
|
18159
18814
|
}
|
|
@@ -18177,7 +18832,7 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
18177
18832
|
document.removeEventListener("mousemove", onMouseMove);
|
|
18178
18833
|
};
|
|
18179
18834
|
}, [controlsRef, gl.domElement, mode, mousePointerLock]);
|
|
18180
|
-
(0,
|
|
18835
|
+
(0, import_react62.useEffect)(
|
|
18181
18836
|
() => () => {
|
|
18182
18837
|
const session2 = webXRSessionRef.current;
|
|
18183
18838
|
if (session2) {
|
|
@@ -18192,7 +18847,7 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
18192
18847
|
},
|
|
18193
18848
|
[controlsRef]
|
|
18194
18849
|
);
|
|
18195
|
-
(0,
|
|
18850
|
+
(0, import_react62.useEffect)(() => {
|
|
18196
18851
|
if (mode !== "mobilevr" && mode !== "fake") {
|
|
18197
18852
|
return;
|
|
18198
18853
|
}
|
|
@@ -18201,6 +18856,23 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
18201
18856
|
void exitVR();
|
|
18202
18857
|
});
|
|
18203
18858
|
}, [exitVR, gl.domElement, mode]);
|
|
18859
|
+
(0, import_react62.useEffect)(() => {
|
|
18860
|
+
if (mode !== "webxr") {
|
|
18861
|
+
return;
|
|
18862
|
+
}
|
|
18863
|
+
const session2 = webXRSessionRef.current ?? xrStore.getState().session ?? null;
|
|
18864
|
+
if (!session2) {
|
|
18865
|
+
return;
|
|
18866
|
+
}
|
|
18867
|
+
const nextFoveation = foveationRef.current;
|
|
18868
|
+
if (nextFoveation !== void 0 && typeof gl.xr.setFoveation === "function") {
|
|
18869
|
+
gl.xr.setFoveation(nextFoveation);
|
|
18870
|
+
}
|
|
18871
|
+
const frameRateOption = resolveWebVRFrameRateOption(frameRateRef.current);
|
|
18872
|
+
if (frameRateOption !== void 0) {
|
|
18873
|
+
xrStore.setFrameRate(frameRateOption);
|
|
18874
|
+
}
|
|
18875
|
+
}, [foveation, frameRate, gl.xr, mode, xrStore]);
|
|
18204
18876
|
useWebVRPointerLock(
|
|
18205
18877
|
mousePointerLock && mode === "fake",
|
|
18206
18878
|
gl.domElement
|
|
@@ -18213,22 +18885,26 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
18213
18885
|
Gyro,
|
|
18214
18886
|
{
|
|
18215
18887
|
ref: gyroRef,
|
|
18888
|
+
absolute,
|
|
18216
18889
|
desktopSupport,
|
|
18217
18890
|
enabled: mode === "mobilevr",
|
|
18891
|
+
friction,
|
|
18892
|
+
north,
|
|
18218
18893
|
onDenied: () => {
|
|
18219
18894
|
reportDenied();
|
|
18220
18895
|
deactivate("mobilevr");
|
|
18221
18896
|
},
|
|
18222
18897
|
softstart: 0,
|
|
18223
|
-
touchMode: "off"
|
|
18898
|
+
touchMode: touchSupport ? "horizontaloffset" : "off"
|
|
18224
18899
|
}
|
|
18225
18900
|
),
|
|
18226
18901
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
18227
18902
|
WebVRStereoRenderer,
|
|
18228
18903
|
{
|
|
18229
18904
|
mode,
|
|
18905
|
+
oversampling: resolvedOversampling,
|
|
18230
18906
|
profile: resolvedProfile,
|
|
18231
|
-
screensize:
|
|
18907
|
+
screensize: effectiveScreensize
|
|
18232
18908
|
}
|
|
18233
18909
|
),
|
|
18234
18910
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
@@ -18243,7 +18919,7 @@ var WebVR = (0, import_react61.forwardRef)(function WebVR2({
|
|
|
18243
18919
|
});
|
|
18244
18920
|
|
|
18245
18921
|
// src/pano-scene-menu.tsx
|
|
18246
|
-
var
|
|
18922
|
+
var import_react63 = require("react");
|
|
18247
18923
|
|
|
18248
18924
|
// src/drag-motion.ts
|
|
18249
18925
|
var DRAG_INERTIA_DAMPING = 8;
|
|
@@ -18627,10 +19303,10 @@ function PanoSceneMenu({
|
|
|
18627
19303
|
expandLabel = "Show scenes",
|
|
18628
19304
|
collapseLabel = "Hide scenes"
|
|
18629
19305
|
}) {
|
|
18630
|
-
const listId = (0,
|
|
18631
|
-
const listRef = (0,
|
|
18632
|
-
const trackRef = (0,
|
|
18633
|
-
const itemRefs = (0,
|
|
19306
|
+
const listId = (0, import_react63.useId)();
|
|
19307
|
+
const listRef = (0, import_react63.useRef)(null);
|
|
19308
|
+
const trackRef = (0, import_react63.useRef)(null);
|
|
19309
|
+
const itemRefs = (0, import_react63.useRef)(/* @__PURE__ */ new Map());
|
|
18634
19310
|
const resolved = resolveAppearance2(appearance);
|
|
18635
19311
|
const resolvedInset = resolveInset(inset);
|
|
18636
19312
|
const horizontal = isHorizontal(placement);
|
|
@@ -18639,34 +19315,34 @@ function PanoSceneMenu({
|
|
|
18639
19315
|
dragMotionProp === false ? false : dragMotionProp
|
|
18640
19316
|
);
|
|
18641
19317
|
const isExpandedControlled = expandedProp !== void 0;
|
|
18642
|
-
const [internalExpanded, setInternalExpanded] = (0,
|
|
19318
|
+
const [internalExpanded, setInternalExpanded] = (0, import_react63.useState)(defaultExpanded);
|
|
18643
19319
|
const expanded = collapsible ? isExpandedControlled ? expandedProp : internalExpanded : true;
|
|
18644
|
-
const [offset, setOffset] = (0,
|
|
18645
|
-
const [viewportSize, setViewportSize] = (0,
|
|
18646
|
-
const [contentSize, setContentSize] = (0,
|
|
18647
|
-
const offsetRef = (0,
|
|
18648
|
-
const dragRef = (0,
|
|
18649
|
-
const animRef = (0,
|
|
19320
|
+
const [offset, setOffset] = (0, import_react63.useState)(0);
|
|
19321
|
+
const [viewportSize, setViewportSize] = (0, import_react63.useState)(0);
|
|
19322
|
+
const [contentSize, setContentSize] = (0, import_react63.useState)(0);
|
|
19323
|
+
const offsetRef = (0, import_react63.useRef)(0);
|
|
19324
|
+
const dragRef = (0, import_react63.useRef)(null);
|
|
19325
|
+
const animRef = (0, import_react63.useRef)(null);
|
|
18650
19326
|
const maxOffset = Math.max(0, contentSize - viewportSize);
|
|
18651
19327
|
offsetRef.current = offset;
|
|
18652
|
-
const activeIndex = (0,
|
|
19328
|
+
const activeIndex = (0, import_react63.useMemo)(() => {
|
|
18653
19329
|
if (activeId == null) {
|
|
18654
19330
|
return -1;
|
|
18655
19331
|
}
|
|
18656
19332
|
return items.findIndex((item) => item.id === activeId);
|
|
18657
19333
|
}, [activeId, items]);
|
|
18658
|
-
const cancelScrollAnimation = (0,
|
|
19334
|
+
const cancelScrollAnimation = (0, import_react63.useCallback)(() => {
|
|
18659
19335
|
const anim = animRef.current;
|
|
18660
19336
|
if (anim?.raf != null) {
|
|
18661
19337
|
cancelAnimationFrame(anim.raf);
|
|
18662
19338
|
}
|
|
18663
19339
|
animRef.current = null;
|
|
18664
19340
|
}, []);
|
|
18665
|
-
const clampOffset = (0,
|
|
19341
|
+
const clampOffset = (0, import_react63.useCallback)(
|
|
18666
19342
|
(value) => Math.min(maxOffset, Math.max(0, value)),
|
|
18667
19343
|
[maxOffset]
|
|
18668
19344
|
);
|
|
18669
|
-
const startScrollAnimation = (0,
|
|
19345
|
+
const startScrollAnimation = (0, import_react63.useCallback)(
|
|
18670
19346
|
(velocity) => {
|
|
18671
19347
|
cancelScrollAnimation();
|
|
18672
19348
|
const current = offsetRef.current;
|
|
@@ -18721,8 +19397,8 @@ function PanoSceneMenu({
|
|
|
18721
19397
|
maxOffset
|
|
18722
19398
|
]
|
|
18723
19399
|
);
|
|
18724
|
-
(0,
|
|
18725
|
-
(0,
|
|
19400
|
+
(0, import_react63.useEffect)(() => () => cancelScrollAnimation(), [cancelScrollAnimation]);
|
|
19401
|
+
(0, import_react63.useLayoutEffect)(() => {
|
|
18726
19402
|
if (!customDrag || !expanded) return;
|
|
18727
19403
|
const list = listRef.current;
|
|
18728
19404
|
const track = trackRef.current;
|
|
@@ -18743,12 +19419,12 @@ function PanoSceneMenu({
|
|
|
18743
19419
|
observer.observe(track);
|
|
18744
19420
|
return () => observer.disconnect();
|
|
18745
19421
|
}, [customDrag, expanded, horizontal, items]);
|
|
18746
|
-
(0,
|
|
19422
|
+
(0, import_react63.useEffect)(() => {
|
|
18747
19423
|
if (!customDrag) return;
|
|
18748
19424
|
if (dragRef.current || animRef.current) return;
|
|
18749
19425
|
setOffset((previous) => Math.min(maxOffset, Math.max(0, previous)));
|
|
18750
19426
|
}, [customDrag, maxOffset]);
|
|
18751
|
-
(0,
|
|
19427
|
+
(0, import_react63.useEffect)(() => {
|
|
18752
19428
|
if (!expanded || activeId == null) {
|
|
18753
19429
|
return;
|
|
18754
19430
|
}
|
|
@@ -18791,7 +19467,7 @@ function PanoSceneMenu({
|
|
|
18791
19467
|
expanded,
|
|
18792
19468
|
horizontal
|
|
18793
19469
|
]);
|
|
18794
|
-
const rootStyle = (0,
|
|
19470
|
+
const rootStyle = (0, import_react63.useMemo)(() => {
|
|
18795
19471
|
const vars = {
|
|
18796
19472
|
"--pano-scene-menu-background": resolved.background,
|
|
18797
19473
|
"--pano-scene-menu-padding": cssLength(resolved.padding),
|
|
@@ -18933,7 +19609,7 @@ function PanoSceneMenu({
|
|
|
18933
19609
|
setOffset((previous) => clampOffset(previous + event.deltaX));
|
|
18934
19610
|
};
|
|
18935
19611
|
const axisPoint = (event) => horizontal ? event.clientX : event.clientY;
|
|
18936
|
-
const endSuppressClickRef = (0,
|
|
19612
|
+
const endSuppressClickRef = (0, import_react63.useRef)(false);
|
|
18937
19613
|
const beginListDrag = (event, captureTarget) => {
|
|
18938
19614
|
if (!customDrag || event.button !== 0) return;
|
|
18939
19615
|
cancelScrollAnimation();
|
|
@@ -19143,7 +19819,7 @@ function PanoSceneMenu({
|
|
|
19143
19819
|
}
|
|
19144
19820
|
|
|
19145
19821
|
// src/use-pano-viewer.ts
|
|
19146
|
-
var
|
|
19822
|
+
var import_react64 = require("react");
|
|
19147
19823
|
function createPanoViewerHandle(ref) {
|
|
19148
19824
|
return {
|
|
19149
19825
|
getView: () => ref.current?.getView() ?? { yaw: 0, pitch: 0, fov: 75 },
|
|
@@ -19174,6 +19850,36 @@ function createPanoViewerHandle(ref) {
|
|
|
19174
19850
|
isVRAvailable: () => ref.current?.isVRAvailable() ?? false,
|
|
19175
19851
|
isVREnabled: () => ref.current?.isVREnabled() ?? false,
|
|
19176
19852
|
getVRMode: () => ref.current?.getVRMode() ?? null,
|
|
19853
|
+
getVRState: () => ref.current?.getVRState() ?? EMPTY_WEBVR_STATE,
|
|
19854
|
+
subscribeVR: (onStoreChange) => {
|
|
19855
|
+
let disposed = false;
|
|
19856
|
+
let unsubscribe;
|
|
19857
|
+
const timers = [];
|
|
19858
|
+
const attach = () => {
|
|
19859
|
+
if (disposed || unsubscribe) {
|
|
19860
|
+
return;
|
|
19861
|
+
}
|
|
19862
|
+
const handle = ref.current;
|
|
19863
|
+
if (!handle) {
|
|
19864
|
+
return;
|
|
19865
|
+
}
|
|
19866
|
+
unsubscribe = handle.subscribeVR(onStoreChange);
|
|
19867
|
+
onStoreChange();
|
|
19868
|
+
};
|
|
19869
|
+
attach();
|
|
19870
|
+
if (typeof window !== "undefined") {
|
|
19871
|
+
for (const delay of [0, 16, 50, 100, 250]) {
|
|
19872
|
+
timers.push(window.setTimeout(attach, delay));
|
|
19873
|
+
}
|
|
19874
|
+
}
|
|
19875
|
+
return () => {
|
|
19876
|
+
disposed = true;
|
|
19877
|
+
for (const id of timers) {
|
|
19878
|
+
window.clearTimeout(id);
|
|
19879
|
+
}
|
|
19880
|
+
unsubscribe?.();
|
|
19881
|
+
};
|
|
19882
|
+
},
|
|
19177
19883
|
requestVRPermission: () => ref.current?.requestVRPermission() ?? Promise.resolve(false),
|
|
19178
19884
|
getVideo: () => ref.current?.getVideo() ?? null,
|
|
19179
19885
|
subscribeVideo: (onStoreChange) => ref.current?.subscribeVideo(onStoreChange) ?? (() => {
|
|
@@ -19225,14 +19931,14 @@ function createPanoViewerHandle(ref) {
|
|
|
19225
19931
|
};
|
|
19226
19932
|
}
|
|
19227
19933
|
function usePanoViewer() {
|
|
19228
|
-
const ref = (0,
|
|
19229
|
-
const handle = (0,
|
|
19230
|
-
return (0,
|
|
19934
|
+
const ref = (0, import_react64.useRef)(null);
|
|
19935
|
+
const handle = (0, import_react64.useMemo)(() => createPanoViewerHandle(ref), []);
|
|
19936
|
+
return (0, import_react64.useMemo)(() => ({ ref, ...handle }), [handle]);
|
|
19231
19937
|
}
|
|
19232
19938
|
|
|
19233
19939
|
// src/video/pano-video.tsx
|
|
19234
19940
|
var import_fiber31 = require("@react-three/fiber");
|
|
19235
|
-
var
|
|
19941
|
+
var import_react65 = require("react");
|
|
19236
19942
|
var import_three40 = require("three");
|
|
19237
19943
|
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
19238
19944
|
var EMPTY_TRACKS = [];
|
|
@@ -19319,10 +20025,10 @@ function applyEquirectangularLayout(texture, anisotropy) {
|
|
|
19319
20025
|
}
|
|
19320
20026
|
function usePosterTexture2(poster, onError) {
|
|
19321
20027
|
const gl = (0, import_fiber31.useThree)((state) => state.gl);
|
|
19322
|
-
const [texture, setTexture] = (0,
|
|
19323
|
-
const onErrorRef = (0,
|
|
20028
|
+
const [texture, setTexture] = (0, import_react65.useState)(null);
|
|
20029
|
+
const onErrorRef = (0, import_react65.useRef)(onError);
|
|
19324
20030
|
onErrorRef.current = onError;
|
|
19325
|
-
(0,
|
|
20031
|
+
(0, import_react65.useEffect)(() => {
|
|
19326
20032
|
let active = true;
|
|
19327
20033
|
setTexture(null);
|
|
19328
20034
|
if (!poster) {
|
|
@@ -19359,7 +20065,7 @@ function usePosterTexture2(poster, onError) {
|
|
|
19359
20065
|
active = false;
|
|
19360
20066
|
};
|
|
19361
20067
|
}, [gl, poster]);
|
|
19362
|
-
(0,
|
|
20068
|
+
(0, import_react65.useEffect)(
|
|
19363
20069
|
() => () => {
|
|
19364
20070
|
texture?.dispose();
|
|
19365
20071
|
},
|
|
@@ -19418,37 +20124,37 @@ function PanoVideo({
|
|
|
19418
20124
|
}) {
|
|
19419
20125
|
usePanoMediaActivationIntent(autoPlay);
|
|
19420
20126
|
const gl = (0, import_fiber31.useThree)((state) => state.gl);
|
|
19421
|
-
const host = (0,
|
|
19422
|
-
const variants = (0,
|
|
20127
|
+
const host = (0, import_react65.useContext)(PanoVideoHostContext);
|
|
20128
|
+
const variants = (0, import_react65.useMemo)(
|
|
19423
20129
|
() => resolvePanoVideoVariants({ poster, src, variants: variantsProp }),
|
|
19424
20130
|
[poster, src, variantsProp]
|
|
19425
20131
|
);
|
|
19426
20132
|
const tracks = tracksProp ?? EMPTY_TRACKS;
|
|
19427
20133
|
const captionsEnabled = captions !== false;
|
|
19428
|
-
const captionAppearance = (0,
|
|
20134
|
+
const captionAppearance = (0, import_react65.useMemo)(
|
|
19429
20135
|
() => resolvePanoVideoCaptionAppearance(
|
|
19430
20136
|
typeof captions === "object" ? captions : void 0
|
|
19431
20137
|
),
|
|
19432
20138
|
[captions]
|
|
19433
20139
|
);
|
|
19434
|
-
const [variantId, setVariantId] = (0,
|
|
20140
|
+
const [variantId, setVariantId] = (0, import_react65.useState)(
|
|
19435
20141
|
() => resolvePanoVideoVariantId(variants, defaultVariantId)
|
|
19436
20142
|
);
|
|
19437
|
-
const [trackId, setTrackId] = (0,
|
|
20143
|
+
const [trackId, setTrackId] = (0, import_react65.useState)(
|
|
19438
20144
|
() => captionsEnabled ? defaultPanoVideoTrackId(tracks) : null
|
|
19439
20145
|
);
|
|
19440
|
-
const [ready, setReady] = (0,
|
|
19441
|
-
const autoPlayRef = (0,
|
|
20146
|
+
const [ready, setReady] = (0, import_react65.useState)(false);
|
|
20147
|
+
const autoPlayRef = (0, import_react65.useRef)(autoPlay);
|
|
19442
20148
|
autoPlayRef.current = autoPlay;
|
|
19443
|
-
const blockedRef = (0,
|
|
19444
|
-
const captionAppearanceOverrideRef = (0,
|
|
20149
|
+
const blockedRef = (0, import_react65.useRef)(false);
|
|
20150
|
+
const captionAppearanceOverrideRef = (0, import_react65.useRef)(
|
|
19445
20151
|
{}
|
|
19446
20152
|
);
|
|
19447
|
-
const mediaCapabilitiesRef = (0,
|
|
20153
|
+
const mediaCapabilitiesRef = (0, import_react65.useRef)({
|
|
19448
20154
|
volumeAdjustable: true,
|
|
19449
20155
|
playbackRates: [...DEFAULT_PANO_VIDEO_PLAYBACK_RATES]
|
|
19450
20156
|
});
|
|
19451
|
-
const storeRef = (0,
|
|
20157
|
+
const storeRef = (0, import_react65.useRef)(null);
|
|
19452
20158
|
if (!storeRef.current) {
|
|
19453
20159
|
storeRef.current = {
|
|
19454
20160
|
snapshot: {
|
|
@@ -19458,7 +20164,7 @@ function PanoVideo({
|
|
|
19458
20164
|
listeners: /* @__PURE__ */ new Set()
|
|
19459
20165
|
};
|
|
19460
20166
|
}
|
|
19461
|
-
const actionsRef = (0,
|
|
20167
|
+
const actionsRef = (0, import_react65.useRef)({
|
|
19462
20168
|
play: async () => {
|
|
19463
20169
|
},
|
|
19464
20170
|
pause: () => {
|
|
@@ -19478,19 +20184,19 @@ function PanoVideo({
|
|
|
19478
20184
|
setCaptionAppearance: (_appearance) => {
|
|
19479
20185
|
}
|
|
19480
20186
|
});
|
|
19481
|
-
const onLoadRef = (0,
|
|
19482
|
-
const onErrorRef = (0,
|
|
19483
|
-
const onPlaybackStateChangeRef = (0,
|
|
19484
|
-
const onEndedRef = (0,
|
|
19485
|
-
const onVariantChangeRef = (0,
|
|
19486
|
-
const onTrackChangeRef = (0,
|
|
20187
|
+
const onLoadRef = (0, import_react65.useRef)(onLoad);
|
|
20188
|
+
const onErrorRef = (0, import_react65.useRef)(onError);
|
|
20189
|
+
const onPlaybackStateChangeRef = (0, import_react65.useRef)(onPlaybackStateChange);
|
|
20190
|
+
const onEndedRef = (0, import_react65.useRef)(onEnded);
|
|
20191
|
+
const onVariantChangeRef = (0, import_react65.useRef)(onVariantChange);
|
|
20192
|
+
const onTrackChangeRef = (0, import_react65.useRef)(onTrackChange);
|
|
19487
20193
|
onLoadRef.current = onLoad;
|
|
19488
20194
|
onErrorRef.current = onError;
|
|
19489
20195
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
19490
20196
|
onEndedRef.current = onEnded;
|
|
19491
20197
|
onVariantChangeRef.current = onVariantChange;
|
|
19492
20198
|
onTrackChangeRef.current = onTrackChange;
|
|
19493
|
-
const resource = (0,
|
|
20199
|
+
const resource = (0, import_react65.useMemo)(() => {
|
|
19494
20200
|
if (typeof document === "undefined") {
|
|
19495
20201
|
return null;
|
|
19496
20202
|
}
|
|
@@ -19505,7 +20211,7 @@ function PanoVideo({
|
|
|
19505
20211
|
texture.generateMipmaps = false;
|
|
19506
20212
|
return { video, texture };
|
|
19507
20213
|
}, []);
|
|
19508
|
-
(0,
|
|
20214
|
+
(0, import_react65.useEffect)(
|
|
19509
20215
|
() => () => {
|
|
19510
20216
|
if (!resource) {
|
|
19511
20217
|
return;
|
|
@@ -19520,13 +20226,13 @@ function PanoVideo({
|
|
|
19520
20226
|
},
|
|
19521
20227
|
[resource]
|
|
19522
20228
|
);
|
|
19523
|
-
(0,
|
|
20229
|
+
(0, import_react65.useEffect)(() => {
|
|
19524
20230
|
if (!resource) {
|
|
19525
20231
|
return;
|
|
19526
20232
|
}
|
|
19527
20233
|
resource.texture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
19528
20234
|
}, [gl, resource]);
|
|
19529
|
-
(0,
|
|
20235
|
+
(0, import_react65.useLayoutEffect)(() => {
|
|
19530
20236
|
if (!resource) {
|
|
19531
20237
|
return;
|
|
19532
20238
|
}
|
|
@@ -19542,7 +20248,7 @@ function PanoVideo({
|
|
|
19542
20248
|
activeVariant?.poster ?? poster,
|
|
19543
20249
|
onError
|
|
19544
20250
|
);
|
|
19545
|
-
const emitSnapshot = (0,
|
|
20251
|
+
const emitSnapshot = (0, import_react65.useCallback)(
|
|
19546
20252
|
(patch) => {
|
|
19547
20253
|
const store = storeRef.current;
|
|
19548
20254
|
const video = resource?.video;
|
|
@@ -19594,7 +20300,7 @@ function PanoVideo({
|
|
|
19594
20300
|
captionAppearance
|
|
19595
20301
|
]
|
|
19596
20302
|
);
|
|
19597
|
-
const controller = (0,
|
|
20303
|
+
const controller = (0, import_react65.useMemo)(
|
|
19598
20304
|
() => ({
|
|
19599
20305
|
subscribe: (onStoreChange) => {
|
|
19600
20306
|
const store = storeRef.current;
|
|
@@ -19646,7 +20352,7 @@ function PanoVideo({
|
|
|
19646
20352
|
}),
|
|
19647
20353
|
[]
|
|
19648
20354
|
);
|
|
19649
|
-
(0,
|
|
20355
|
+
(0, import_react65.useLayoutEffect)(() => {
|
|
19650
20356
|
if (!host || variants.length === 0) {
|
|
19651
20357
|
return;
|
|
19652
20358
|
}
|
|
@@ -19659,7 +20365,7 @@ function PanoVideo({
|
|
|
19659
20365
|
notifyPanoVideoHost(host);
|
|
19660
20366
|
};
|
|
19661
20367
|
}, [captionsEnabled, controller, controls, host, variants.length]);
|
|
19662
|
-
(0,
|
|
20368
|
+
(0, import_react65.useLayoutEffect)(() => {
|
|
19663
20369
|
if (!resource) {
|
|
19664
20370
|
return;
|
|
19665
20371
|
}
|
|
@@ -19672,10 +20378,10 @@ function PanoVideo({
|
|
|
19672
20378
|
};
|
|
19673
20379
|
emitSnapshot();
|
|
19674
20380
|
}, [emitSnapshot, playbackRates, resource]);
|
|
19675
|
-
(0,
|
|
20381
|
+
(0, import_react65.useEffect)(() => {
|
|
19676
20382
|
emitSnapshot();
|
|
19677
20383
|
}, [emitSnapshot]);
|
|
19678
|
-
(0,
|
|
20384
|
+
(0, import_react65.useEffect)(() => {
|
|
19679
20385
|
if (!resource || !activeVariant || !mediaKey) {
|
|
19680
20386
|
return;
|
|
19681
20387
|
}
|
|
@@ -19732,7 +20438,7 @@ function PanoVideo({
|
|
|
19732
20438
|
video.removeEventListener("error", handleError);
|
|
19733
20439
|
};
|
|
19734
20440
|
}, [mediaKey, resource]);
|
|
19735
|
-
(0,
|
|
20441
|
+
(0, import_react65.useEffect)(() => {
|
|
19736
20442
|
if (!resource) {
|
|
19737
20443
|
return;
|
|
19738
20444
|
}
|
|
@@ -19824,7 +20530,7 @@ function PanoVideo({
|
|
|
19824
20530
|
}
|
|
19825
20531
|
};
|
|
19826
20532
|
}, [emitSnapshot, resource]);
|
|
19827
|
-
(0,
|
|
20533
|
+
(0, import_react65.useLayoutEffect)(() => {
|
|
19828
20534
|
if (!resource) {
|
|
19829
20535
|
return;
|
|
19830
20536
|
}
|
|
@@ -19837,7 +20543,7 @@ function PanoVideo({
|
|
|
19837
20543
|
applyInlineVideoPlayback(video, playsInline);
|
|
19838
20544
|
video.preload = preload;
|
|
19839
20545
|
}, [loop, muted, playsInline, preload, resource, volume]);
|
|
19840
|
-
(0,
|
|
20546
|
+
(0, import_react65.useEffect)(() => {
|
|
19841
20547
|
if (!resource) {
|
|
19842
20548
|
return;
|
|
19843
20549
|
}
|
|
@@ -19887,7 +20593,7 @@ function PanoVideo({
|
|
|
19887
20593
|
video.removeEventListener("ratechange", handleVolume);
|
|
19888
20594
|
};
|
|
19889
20595
|
}, [emitSnapshot, resource]);
|
|
19890
|
-
(0,
|
|
20596
|
+
(0, import_react65.useEffect)(() => {
|
|
19891
20597
|
if (!resource) {
|
|
19892
20598
|
return;
|
|
19893
20599
|
}
|
|
@@ -19922,7 +20628,7 @@ function PanoVideo({
|
|
|
19922
20628
|
video.textTracks.removeEventListener("change", applyModes);
|
|
19923
20629
|
};
|
|
19924
20630
|
}, [emitSnapshot, resource, trackId, tracks]);
|
|
19925
|
-
(0,
|
|
20631
|
+
(0, import_react65.useEffect)(() => {
|
|
19926
20632
|
if (!captionsEnabled) {
|
|
19927
20633
|
setTrackId(null);
|
|
19928
20634
|
return;
|
|
@@ -19957,7 +20663,7 @@ function PanoVideo({
|
|
|
19957
20663
|
}
|
|
19958
20664
|
|
|
19959
20665
|
// src/map/pano-map.tsx
|
|
19960
|
-
var
|
|
20666
|
+
var import_react67 = require("react");
|
|
19961
20667
|
|
|
19962
20668
|
// src/map/geometry.ts
|
|
19963
20669
|
function sectorRotation(heading, yaw) {
|
|
@@ -20017,14 +20723,14 @@ function normalizeDegrees(value) {
|
|
|
20017
20723
|
}
|
|
20018
20724
|
|
|
20019
20725
|
// src/map/use-map-view.ts
|
|
20020
|
-
var
|
|
20726
|
+
var import_react66 = require("react");
|
|
20021
20727
|
var DEFAULT_VIEW2 = { yaw: 0, pitch: 0, fov: 75 };
|
|
20022
20728
|
function useMapView(controlled) {
|
|
20023
|
-
const eventBus = (0,
|
|
20024
|
-
const [view, setView] = (0,
|
|
20025
|
-
const controlledRef = (0,
|
|
20729
|
+
const eventBus = (0, import_react66.useContext)(PanoEventBusContext);
|
|
20730
|
+
const [view, setView] = (0, import_react66.useState)(controlled ?? DEFAULT_VIEW2);
|
|
20731
|
+
const controlledRef = (0, import_react66.useRef)(controlled);
|
|
20026
20732
|
controlledRef.current = controlled;
|
|
20027
|
-
(0,
|
|
20733
|
+
(0, import_react66.useEffect)(() => {
|
|
20028
20734
|
if (controlled !== void 0) {
|
|
20029
20735
|
setView(controlled);
|
|
20030
20736
|
return;
|
|
@@ -20174,22 +20880,22 @@ function PanoMap({
|
|
|
20174
20880
|
renderChrome,
|
|
20175
20881
|
initialScale
|
|
20176
20882
|
}) {
|
|
20177
|
-
const reactId = (0,
|
|
20883
|
+
const reactId = (0, import_react67.useId)().replace(/:/g, "");
|
|
20178
20884
|
const view = useMapView(controlledView);
|
|
20179
|
-
const rootRef = (0,
|
|
20180
|
-
const containerRef = (0,
|
|
20181
|
-
const sectorNodeRef = (0,
|
|
20182
|
-
const yawRef = (0,
|
|
20183
|
-
const [size, setSize] = (0,
|
|
20184
|
-
const [imageSize2, setImageSize] = (0,
|
|
20185
|
-
const [scale, setScale] = (0,
|
|
20186
|
-
const [pan, setPan] = (0,
|
|
20187
|
-
const [uncontrolledCollapsed, setUncontrolledCollapsed] = (0,
|
|
20188
|
-
const dragRef = (0,
|
|
20189
|
-
const panAnimRef = (0,
|
|
20190
|
-
const panRef = (0,
|
|
20191
|
-
const scaleRef = (0,
|
|
20192
|
-
const initialViewKeyRef = (0,
|
|
20885
|
+
const rootRef = (0, import_react67.useRef)(null);
|
|
20886
|
+
const containerRef = (0, import_react67.useRef)(null);
|
|
20887
|
+
const sectorNodeRef = (0, import_react67.useRef)(null);
|
|
20888
|
+
const yawRef = (0, import_react67.useRef)(view.yaw);
|
|
20889
|
+
const [size, setSize] = (0, import_react67.useState)({ width: 0, height: 0 });
|
|
20890
|
+
const [imageSize2, setImageSize] = (0, import_react67.useState)({ width: 0, height: 0 });
|
|
20891
|
+
const [scale, setScale] = (0, import_react67.useState)(1);
|
|
20892
|
+
const [pan, setPan] = (0, import_react67.useState)({ x: 0, y: 0 });
|
|
20893
|
+
const [uncontrolledCollapsed, setUncontrolledCollapsed] = (0, import_react67.useState)(false);
|
|
20894
|
+
const dragRef = (0, import_react67.useRef)(null);
|
|
20895
|
+
const panAnimRef = (0, import_react67.useRef)(null);
|
|
20896
|
+
const panRef = (0, import_react67.useRef)(pan);
|
|
20897
|
+
const scaleRef = (0, import_react67.useRef)(scale);
|
|
20898
|
+
const initialViewKeyRef = (0, import_react67.useRef)(null);
|
|
20193
20899
|
const spots = map.spots;
|
|
20194
20900
|
const iconSize = map.iconSize ?? DEFAULT_ICON_SIZE2;
|
|
20195
20901
|
const interaction = map.interaction ?? "fixed";
|
|
@@ -20207,15 +20913,15 @@ function PanoMap({
|
|
|
20207
20913
|
const collapseControl = showCollapseControl ?? map.controls?.collapse === true;
|
|
20208
20914
|
const collapsed = controlledCollapsed ?? uncontrolledCollapsed;
|
|
20209
20915
|
const editing = mode === "edit";
|
|
20210
|
-
const fit = (0,
|
|
20916
|
+
const fit = (0, import_react67.useMemo)(
|
|
20211
20917
|
() => containRect(size.width, size.height, imageSize2.width, imageSize2.height),
|
|
20212
20918
|
[size, imageSize2]
|
|
20213
20919
|
);
|
|
20214
|
-
const viewport = (0,
|
|
20920
|
+
const viewport = (0, import_react67.useMemo)(
|
|
20215
20921
|
() => ({ fit, scale, panX: pan.x, panY: pan.y }),
|
|
20216
20922
|
[fit, scale, pan]
|
|
20217
20923
|
);
|
|
20218
|
-
(0,
|
|
20924
|
+
(0, import_react67.useLayoutEffect)(() => {
|
|
20219
20925
|
if (collapsed) return;
|
|
20220
20926
|
const node = containerRef.current;
|
|
20221
20927
|
if (!node) return;
|
|
@@ -20232,7 +20938,7 @@ function PanoMap({
|
|
|
20232
20938
|
observer.observe(node);
|
|
20233
20939
|
return () => observer.disconnect();
|
|
20234
20940
|
}, [collapsed]);
|
|
20235
|
-
(0,
|
|
20941
|
+
(0, import_react67.useEffect)(() => {
|
|
20236
20942
|
yawRef.current = view.yaw;
|
|
20237
20943
|
const node = sectorNodeRef.current;
|
|
20238
20944
|
if (!node) return;
|
|
@@ -20249,7 +20955,7 @@ function PanoMap({
|
|
|
20249
20955
|
};
|
|
20250
20956
|
panRef.current = pan;
|
|
20251
20957
|
scaleRef.current = scale;
|
|
20252
|
-
const panBoundsFor = (0,
|
|
20958
|
+
const panBoundsFor = (0, import_react67.useCallback)(
|
|
20253
20959
|
(nextScale) => {
|
|
20254
20960
|
const width = fit.width * nextScale;
|
|
20255
20961
|
const height = fit.height * nextScale;
|
|
@@ -20265,7 +20971,7 @@ function PanoMap({
|
|
|
20265
20971
|
},
|
|
20266
20972
|
[fit, size]
|
|
20267
20973
|
);
|
|
20268
|
-
const clampPan = (0,
|
|
20974
|
+
const clampPan = (0, import_react67.useCallback)(
|
|
20269
20975
|
(nextScale, nextPan) => {
|
|
20270
20976
|
const bounds = panBoundsFor(nextScale);
|
|
20271
20977
|
return {
|
|
@@ -20275,14 +20981,14 @@ function PanoMap({
|
|
|
20275
20981
|
},
|
|
20276
20982
|
[panBoundsFor]
|
|
20277
20983
|
);
|
|
20278
|
-
const cancelPanAnimation = (0,
|
|
20984
|
+
const cancelPanAnimation = (0, import_react67.useCallback)(() => {
|
|
20279
20985
|
const anim = panAnimRef.current;
|
|
20280
20986
|
if (anim?.raf != null) {
|
|
20281
20987
|
cancelAnimationFrame(anim.raf);
|
|
20282
20988
|
}
|
|
20283
20989
|
panAnimRef.current = null;
|
|
20284
20990
|
}, []);
|
|
20285
|
-
const startPanAnimation = (0,
|
|
20991
|
+
const startPanAnimation = (0, import_react67.useCallback)(
|
|
20286
20992
|
(velocity) => {
|
|
20287
20993
|
cancelPanAnimation();
|
|
20288
20994
|
const current = panRef.current;
|
|
@@ -20342,11 +21048,11 @@ function PanoMap({
|
|
|
20342
21048
|
},
|
|
20343
21049
|
[cancelPanAnimation, clampPan, dragMotion.bounce, dragMotion.inertia, panBoundsFor]
|
|
20344
21050
|
);
|
|
20345
|
-
(0,
|
|
20346
|
-
(0,
|
|
21051
|
+
(0, import_react67.useEffect)(() => () => cancelPanAnimation(), [cancelPanAnimation]);
|
|
21052
|
+
(0, import_react67.useEffect)(() => {
|
|
20347
21053
|
if (collapsed) cancelPanAnimation();
|
|
20348
21054
|
}, [cancelPanAnimation, collapsed]);
|
|
20349
|
-
(0,
|
|
21055
|
+
(0, import_react67.useEffect)(() => {
|
|
20350
21056
|
if (!gestureZoom) {
|
|
20351
21057
|
initialViewKeyRef.current = null;
|
|
20352
21058
|
setScale(1);
|
|
@@ -20361,7 +21067,7 @@ function PanoMap({
|
|
|
20361
21067
|
return next;
|
|
20362
21068
|
});
|
|
20363
21069
|
}, [clampPan, gestureZoom, maxScale]);
|
|
20364
|
-
(0,
|
|
21070
|
+
(0, import_react67.useEffect)(() => {
|
|
20365
21071
|
if (!gestureZoom) return;
|
|
20366
21072
|
if (!(fit.width > 0) || !(fit.height > 0)) return;
|
|
20367
21073
|
if (!(size.width > 0) || !(size.height > 0)) return;
|
|
@@ -20388,7 +21094,7 @@ function PanoMap({
|
|
|
20388
21094
|
size.height,
|
|
20389
21095
|
size.width
|
|
20390
21096
|
]);
|
|
20391
|
-
const applyZoom = (0,
|
|
21097
|
+
const applyZoom = (0, import_react67.useCallback)(
|
|
20392
21098
|
(nextScale, origin) => {
|
|
20393
21099
|
if (!gestureZoom) return;
|
|
20394
21100
|
cancelPanAnimation();
|
|
@@ -20416,7 +21122,7 @@ function PanoMap({
|
|
|
20416
21122
|
size.width
|
|
20417
21123
|
]
|
|
20418
21124
|
);
|
|
20419
|
-
(0,
|
|
21125
|
+
(0, import_react67.useEffect)(() => {
|
|
20420
21126
|
const root = rootRef.current;
|
|
20421
21127
|
if (!root) return;
|
|
20422
21128
|
const onWheel = (event) => {
|
|
@@ -20838,7 +21544,7 @@ function PanoMap({
|
|
|
20838
21544
|
}
|
|
20839
21545
|
|
|
20840
21546
|
// src/map/pano-map-overlay.tsx
|
|
20841
|
-
var
|
|
21547
|
+
var import_react68 = require("react");
|
|
20842
21548
|
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
20843
21549
|
var DEFAULT_DIALOG_WIDTH = 720;
|
|
20844
21550
|
var DEFAULT_DIALOG_HEIGHT = 520;
|
|
@@ -20858,10 +21564,10 @@ function PanoMapDialogShell({
|
|
|
20858
21564
|
}) {
|
|
20859
21565
|
usePanoModal(open);
|
|
20860
21566
|
const { size } = usePanoOverlay();
|
|
20861
|
-
const titleId = (0,
|
|
20862
|
-
const panelRef = (0,
|
|
20863
|
-
const previouslyFocused = (0,
|
|
20864
|
-
(0,
|
|
21567
|
+
const titleId = (0, import_react68.useId)();
|
|
21568
|
+
const panelRef = (0, import_react68.useRef)(null);
|
|
21569
|
+
const previouslyFocused = (0, import_react68.useRef)(null);
|
|
21570
|
+
(0, import_react68.useEffect)(() => {
|
|
20865
21571
|
if (!open) return;
|
|
20866
21572
|
const active = panelRef.current?.ownerDocument.activeElement;
|
|
20867
21573
|
previouslyFocused.current = active instanceof HTMLElement ? active : null;
|
|
@@ -20979,8 +21685,8 @@ function PanoMapOverlay({
|
|
|
20979
21685
|
editorSurface = false
|
|
20980
21686
|
}) {
|
|
20981
21687
|
const { size } = usePanoOverlay();
|
|
20982
|
-
const [open, setOpen] = (0,
|
|
20983
|
-
const [collapsed, setCollapsed] = (0,
|
|
21688
|
+
const [open, setOpen] = (0, import_react68.useState)(false);
|
|
21689
|
+
const [collapsed, setCollapsed] = (0, import_react68.useState)(false);
|
|
20984
21690
|
const basePresentation = presentationOverride ?? map.presentation ?? {
|
|
20985
21691
|
mode: "docked",
|
|
20986
21692
|
corner: "bottom-left",
|
|
@@ -20995,7 +21701,7 @@ function PanoMapOverlay({
|
|
|
20995
21701
|
const offsetY = offsetYProp ?? basePresentation.offsetY ?? 16;
|
|
20996
21702
|
const width = widthProp ?? basePresentation.width ?? (presentationMode === "dialog" ? 48 : 220);
|
|
20997
21703
|
const height = heightProp ?? basePresentation.height ?? (presentationMode === "dialog" ? 48 : 160);
|
|
20998
|
-
const resolvedMap = (0,
|
|
21704
|
+
const resolvedMap = (0, import_react68.useMemo)(() => {
|
|
20999
21705
|
if (interaction === void 0 && maxScale === void 0 && iconSize === void 0) {
|
|
21000
21706
|
return map;
|
|
21001
21707
|
}
|
|
@@ -21023,7 +21729,7 @@ function PanoMapOverlay({
|
|
|
21023
21729
|
if (presentationMode === "dialog") setOpen(false);
|
|
21024
21730
|
}
|
|
21025
21731
|
};
|
|
21026
|
-
const editorBox = (0,
|
|
21732
|
+
const editorBox = (0, import_react68.useMemo)(() => {
|
|
21027
21733
|
const panelWidth2 = widthProp !== void 0 && Number.isFinite(widthProp) && widthProp > 0 ? widthProp : Math.min(420, Math.max(240, size.width * 0.45));
|
|
21028
21734
|
const panelHeight2 = heightProp !== void 0 && Number.isFinite(heightProp) && heightProp > 0 ? heightProp : Math.min(320, Math.max(180, size.height * 0.45));
|
|
21029
21735
|
return {
|
|
@@ -21124,6 +21830,7 @@ function PanoMapOverlay({
|
|
|
21124
21830
|
DEFAULT_PANO_VIDEO_PLAYBACK_RATES,
|
|
21125
21831
|
DEFAULT_WEBVR_CHROME_APPEARANCE,
|
|
21126
21832
|
DEFAULT_WEBVR_CURSOR_DWELL_MS,
|
|
21833
|
+
EMPTY_WEBVR_STATE,
|
|
21127
21834
|
GraphicHotspot,
|
|
21128
21835
|
Gyro,
|
|
21129
21836
|
IframeHotspot,
|
|
@@ -21138,6 +21845,7 @@ function PanoMapOverlay({
|
|
|
21138
21845
|
PanoFilter,
|
|
21139
21846
|
PanoMap,
|
|
21140
21847
|
PanoMapOverlay,
|
|
21848
|
+
PanoOverlay,
|
|
21141
21849
|
PanoOverlayPortalProvider,
|
|
21142
21850
|
PanoSceneMenu,
|
|
21143
21851
|
PanoVideo,
|