@ericchen1990/pano-view 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -28
- package/dist/index.cjs +84 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +31 -7
- package/dist/index.d.ts +31 -7
- package/dist/index.mjs +123 -60
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -790,14 +790,25 @@ declare function TouchControls({ enabled, rotateSpeed, invert, pinchZoom, }: Tou
|
|
|
790
790
|
|
|
791
791
|
type SphereProps = {
|
|
792
792
|
src: string;
|
|
793
|
+
/**
|
|
794
|
+
* Low-resolution 2:1 equirectangular image shown while `src` loads.
|
|
795
|
+
* Relative paths resolve against the directory of `src`. Root-absolute and
|
|
796
|
+
* `http(s)` / `blob:` / `data:` URLs are used as-is. For krpano sphere
|
|
797
|
+
* scenes, copy `<preview url>`.
|
|
798
|
+
*/
|
|
799
|
+
previewUrl: string;
|
|
793
800
|
/** Horizontal image offset in degrees. */
|
|
794
801
|
yawOffset?: number;
|
|
802
|
+
/** Called once the first paintable texture (preview or `src`) is ready. */
|
|
803
|
+
onReady?: () => void;
|
|
795
804
|
onLoad?: (texture: Texture) => void;
|
|
796
805
|
onError?: (error: unknown) => void;
|
|
806
|
+
/** Called when `previewUrl` cannot be loaded; `src` still continues. */
|
|
807
|
+
onPreviewError?: (error: unknown) => void;
|
|
797
808
|
/** Keeps the source mounted for preloading without drawing it. */
|
|
798
809
|
visible?: boolean;
|
|
799
810
|
};
|
|
800
|
-
declare function Sphere({ src, yawOffset, onLoad, onError, visible, }: SphereProps): react.JSX.Element | null;
|
|
811
|
+
declare function Sphere({ src, previewUrl, yawOffset, onReady, onLoad, onError, onPreviewError, visible, }: SphereProps): react.JSX.Element | null;
|
|
801
812
|
|
|
802
813
|
type VideoPlaybackState = "playing" | "paused" | "ended" | "blocked";
|
|
803
814
|
type VideoHotspotErrorEvent = {
|
|
@@ -1001,18 +1012,30 @@ type TileLoadError = {
|
|
|
1001
1012
|
};
|
|
1002
1013
|
type TileProps = {
|
|
1003
1014
|
baseUrl: string;
|
|
1015
|
+
/**
|
|
1016
|
+
* Tile size followed by ascending cube-face sizes (`TILESIZE,LEVELSIZE1,...`).
|
|
1017
|
+
* For krpano output, copy `image.cube.multires` from the XML.
|
|
1018
|
+
*/
|
|
1004
1019
|
multires: string | TileMultiresConfig;
|
|
1005
|
-
/**
|
|
1006
|
-
|
|
1020
|
+
/**
|
|
1021
|
+
* Preview atlas path. Relative paths resolve against `baseUrl`; root-absolute
|
|
1022
|
+
* and `http(s)` / `blob:` / `data:` URLs are used as-is. For krpano output,
|
|
1023
|
+
* copy `<preview url>` (often `preview.jpg` at the scene root). This package's
|
|
1024
|
+
* common cube atlas path is `previews/cube-vertical.webp`.
|
|
1025
|
+
*/
|
|
1026
|
+
previewUrl: string;
|
|
1007
1027
|
/**
|
|
1008
1028
|
* Face order in the vertical preview atlas, from top to bottom. Defaults to
|
|
1009
|
-
* `l/f/r/b/u/d`.
|
|
1029
|
+
* `l/f/r/b/u/d`, matching krpano `preview.striporder` `LFRBUD`.
|
|
1010
1030
|
*/
|
|
1011
1031
|
previewFaceOrder?: readonly CubeFaceCode[];
|
|
1012
1032
|
/**
|
|
1013
|
-
*
|
|
1014
|
-
*
|
|
1015
|
-
*
|
|
1033
|
+
* Path relative to `baseUrl`. Defaults to
|
|
1034
|
+
* `tiles/%s/l%l/%v/l%l_%s_%h_%v.webp`. For krpano output, copy `<cube url>`
|
|
1035
|
+
* from the XML; krpano templates often use `%v_%h` instead of this default
|
|
1036
|
+
* `%h_%v`, so omitting `urlTemplate` requests the wrong files. Supports
|
|
1037
|
+
* krpano cube-tile `%s` and `%l` placeholders, horizontal `%h`/`%x`/`%u`/`%c`,
|
|
1038
|
+
* vertical `%v`/`%y`/`%w`/`%r`, and index padding such as `%0h` or `%00v`.
|
|
1016
1039
|
*/
|
|
1017
1040
|
urlTemplate?: string;
|
|
1018
1041
|
/** Returns a path relative to `baseUrl`; takes precedence over `urlTemplate`. */
|
|
@@ -1040,6 +1063,7 @@ type SphereScene = {
|
|
|
1040
1063
|
id: string;
|
|
1041
1064
|
type: "sphere";
|
|
1042
1065
|
src: string;
|
|
1066
|
+
previewUrl: string;
|
|
1043
1067
|
yawOffset?: number;
|
|
1044
1068
|
};
|
|
1045
1069
|
type TileScene = Omit<TileProps, "loadMode" | "visible" | "onReady" | "onPreviewError" | "onLoadProgress" | "onTileError" | "onLevelChange"> & {
|
package/dist/index.d.ts
CHANGED
|
@@ -790,14 +790,25 @@ declare function TouchControls({ enabled, rotateSpeed, invert, pinchZoom, }: Tou
|
|
|
790
790
|
|
|
791
791
|
type SphereProps = {
|
|
792
792
|
src: string;
|
|
793
|
+
/**
|
|
794
|
+
* Low-resolution 2:1 equirectangular image shown while `src` loads.
|
|
795
|
+
* Relative paths resolve against the directory of `src`. Root-absolute and
|
|
796
|
+
* `http(s)` / `blob:` / `data:` URLs are used as-is. For krpano sphere
|
|
797
|
+
* scenes, copy `<preview url>`.
|
|
798
|
+
*/
|
|
799
|
+
previewUrl: string;
|
|
793
800
|
/** Horizontal image offset in degrees. */
|
|
794
801
|
yawOffset?: number;
|
|
802
|
+
/** Called once the first paintable texture (preview or `src`) is ready. */
|
|
803
|
+
onReady?: () => void;
|
|
795
804
|
onLoad?: (texture: Texture) => void;
|
|
796
805
|
onError?: (error: unknown) => void;
|
|
806
|
+
/** Called when `previewUrl` cannot be loaded; `src` still continues. */
|
|
807
|
+
onPreviewError?: (error: unknown) => void;
|
|
797
808
|
/** Keeps the source mounted for preloading without drawing it. */
|
|
798
809
|
visible?: boolean;
|
|
799
810
|
};
|
|
800
|
-
declare function Sphere({ src, yawOffset, onLoad, onError, visible, }: SphereProps): react.JSX.Element | null;
|
|
811
|
+
declare function Sphere({ src, previewUrl, yawOffset, onReady, onLoad, onError, onPreviewError, visible, }: SphereProps): react.JSX.Element | null;
|
|
801
812
|
|
|
802
813
|
type VideoPlaybackState = "playing" | "paused" | "ended" | "blocked";
|
|
803
814
|
type VideoHotspotErrorEvent = {
|
|
@@ -1001,18 +1012,30 @@ type TileLoadError = {
|
|
|
1001
1012
|
};
|
|
1002
1013
|
type TileProps = {
|
|
1003
1014
|
baseUrl: string;
|
|
1015
|
+
/**
|
|
1016
|
+
* Tile size followed by ascending cube-face sizes (`TILESIZE,LEVELSIZE1,...`).
|
|
1017
|
+
* For krpano output, copy `image.cube.multires` from the XML.
|
|
1018
|
+
*/
|
|
1004
1019
|
multires: string | TileMultiresConfig;
|
|
1005
|
-
/**
|
|
1006
|
-
|
|
1020
|
+
/**
|
|
1021
|
+
* Preview atlas path. Relative paths resolve against `baseUrl`; root-absolute
|
|
1022
|
+
* and `http(s)` / `blob:` / `data:` URLs are used as-is. For krpano output,
|
|
1023
|
+
* copy `<preview url>` (often `preview.jpg` at the scene root). This package's
|
|
1024
|
+
* common cube atlas path is `previews/cube-vertical.webp`.
|
|
1025
|
+
*/
|
|
1026
|
+
previewUrl: string;
|
|
1007
1027
|
/**
|
|
1008
1028
|
* Face order in the vertical preview atlas, from top to bottom. Defaults to
|
|
1009
|
-
* `l/f/r/b/u/d`.
|
|
1029
|
+
* `l/f/r/b/u/d`, matching krpano `preview.striporder` `LFRBUD`.
|
|
1010
1030
|
*/
|
|
1011
1031
|
previewFaceOrder?: readonly CubeFaceCode[];
|
|
1012
1032
|
/**
|
|
1013
|
-
*
|
|
1014
|
-
*
|
|
1015
|
-
*
|
|
1033
|
+
* Path relative to `baseUrl`. Defaults to
|
|
1034
|
+
* `tiles/%s/l%l/%v/l%l_%s_%h_%v.webp`. For krpano output, copy `<cube url>`
|
|
1035
|
+
* from the XML; krpano templates often use `%v_%h` instead of this default
|
|
1036
|
+
* `%h_%v`, so omitting `urlTemplate` requests the wrong files. Supports
|
|
1037
|
+
* krpano cube-tile `%s` and `%l` placeholders, horizontal `%h`/`%x`/`%u`/`%c`,
|
|
1038
|
+
* vertical `%v`/`%y`/`%w`/`%r`, and index padding such as `%0h` or `%00v`.
|
|
1016
1039
|
*/
|
|
1017
1040
|
urlTemplate?: string;
|
|
1018
1041
|
/** Returns a path relative to `baseUrl`; takes precedence over `urlTemplate`. */
|
|
@@ -1040,6 +1063,7 @@ type SphereScene = {
|
|
|
1040
1063
|
id: string;
|
|
1041
1064
|
type: "sphere";
|
|
1042
1065
|
src: string;
|
|
1066
|
+
previewUrl: string;
|
|
1043
1067
|
yawOffset?: number;
|
|
1044
1068
|
};
|
|
1045
1069
|
type TileScene = Omit<TileProps, "loadMode" | "visible" | "onReady" | "onPreviewError" | "onLoadProgress" | "onTileError" | "onLevelChange"> & {
|
package/dist/index.mjs
CHANGED
|
@@ -6369,7 +6369,7 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
6369
6369
|
|
|
6370
6370
|
// src/sphere.tsx
|
|
6371
6371
|
import { useThree as useThree13 } from "@react-three/fiber";
|
|
6372
|
-
import { useEffect as useEffect19, useRef as useRef19, useState as useState8 } from "react";
|
|
6372
|
+
import { useEffect as useEffect19, useMemo as useMemo12, useRef as useRef19, useState as useState8 } from "react";
|
|
6373
6373
|
import {
|
|
6374
6374
|
BackSide as BackSide2,
|
|
6375
6375
|
LinearFilter,
|
|
@@ -6380,6 +6380,27 @@ import {
|
|
|
6380
6380
|
TextureLoader
|
|
6381
6381
|
} from "three";
|
|
6382
6382
|
|
|
6383
|
+
// src/asset-url.ts
|
|
6384
|
+
function isAbsoluteAssetUrl(url) {
|
|
6385
|
+
return url.startsWith("/") || url.startsWith("//") || /^[a-z][a-z0-9+.-]*:/i.test(url);
|
|
6386
|
+
}
|
|
6387
|
+
function resolveRelativeAssetUrl(baseUrl, relativePath) {
|
|
6388
|
+
const normalizedBaseUrl = baseUrl.replace(/\/+$/, "");
|
|
6389
|
+
const normalizedPath = relativePath.replace(/^\/+/, "");
|
|
6390
|
+
return normalizedBaseUrl ? `${normalizedBaseUrl}/${normalizedPath}` : normalizedPath;
|
|
6391
|
+
}
|
|
6392
|
+
function resolveAssetUrl(baseUrl, path) {
|
|
6393
|
+
return isAbsoluteAssetUrl(path) ? path : resolveRelativeAssetUrl(baseUrl, path);
|
|
6394
|
+
}
|
|
6395
|
+
function resolveUrlAgainstFile(fileUrl, path) {
|
|
6396
|
+
if (isAbsoluteAssetUrl(path)) {
|
|
6397
|
+
return path;
|
|
6398
|
+
}
|
|
6399
|
+
const slash = fileUrl.lastIndexOf("/");
|
|
6400
|
+
const directory = slash === -1 ? "" : fileUrl.slice(0, slash);
|
|
6401
|
+
return resolveRelativeAssetUrl(directory, path);
|
|
6402
|
+
}
|
|
6403
|
+
|
|
6383
6404
|
// src/pano-filter/pano-basic-material.tsx
|
|
6384
6405
|
import { useLayoutEffect as useLayoutEffect2, useMemo as useMemo11, useRef as useRef18 } from "react";
|
|
6385
6406
|
|
|
@@ -6596,25 +6617,22 @@ function PanoBasicMaterial({
|
|
|
6596
6617
|
|
|
6597
6618
|
// src/sphere.tsx
|
|
6598
6619
|
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
6599
|
-
function
|
|
6600
|
-
src,
|
|
6601
|
-
yawOffset = 0,
|
|
6602
|
-
onLoad,
|
|
6603
|
-
onError,
|
|
6604
|
-
visible = true
|
|
6605
|
-
}) {
|
|
6606
|
-
const gl = useThree13((state) => state.gl);
|
|
6620
|
+
function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
6607
6621
|
const [texture, setTexture] = useState8(null);
|
|
6608
6622
|
const onLoadRef = useRef19(onLoad);
|
|
6609
6623
|
const onErrorRef = useRef19(onError);
|
|
6610
6624
|
onLoadRef.current = onLoad;
|
|
6611
6625
|
onErrorRef.current = onError;
|
|
6612
6626
|
useEffect19(() => {
|
|
6627
|
+
if (!url) {
|
|
6628
|
+
setTexture(null);
|
|
6629
|
+
return;
|
|
6630
|
+
}
|
|
6613
6631
|
let active = true;
|
|
6614
6632
|
const loader = new TextureLoader();
|
|
6615
6633
|
setTexture(null);
|
|
6616
6634
|
loader.load(
|
|
6617
|
-
|
|
6635
|
+
url,
|
|
6618
6636
|
(loadedTexture) => {
|
|
6619
6637
|
if (!active) {
|
|
6620
6638
|
loadedTexture.dispose();
|
|
@@ -6624,10 +6642,10 @@ function Sphere({
|
|
|
6624
6642
|
loadedTexture.wrapS = RepeatWrapping;
|
|
6625
6643
|
loadedTexture.repeat.x = -1;
|
|
6626
6644
|
loadedTexture.offset.x = 1;
|
|
6627
|
-
loadedTexture.anisotropy =
|
|
6645
|
+
loadedTexture.anisotropy = anisotropy;
|
|
6628
6646
|
loadedTexture.magFilter = LinearFilter;
|
|
6629
|
-
loadedTexture.minFilter = LinearMipmapLinearFilter;
|
|
6630
|
-
loadedTexture.generateMipmaps =
|
|
6647
|
+
loadedTexture.minFilter = generateMipmaps ? LinearMipmapLinearFilter : LinearFilter;
|
|
6648
|
+
loadedTexture.generateMipmaps = generateMipmaps;
|
|
6631
6649
|
loadedTexture.needsUpdate = true;
|
|
6632
6650
|
setTexture(loadedTexture);
|
|
6633
6651
|
onLoadRef.current?.(loadedTexture);
|
|
@@ -6635,6 +6653,7 @@ function Sphere({
|
|
|
6635
6653
|
void 0,
|
|
6636
6654
|
(error) => {
|
|
6637
6655
|
if (active) {
|
|
6656
|
+
setTexture(null);
|
|
6638
6657
|
onErrorRef.current?.(error);
|
|
6639
6658
|
}
|
|
6640
6659
|
}
|
|
@@ -6642,14 +6661,58 @@ function Sphere({
|
|
|
6642
6661
|
return () => {
|
|
6643
6662
|
active = false;
|
|
6644
6663
|
};
|
|
6645
|
-
}, [
|
|
6664
|
+
}, [anisotropy, generateMipmaps, url]);
|
|
6646
6665
|
useEffect19(
|
|
6647
6666
|
() => () => {
|
|
6648
6667
|
texture?.dispose();
|
|
6649
6668
|
},
|
|
6650
6669
|
[texture]
|
|
6651
6670
|
);
|
|
6652
|
-
|
|
6671
|
+
return texture;
|
|
6672
|
+
}
|
|
6673
|
+
function Sphere({
|
|
6674
|
+
src,
|
|
6675
|
+
previewUrl,
|
|
6676
|
+
yawOffset = 0,
|
|
6677
|
+
onReady,
|
|
6678
|
+
onLoad,
|
|
6679
|
+
onError,
|
|
6680
|
+
onPreviewError,
|
|
6681
|
+
visible = true
|
|
6682
|
+
}) {
|
|
6683
|
+
const gl = useThree13((state) => state.gl);
|
|
6684
|
+
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
6685
|
+
const resolvedPreviewUrl = useMemo12(
|
|
6686
|
+
() => resolveUrlAgainstFile(src, previewUrl),
|
|
6687
|
+
[previewUrl, src]
|
|
6688
|
+
);
|
|
6689
|
+
const texture = useEquirectTexture(
|
|
6690
|
+
src,
|
|
6691
|
+
anisotropy,
|
|
6692
|
+
true,
|
|
6693
|
+
onLoad,
|
|
6694
|
+
onError
|
|
6695
|
+
);
|
|
6696
|
+
const previewTexture = useEquirectTexture(
|
|
6697
|
+
texture ? null : resolvedPreviewUrl,
|
|
6698
|
+
anisotropy,
|
|
6699
|
+
false,
|
|
6700
|
+
void 0,
|
|
6701
|
+
onPreviewError
|
|
6702
|
+
);
|
|
6703
|
+
const displayTexture = texture ?? previewTexture;
|
|
6704
|
+
const readyRef = useRef19(false);
|
|
6705
|
+
useEffect19(() => {
|
|
6706
|
+
readyRef.current = false;
|
|
6707
|
+
}, [resolvedPreviewUrl, src]);
|
|
6708
|
+
useEffect19(() => {
|
|
6709
|
+
if (!displayTexture || readyRef.current) {
|
|
6710
|
+
return;
|
|
6711
|
+
}
|
|
6712
|
+
readyRef.current = true;
|
|
6713
|
+
onReady?.();
|
|
6714
|
+
}, [displayTexture, onReady]);
|
|
6715
|
+
if (!displayTexture) {
|
|
6653
6716
|
return null;
|
|
6654
6717
|
}
|
|
6655
6718
|
return /* @__PURE__ */ jsxs9(
|
|
@@ -6662,7 +6725,7 @@ function Sphere({
|
|
|
6662
6725
|
/* @__PURE__ */ jsx15(
|
|
6663
6726
|
PanoBasicMaterial,
|
|
6664
6727
|
{
|
|
6665
|
-
map:
|
|
6728
|
+
map: displayTexture,
|
|
6666
6729
|
side: BackSide2,
|
|
6667
6730
|
toneMapped: false
|
|
6668
6731
|
}
|
|
@@ -6679,7 +6742,7 @@ import {
|
|
|
6679
6742
|
useContext as useContext19,
|
|
6680
6743
|
useEffect as useEffect20,
|
|
6681
6744
|
useLayoutEffect as useLayoutEffect3,
|
|
6682
|
-
useMemo as
|
|
6745
|
+
useMemo as useMemo13,
|
|
6683
6746
|
useRef as useRef20,
|
|
6684
6747
|
useState as useState9
|
|
6685
6748
|
} from "react";
|
|
@@ -6878,13 +6941,13 @@ function PanoVideo({
|
|
|
6878
6941
|
const gl = useThree14((state) => state.gl);
|
|
6879
6942
|
const host = useContext19(PanoVideoHostContext);
|
|
6880
6943
|
const overlay = useContext19(PanoChromeOverlayContext);
|
|
6881
|
-
const variants =
|
|
6944
|
+
const variants = useMemo13(
|
|
6882
6945
|
() => resolvePanoVideoVariants({ poster, src, variants: variantsProp }),
|
|
6883
6946
|
[poster, src, variantsProp]
|
|
6884
6947
|
);
|
|
6885
6948
|
const tracks = tracksProp ?? EMPTY_TRACKS;
|
|
6886
6949
|
const captionsEnabled = captions !== false;
|
|
6887
|
-
const captionAppearance =
|
|
6950
|
+
const captionAppearance = useMemo13(
|
|
6888
6951
|
() => resolvePanoVideoCaptionAppearance(
|
|
6889
6952
|
typeof captions === "object" ? captions : void 0
|
|
6890
6953
|
),
|
|
@@ -6949,7 +7012,7 @@ function PanoVideo({
|
|
|
6949
7012
|
onEndedRef.current = onEnded;
|
|
6950
7013
|
onVariantChangeRef.current = onVariantChange;
|
|
6951
7014
|
onTrackChangeRef.current = onTrackChange;
|
|
6952
|
-
const resource =
|
|
7015
|
+
const resource = useMemo13(() => {
|
|
6953
7016
|
if (typeof document === "undefined") {
|
|
6954
7017
|
return null;
|
|
6955
7018
|
}
|
|
@@ -7062,7 +7125,7 @@ function PanoVideo({
|
|
|
7062
7125
|
captionAppearance
|
|
7063
7126
|
]
|
|
7064
7127
|
);
|
|
7065
|
-
const controller =
|
|
7128
|
+
const controller = useMemo13(
|
|
7066
7129
|
() => ({
|
|
7067
7130
|
subscribe: (onStoreChange) => {
|
|
7068
7131
|
const store = storeRef.current;
|
|
@@ -7429,7 +7492,7 @@ import {
|
|
|
7429
7492
|
useCallback as useCallback10,
|
|
7430
7493
|
useContext as useContext21,
|
|
7431
7494
|
useEffect as useEffect25,
|
|
7432
|
-
useMemo as
|
|
7495
|
+
useMemo as useMemo18,
|
|
7433
7496
|
useRef as useRef24,
|
|
7434
7497
|
useState as useState11
|
|
7435
7498
|
} from "react";
|
|
@@ -7487,7 +7550,7 @@ function isSnapshotTransition(preset) {
|
|
|
7487
7550
|
|
|
7488
7551
|
// src/scene-transitions/particle-overlay.tsx
|
|
7489
7552
|
import { useFrame as useFrame9, useThree as useThree15 } from "@react-three/fiber";
|
|
7490
|
-
import { useEffect as useEffect21, useMemo as
|
|
7553
|
+
import { useEffect as useEffect21, useMemo as useMemo14, useRef as useRef21 } from "react";
|
|
7491
7554
|
import {
|
|
7492
7555
|
DoubleSide as DoubleSide2,
|
|
7493
7556
|
InstancedBufferAttribute,
|
|
@@ -7631,8 +7694,8 @@ function ParticleOverlay({
|
|
|
7631
7694
|
const startRef = useRef21(null);
|
|
7632
7695
|
const finishedRef = useRef21(false);
|
|
7633
7696
|
const directionRef = useRef21(new Vector38());
|
|
7634
|
-
const geometry =
|
|
7635
|
-
const material =
|
|
7697
|
+
const geometry = useMemo14(() => createParticleGeometry(), []);
|
|
7698
|
+
const material = useMemo14(
|
|
7636
7699
|
() => new ShaderMaterial2({
|
|
7637
7700
|
transparent: true,
|
|
7638
7701
|
depthTest: false,
|
|
@@ -7686,7 +7749,7 @@ function ParticleOverlay({
|
|
|
7686
7749
|
|
|
7687
7750
|
// src/scene-transitions/snapshot-overlay.tsx
|
|
7688
7751
|
import { useFrame as useFrame10, useThree as useThree16 } from "@react-three/fiber";
|
|
7689
|
-
import { useEffect as useEffect22, useMemo as
|
|
7752
|
+
import { useEffect as useEffect22, useMemo as useMemo15, useRef as useRef22 } from "react";
|
|
7690
7753
|
import { Vector3 as Vector39 } from "three";
|
|
7691
7754
|
|
|
7692
7755
|
// src/scene-transitions/snapshot-shaders.ts
|
|
@@ -7979,7 +8042,7 @@ function SnapshotOverlay({
|
|
|
7979
8042
|
const startRef = useRef22(null);
|
|
7980
8043
|
const finishedRef = useRef22(false);
|
|
7981
8044
|
const directionRef = useRef22(new Vector39());
|
|
7982
|
-
const material =
|
|
8045
|
+
const material = useMemo15(() => {
|
|
7983
8046
|
if (!isSnapshotTransition(transition.preset)) {
|
|
7984
8047
|
return null;
|
|
7985
8048
|
}
|
|
@@ -8072,7 +8135,7 @@ import {
|
|
|
8072
8135
|
createContext as createContext11,
|
|
8073
8136
|
useContext as useContext20,
|
|
8074
8137
|
useEffect as useEffect23,
|
|
8075
|
-
useMemo as
|
|
8138
|
+
useMemo as useMemo16
|
|
8076
8139
|
} from "react";
|
|
8077
8140
|
|
|
8078
8141
|
// src/tile/texture-manager.ts
|
|
@@ -8313,7 +8376,7 @@ function TileTextureManagerProvider({
|
|
|
8313
8376
|
}) {
|
|
8314
8377
|
const gl = useThree17((state) => state.gl);
|
|
8315
8378
|
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
8316
|
-
const manager =
|
|
8379
|
+
const manager = useMemo16(
|
|
8317
8380
|
() => new TileTextureManager({
|
|
8318
8381
|
anisotropy,
|
|
8319
8382
|
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
@@ -8337,7 +8400,7 @@ import { useFrame as useFrame11, useThree as useThree18 } from "@react-three/fib
|
|
|
8337
8400
|
import {
|
|
8338
8401
|
memo,
|
|
8339
8402
|
useEffect as useEffect24,
|
|
8340
|
-
useMemo as
|
|
8403
|
+
useMemo as useMemo17,
|
|
8341
8404
|
useRef as useRef23,
|
|
8342
8405
|
useState as useState10
|
|
8343
8406
|
} from "react";
|
|
@@ -8520,13 +8583,12 @@ function parseMultires(multires) {
|
|
|
8520
8583
|
);
|
|
8521
8584
|
return { tileSize, levels };
|
|
8522
8585
|
}
|
|
8586
|
+
var DEFAULT_TILE_URL_TEMPLATE = "tiles/%s/l%l/%v/l%l_%s_%h_%v.webp";
|
|
8523
8587
|
function buildDefaultTileUrlTemplate() {
|
|
8524
|
-
return
|
|
8588
|
+
return DEFAULT_TILE_URL_TEMPLATE;
|
|
8525
8589
|
}
|
|
8526
8590
|
function resolveRelativeTileUrl(baseUrl, relativePath) {
|
|
8527
|
-
|
|
8528
|
-
const normalizedPath = relativePath.replace(/^\/+/, "");
|
|
8529
|
-
return normalizedBaseUrl ? `${normalizedBaseUrl}/${normalizedPath}` : normalizedPath;
|
|
8591
|
+
return resolveRelativeAssetUrl(baseUrl, relativePath);
|
|
8530
8592
|
}
|
|
8531
8593
|
function resolveTemplateUrl(template, address) {
|
|
8532
8594
|
return template.replace(/%s/g, address.face).replace(/%l/g, String(address.level)).replace(/%(0*)([hxucvywr])/g, (_match, zeroes, placeholder) => {
|
|
@@ -8598,7 +8660,7 @@ function PreviewFace({
|
|
|
8598
8660
|
texture,
|
|
8599
8661
|
faceOrder
|
|
8600
8662
|
}) {
|
|
8601
|
-
const geometry =
|
|
8663
|
+
const geometry = useMemo17(() => {
|
|
8602
8664
|
const nextGeometry = new PlaneGeometry4(
|
|
8603
8665
|
PREVIEW_RADIUS * 2,
|
|
8604
8666
|
PREVIEW_RADIUS * 2
|
|
@@ -8884,15 +8946,15 @@ function Tile({
|
|
|
8884
8946
|
onLevelChange
|
|
8885
8947
|
}) {
|
|
8886
8948
|
const { camera, gl, size } = useThree18();
|
|
8887
|
-
const multiresConfig =
|
|
8949
|
+
const multiresConfig = useMemo17(() => parseMultires(multires), [multires]);
|
|
8888
8950
|
const { levels, tileSize } = multiresConfig;
|
|
8889
8951
|
const multiresToken = `${tileSize}:${levels.join(",")}`;
|
|
8890
|
-
const candidatesByLevel =
|
|
8952
|
+
const candidatesByLevel = useMemo17(
|
|
8891
8953
|
() => buildTileCandidates(levels, tileSize),
|
|
8892
8954
|
[levels, tileSize]
|
|
8893
8955
|
);
|
|
8894
8956
|
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
8895
|
-
const effectivePreviewUrl =
|
|
8957
|
+
const effectivePreviewUrl = resolveAssetUrl(baseUrl, previewUrl);
|
|
8896
8958
|
const previewTexture = usePreviewTexture(
|
|
8897
8959
|
effectivePreviewUrl,
|
|
8898
8960
|
anisotropy,
|
|
@@ -8905,7 +8967,7 @@ function Tile({
|
|
|
8905
8967
|
progressRef.current = onLoadProgress;
|
|
8906
8968
|
errorRef.current = onTileError;
|
|
8907
8969
|
levelChangeRef.current = onLevelChange;
|
|
8908
|
-
const ownedManager =
|
|
8970
|
+
const ownedManager = useMemo17(
|
|
8909
8971
|
() => new TileTextureManager({
|
|
8910
8972
|
anisotropy,
|
|
8911
8973
|
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
@@ -8948,7 +9010,7 @@ function Tile({
|
|
|
8948
9010
|
onReady?.();
|
|
8949
9011
|
}, [onReady, previewTexture]);
|
|
8950
9012
|
const template = urlTemplate ?? buildDefaultTileUrlTemplate();
|
|
8951
|
-
const resolveUrl =
|
|
9013
|
+
const resolveUrl = useMemo17(
|
|
8952
9014
|
() => (address) => {
|
|
8953
9015
|
const relativePath = resolveTileUrl ? resolveTileUrl(address) : resolveTemplateUrl(template, address);
|
|
8954
9016
|
return resolveRelativeTileUrl(baseUrl, relativePath);
|
|
@@ -9090,9 +9152,10 @@ function SceneSource({
|
|
|
9090
9152
|
Sphere,
|
|
9091
9153
|
{
|
|
9092
9154
|
src: scene.src,
|
|
9155
|
+
previewUrl: scene.previewUrl,
|
|
9093
9156
|
yawOffset: scene.yawOffset,
|
|
9094
9157
|
visible,
|
|
9095
|
-
|
|
9158
|
+
onReady,
|
|
9096
9159
|
onError
|
|
9097
9160
|
}
|
|
9098
9161
|
);
|
|
@@ -9181,11 +9244,11 @@ function ScenesController({
|
|
|
9181
9244
|
}) {
|
|
9182
9245
|
const controlsRef = useContext21(PanoramaViewContext);
|
|
9183
9246
|
const manager = useSharedTileTextureManager();
|
|
9184
|
-
const transition =
|
|
9247
|
+
const transition = useMemo18(
|
|
9185
9248
|
() => resolveTransition(transitionInput),
|
|
9186
9249
|
[transitionInput]
|
|
9187
9250
|
);
|
|
9188
|
-
const sceneMap =
|
|
9251
|
+
const sceneMap = useMemo18(
|
|
9189
9252
|
() => new Map(scenes.map((scene) => [scene.id, scene])),
|
|
9190
9253
|
[scenes]
|
|
9191
9254
|
);
|
|
@@ -9435,7 +9498,7 @@ import {
|
|
|
9435
9498
|
useContext as useContext23,
|
|
9436
9499
|
useEffect as useEffect27,
|
|
9437
9500
|
useLayoutEffect as useLayoutEffect4,
|
|
9438
|
-
useMemo as
|
|
9501
|
+
useMemo as useMemo20,
|
|
9439
9502
|
useRef as useRef25,
|
|
9440
9503
|
useState as useState13
|
|
9441
9504
|
} from "react";
|
|
@@ -9453,7 +9516,7 @@ import {
|
|
|
9453
9516
|
} from "three";
|
|
9454
9517
|
|
|
9455
9518
|
// src/hotspot/hotspot-tooltip.tsx
|
|
9456
|
-
import { useEffect as useEffect26, useMemo as
|
|
9519
|
+
import { useEffect as useEffect26, useMemo as useMemo19, useState as useState12 } from "react";
|
|
9457
9520
|
|
|
9458
9521
|
// src/webvr/stereo-html.tsx
|
|
9459
9522
|
import { Html } from "@react-three/drei";
|
|
@@ -9581,11 +9644,11 @@ function HotspotTooltip({
|
|
|
9581
9644
|
setImageFailed(false);
|
|
9582
9645
|
}, [content.image]);
|
|
9583
9646
|
const showImage = Boolean(content.image) && !imageFailed;
|
|
9584
|
-
const resolvedAppearance =
|
|
9647
|
+
const resolvedAppearance = useMemo19(
|
|
9585
9648
|
() => resolveHotspotTooltipAppearance(appearance),
|
|
9586
9649
|
[appearance]
|
|
9587
9650
|
);
|
|
9588
|
-
const bubbleStyle =
|
|
9651
|
+
const bubbleStyle = useMemo19(
|
|
9589
9652
|
() => ({
|
|
9590
9653
|
background: resolvedAppearance.background,
|
|
9591
9654
|
border: resolvedAppearance.border,
|
|
@@ -9975,7 +10038,7 @@ function HotspotAnchor({
|
|
|
9975
10038
|
const [hovered, setHovered] = useState13(false);
|
|
9976
10039
|
const [dragging, setDragging] = useState13(false);
|
|
9977
10040
|
const [pinned, setPinned] = useState13(false);
|
|
9978
|
-
const tooltipContent =
|
|
10041
|
+
const tooltipContent = useMemo20(
|
|
9979
10042
|
() => resolveHotspotTooltipContent(tooltip),
|
|
9980
10043
|
[tooltip]
|
|
9981
10044
|
);
|
|
@@ -9991,17 +10054,17 @@ function HotspotAnchor({
|
|
|
9991
10054
|
scaledWidth,
|
|
9992
10055
|
scaledHeight
|
|
9993
10056
|
);
|
|
9994
|
-
const worldPosition =
|
|
10057
|
+
const worldPosition = useMemo20(
|
|
9995
10058
|
() => panoPositionToVector3(normalizedPosition, resolvedDistance),
|
|
9996
10059
|
[normalizedPosition.pitch, normalizedPosition.yaw, resolvedDistance]
|
|
9997
10060
|
);
|
|
9998
|
-
const surfaceQuaternion3 =
|
|
10061
|
+
const surfaceQuaternion3 = useMemo20(
|
|
9999
10062
|
() => createSurfaceQuaternion(normalizedPosition),
|
|
10000
10063
|
[normalizedPosition.pitch, normalizedPosition.yaw]
|
|
10001
10064
|
);
|
|
10002
10065
|
const worldWidth = angularSizeToWorldSize(scaledWidth, resolvedDistance);
|
|
10003
10066
|
const worldHeight = angularSizeToWorldSize(scaledHeight, resolvedDistance);
|
|
10004
|
-
const focusGeometry =
|
|
10067
|
+
const focusGeometry = useMemo20(() => {
|
|
10005
10068
|
const planeGeometry = new PlaneGeometry5(1, 1);
|
|
10006
10069
|
const geometry = new EdgesGeometry(planeGeometry);
|
|
10007
10070
|
planeGeometry.dispose();
|
|
@@ -10487,7 +10550,7 @@ function ImageHotspot({
|
|
|
10487
10550
|
}
|
|
10488
10551
|
|
|
10489
10552
|
// src/hotspot/polygon-hotspot.tsx
|
|
10490
|
-
import { useEffect as useEffect29, useMemo as
|
|
10553
|
+
import { useEffect as useEffect29, useMemo as useMemo21, useRef as useRef28 } from "react";
|
|
10491
10554
|
import {
|
|
10492
10555
|
BufferGeometry,
|
|
10493
10556
|
DoubleSide as DoubleSide5,
|
|
@@ -10832,14 +10895,14 @@ function PolygonHotspot({
|
|
|
10832
10895
|
onInvalid,
|
|
10833
10896
|
...anchorProps
|
|
10834
10897
|
}) {
|
|
10835
|
-
const issues =
|
|
10898
|
+
const issues = useMemo21(() => validatePolygonVertices(vertices), [vertices]);
|
|
10836
10899
|
const valid = issues.length === 0;
|
|
10837
|
-
const center =
|
|
10838
|
-
const fillGeometry =
|
|
10900
|
+
const center = useMemo21(() => valid ? polygonCenter(vertices) : null, [valid, vertices]);
|
|
10901
|
+
const fillGeometry = useMemo21(
|
|
10839
10902
|
() => valid && center ? makeFillGeometry(vertices, center) : null,
|
|
10840
10903
|
[center, valid, vertices]
|
|
10841
10904
|
);
|
|
10842
|
-
const strokePoints =
|
|
10905
|
+
const strokePoints = useMemo21(
|
|
10843
10906
|
() => valid && center ? makeStrokePositions(vertices, center) : null,
|
|
10844
10907
|
[center, valid, vertices]
|
|
10845
10908
|
);
|
|
@@ -10929,7 +10992,7 @@ function PolygonHotspot({
|
|
|
10929
10992
|
}
|
|
10930
10993
|
|
|
10931
10994
|
// src/hotspot/polyline-hotspot.tsx
|
|
10932
|
-
import { useEffect as useEffect30, useMemo as
|
|
10995
|
+
import { useEffect as useEffect30, useMemo as useMemo22, useRef as useRef29 } from "react";
|
|
10933
10996
|
import {
|
|
10934
10997
|
MathUtils as MathUtils8,
|
|
10935
10998
|
Matrix4 as Matrix44,
|
|
@@ -11053,10 +11116,10 @@ function PolylineHotspot({
|
|
|
11053
11116
|
onInvalid,
|
|
11054
11117
|
...anchorProps
|
|
11055
11118
|
}) {
|
|
11056
|
-
const issues =
|
|
11119
|
+
const issues = useMemo22(() => validatePolylineVertices(vertices), [vertices]);
|
|
11057
11120
|
const valid = issues.length === 0;
|
|
11058
|
-
const center =
|
|
11059
|
-
const linePoints =
|
|
11121
|
+
const center = useMemo22(() => valid ? polylineCenter(vertices) : null, [valid, vertices]);
|
|
11122
|
+
const linePoints = useMemo22(
|
|
11060
11123
|
() => valid && center ? makeLinePositions(vertices, center) : null,
|
|
11061
11124
|
[center, valid, vertices]
|
|
11062
11125
|
);
|