@ericchen1990/pano-view 3.6.7 → 3.8.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 +6 -0
- package/README.zh-CN.md +6 -0
- package/dist/data.cjs +220 -7
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.mts +104 -2
- package/dist/data.d.ts +104 -2
- package/dist/data.mjs +220 -7
- package/dist/data.mjs.map +1 -1
- package/dist/index.cjs +2935 -1119
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +194 -2
- package/dist/index.d.ts +194 -2
- package/dist/index.mjs +2461 -638
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +179 -0
- package/dist/ui.cjs +1 -1
- package/dist/ui.cjs.map +1 -1
- package/dist/ui.mjs +1 -1
- package/dist/ui.mjs.map +1 -1
- package/package.json +1 -1
package/dist/data.d.ts
CHANGED
|
@@ -209,7 +209,7 @@ type SphereTileScene = Omit<SphereTileProps, "loadMode" | "visible" | "onReady"
|
|
|
209
209
|
|
|
210
210
|
type AssetUrlContext = {
|
|
211
211
|
defaultUrl: string;
|
|
212
|
-
kind: "tile" | "preview" | "hotspot";
|
|
212
|
+
kind: "tile" | "preview" | "hotspot" | "map";
|
|
213
213
|
sceneId: string;
|
|
214
214
|
hotspotId?: string;
|
|
215
215
|
};
|
|
@@ -531,6 +531,106 @@ type ProjectHotspotDefinition = HotspotDefinition & {
|
|
|
531
531
|
};
|
|
532
532
|
declare function resolveHotspotAssets(hotspot: ProjectHotspotDefinition, baseUrl: string, sceneId: string, resolver?: AssetUrlResolver): ProjectHotspotDefinition;
|
|
533
533
|
|
|
534
|
+
type PanoMapCorner = "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
|
535
|
+
type PanoMapGradientStop = {
|
|
536
|
+
offset: number;
|
|
537
|
+
color: string;
|
|
538
|
+
opacity?: number;
|
|
539
|
+
};
|
|
540
|
+
type PanoMapSectorGradient = {
|
|
541
|
+
type: "radial" | "linear";
|
|
542
|
+
stops: PanoMapGradientStop[];
|
|
543
|
+
};
|
|
544
|
+
type PanoMapSectorDefinition = {
|
|
545
|
+
/** Sector opening angle in degrees. */
|
|
546
|
+
angle: number;
|
|
547
|
+
/** Sector radius in CSS pixels; does not scale with the floor image. */
|
|
548
|
+
radius: number;
|
|
549
|
+
/** When true, sector angle follows the current horizontal FOV. */
|
|
550
|
+
followFov?: boolean;
|
|
551
|
+
/** Solid fill color when `gradient` is omitted. */
|
|
552
|
+
color?: string;
|
|
553
|
+
/**
|
|
554
|
+
* Overall fill opacity in [0, 1].
|
|
555
|
+
* Applies in both solid and gradient modes; gradient stop opacities only
|
|
556
|
+
* describe the relative fade shape and are normalized against this value.
|
|
557
|
+
*/
|
|
558
|
+
opacity?: number;
|
|
559
|
+
/** Optional sector outline color. */
|
|
560
|
+
strokeColor?: string;
|
|
561
|
+
/** Outline width in CSS pixels. */
|
|
562
|
+
strokeWidth?: number;
|
|
563
|
+
/** Outline opacity in [0, 1]. Defaults to 1 when stroke is set. */
|
|
564
|
+
strokeOpacity?: number;
|
|
565
|
+
/**
|
|
566
|
+
* Optional fill gradient. When omitted, the sector uses a solid `color`.
|
|
567
|
+
* Stop colors are independent of `color` unless the author keeps them in sync.
|
|
568
|
+
*/
|
|
569
|
+
gradient?: PanoMapSectorGradient;
|
|
570
|
+
};
|
|
571
|
+
type PanoMapSpotDefinition = {
|
|
572
|
+
id: string;
|
|
573
|
+
sceneId: string;
|
|
574
|
+
/** Normalized image X in [0, 1], origin at the top-left. */
|
|
575
|
+
x: number;
|
|
576
|
+
/** Normalized image Y in [0, 1], origin at the top-left. */
|
|
577
|
+
y: number;
|
|
578
|
+
/**
|
|
579
|
+
* Clockwise degrees from image up when viewer yaw is 0.
|
|
580
|
+
* Runtime sector rotation is `heading + yaw`.
|
|
581
|
+
*/
|
|
582
|
+
heading: number;
|
|
583
|
+
icon?: string;
|
|
584
|
+
};
|
|
585
|
+
type PanoMapControlsDefinition = {
|
|
586
|
+
/** Show expand/collapse on a docked panel. */
|
|
587
|
+
collapse?: boolean;
|
|
588
|
+
/** Show zoom-in and zoom-out buttons. */
|
|
589
|
+
zoom?: boolean;
|
|
590
|
+
};
|
|
591
|
+
type PanoMapDockedPresentation = {
|
|
592
|
+
mode: "docked";
|
|
593
|
+
corner?: PanoMapCorner;
|
|
594
|
+
width?: number;
|
|
595
|
+
height?: number;
|
|
596
|
+
offsetX?: number;
|
|
597
|
+
offsetY?: number;
|
|
598
|
+
};
|
|
599
|
+
type PanoMapDialogPresentation = {
|
|
600
|
+
mode: "dialog";
|
|
601
|
+
corner?: PanoMapCorner;
|
|
602
|
+
offsetX?: number;
|
|
603
|
+
offsetY?: number;
|
|
604
|
+
width?: number;
|
|
605
|
+
height?: number;
|
|
606
|
+
};
|
|
607
|
+
type PanoMapPresentation = PanoMapDockedPresentation | PanoMapDialogPresentation;
|
|
608
|
+
type PanoMapDefinition = {
|
|
609
|
+
image: string;
|
|
610
|
+
/**
|
|
611
|
+
* Pointer interaction with the floor image.
|
|
612
|
+
* - `fixed`: fit-only; no wheel/pan zoom (zoom buttons are also suppressed).
|
|
613
|
+
* - `zoom`: wheel/pan zoom and optional zoom buttons.
|
|
614
|
+
*/
|
|
615
|
+
interaction?: "fixed" | "zoom";
|
|
616
|
+
presentation?: PanoMapPresentation;
|
|
617
|
+
controls?: PanoMapControlsDefinition;
|
|
618
|
+
/** Spot icon edge length in CSS pixels. */
|
|
619
|
+
iconSize?: number;
|
|
620
|
+
/**
|
|
621
|
+
* Maximum zoom multiplier relative to the contain-fit scale.
|
|
622
|
+
* Only applies when `interaction` is `"zoom"`. Defaults to 8.
|
|
623
|
+
*/
|
|
624
|
+
maxScale?: number;
|
|
625
|
+
spots: PanoMapSpotDefinition[];
|
|
626
|
+
sector?: PanoMapSectorDefinition;
|
|
627
|
+
};
|
|
628
|
+
/** Parse an optional project floor plan. Scene IDs must already be collected. */
|
|
629
|
+
declare function parsePanoMap(value: unknown, sceneIds: Set<string>, options?: {
|
|
630
|
+
draft?: boolean;
|
|
631
|
+
}): PanoMapDefinition | undefined;
|
|
632
|
+
declare function resolvePanoMapAssets(map: PanoMapDefinition, baseUrl: string, resolveAssetUrl?: AssetUrlResolver): PanoMapDefinition;
|
|
633
|
+
|
|
534
634
|
type PanoProjectSceneDefinition = {
|
|
535
635
|
id: string;
|
|
536
636
|
title?: string;
|
|
@@ -553,6 +653,7 @@ type PanoProjectDefinition = {
|
|
|
553
653
|
initialSceneId?: string;
|
|
554
654
|
scenes: PanoProjectSceneDefinition[];
|
|
555
655
|
popups?: ProjectPopupDefinition[];
|
|
656
|
+
map?: PanoMapDefinition;
|
|
556
657
|
};
|
|
557
658
|
type LoadedProjectScene = {
|
|
558
659
|
scene: TileScene | SphereTileScene;
|
|
@@ -565,6 +666,7 @@ type LoadedPanoProject = {
|
|
|
565
666
|
initialSceneId: string;
|
|
566
667
|
scenes: LoadedProjectScene[];
|
|
567
668
|
popups?: ProjectPopupDefinition[];
|
|
669
|
+
map?: PanoMapDefinition;
|
|
568
670
|
};
|
|
569
671
|
type LoadPanoProjectOptions = JsonRequestOptions & {
|
|
570
672
|
/** Directory used for project-relative references. Required for object input. */
|
|
@@ -578,4 +680,4 @@ declare function parsePanoProject(value: unknown, options?: {
|
|
|
578
680
|
}): PanoProjectDefinition;
|
|
579
681
|
declare function loadPanoProject(source: string | PanoProjectDefinition, options?: LoadPanoProjectOptions): Promise<LoadedPanoProject>;
|
|
580
682
|
|
|
581
|
-
export { type AssetUrlContext, type AssetUrlResolver, type CubemapViewerConfig, type JsonObject, type JsonRequestOptions, type JsonValue, type LoadPanoProjectOptions, type LoadSceneFromJsonOptions, type LoadedPanoProject, type LoadedProjectScene, PanoDataError, type PanoDataErrorCode, type PanoProjectDefinition, type PanoProjectSceneDefinition, type PanoViewLimits, type PopupAssetUrlContext, type PopupAssetUrlResolver, type ProjectCustomHotspotAction, type ProjectHotspotAction, type ProjectHotspotDefinition, type ProjectHotspotTrigger, type ProjectPopupBlock, type ProjectPopupDefinition, type SceneFromViewerConfigOptions, type SphereViewerConfig, type ViewerConfig, type ViewerDocument, hotspotAction, loadPanoProject, loadSceneFromJson, parsePanoProject, projectHotspotTriggers, resolveHotspotAssets as resolveProjectHotspotAssets, resolveProjectPopupAssets, sceneFromViewerConfig, setHotspotAction };
|
|
683
|
+
export { type AssetUrlContext, type AssetUrlResolver, type CubemapViewerConfig, type JsonObject, type JsonRequestOptions, type JsonValue, type LoadPanoProjectOptions, type LoadSceneFromJsonOptions, type LoadedPanoProject, type LoadedProjectScene, PanoDataError, type PanoDataErrorCode, type PanoMapControlsDefinition, type PanoMapCorner, type PanoMapDefinition, type PanoMapDialogPresentation, type PanoMapDockedPresentation, type PanoMapGradientStop, type PanoMapPresentation, type PanoMapSectorDefinition, type PanoMapSectorGradient, type PanoMapSpotDefinition, type PanoProjectDefinition, type PanoProjectSceneDefinition, type PanoViewLimits, type PopupAssetUrlContext, type PopupAssetUrlResolver, type ProjectCustomHotspotAction, type ProjectHotspotAction, type ProjectHotspotDefinition, type ProjectHotspotTrigger, type ProjectPopupBlock, type ProjectPopupDefinition, type SceneFromViewerConfigOptions, type SphereViewerConfig, type ViewerConfig, type ViewerDocument, hotspotAction, loadPanoProject, loadSceneFromJson, parsePanoMap, parsePanoProject, projectHotspotTriggers, resolvePanoMapAssets, resolveHotspotAssets as resolveProjectHotspotAssets, resolveProjectPopupAssets, sceneFromViewerConfig, setHotspotAction };
|
package/dist/data.mjs
CHANGED
|
@@ -809,10 +809,212 @@ function resolveHotspotAssets(hotspot, baseUrl, sceneId, resolver) {
|
|
|
809
809
|
return result;
|
|
810
810
|
}
|
|
811
811
|
|
|
812
|
-
// src/data/
|
|
812
|
+
// src/data/map.ts
|
|
813
|
+
var CORNERS = /* @__PURE__ */ new Set([
|
|
814
|
+
"top-left",
|
|
815
|
+
"top-right",
|
|
816
|
+
"bottom-left",
|
|
817
|
+
"bottom-right"
|
|
818
|
+
]);
|
|
819
|
+
function optionalNumber(record, key, options = {}) {
|
|
820
|
+
const value = record[key];
|
|
821
|
+
if (value === void 0) return void 0;
|
|
822
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
823
|
+
throw new Error(`${key}: expected a finite number`);
|
|
824
|
+
if (options.min !== void 0 && value < options.min)
|
|
825
|
+
throw new Error(`${key}: expected a number >= ${options.min}`);
|
|
826
|
+
if (options.max !== void 0 && value > options.max)
|
|
827
|
+
throw new Error(`${key}: expected a number <= ${options.max}`);
|
|
828
|
+
if (options.exclusiveMin !== void 0 && value <= options.exclusiveMin)
|
|
829
|
+
throw new Error(`${key}: expected a number > ${options.exclusiveMin}`);
|
|
830
|
+
if (options.exclusiveMax !== void 0 && value >= options.exclusiveMax)
|
|
831
|
+
throw new Error(`${key}: expected a number < ${options.exclusiveMax}`);
|
|
832
|
+
return value;
|
|
833
|
+
}
|
|
834
|
+
function requiredNumber(record, key, options = {}) {
|
|
835
|
+
const value = optionalNumber(record, key, options);
|
|
836
|
+
if (value === void 0) throw new Error(`${key}: expected a finite number`);
|
|
837
|
+
return value;
|
|
838
|
+
}
|
|
813
839
|
function optionalString(record, key) {
|
|
814
840
|
return record[key] === void 0 ? void 0 : requiredString(record[key], key);
|
|
815
841
|
}
|
|
842
|
+
function parseGradientStop(value, field) {
|
|
843
|
+
if (!isRecord(value)) throw new Error(`${field}: expected an object`);
|
|
844
|
+
const offset = requiredNumber(value, "offset", { min: 0, max: 1 });
|
|
845
|
+
const color = requiredString(value.color, `${field}.color`);
|
|
846
|
+
const opacity = optionalNumber(value, "opacity", { min: 0, max: 1 });
|
|
847
|
+
return {
|
|
848
|
+
offset,
|
|
849
|
+
color,
|
|
850
|
+
...opacity === void 0 ? {} : { opacity }
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
function parseSector(value, field) {
|
|
854
|
+
if (!isRecord(value)) throw new Error(`${field}: expected an object`);
|
|
855
|
+
const angle = requiredNumber(value, "angle", { exclusiveMin: 0, exclusiveMax: 360 });
|
|
856
|
+
const radius = requiredNumber(value, "radius", { exclusiveMin: 0 });
|
|
857
|
+
const followFov = value.followFov === void 0 ? void 0 : value.followFov === true ? true : value.followFov === false ? false : (() => {
|
|
858
|
+
throw new Error(`${field}.followFov: expected a boolean`);
|
|
859
|
+
})();
|
|
860
|
+
const color = optionalString(value, "color");
|
|
861
|
+
const opacity = optionalNumber(value, "opacity", { min: 0, max: 1 });
|
|
862
|
+
const strokeColor = optionalString(value, "strokeColor");
|
|
863
|
+
const strokeWidth = optionalNumber(value, "strokeWidth", { min: 0 });
|
|
864
|
+
const strokeOpacity = optionalNumber(value, "strokeOpacity", { min: 0, max: 1 });
|
|
865
|
+
let gradient;
|
|
866
|
+
if (value.gradient !== void 0) {
|
|
867
|
+
if (!isRecord(value.gradient))
|
|
868
|
+
throw new Error(`${field}.gradient: expected an object`);
|
|
869
|
+
const type = value.gradient.type;
|
|
870
|
+
if (type !== "radial" && type !== "linear")
|
|
871
|
+
throw new Error(`${field}.gradient.type: expected "radial" or "linear"`);
|
|
872
|
+
if (!Array.isArray(value.gradient.stops) || value.gradient.stops.length < 2)
|
|
873
|
+
throw new Error(`${field}.gradient.stops: expected at least two stops`);
|
|
874
|
+
gradient = {
|
|
875
|
+
type,
|
|
876
|
+
stops: value.gradient.stops.map(
|
|
877
|
+
(stop, index) => parseGradientStop(stop, `${field}.gradient.stops[${index}]`)
|
|
878
|
+
)
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
return {
|
|
882
|
+
angle,
|
|
883
|
+
radius,
|
|
884
|
+
...followFov === void 0 ? {} : { followFov },
|
|
885
|
+
...color === void 0 ? {} : { color },
|
|
886
|
+
...opacity === void 0 ? {} : { opacity },
|
|
887
|
+
...strokeColor === void 0 ? {} : { strokeColor },
|
|
888
|
+
...strokeWidth === void 0 ? {} : { strokeWidth },
|
|
889
|
+
...strokeOpacity === void 0 ? {} : { strokeOpacity },
|
|
890
|
+
...gradient === void 0 ? {} : { gradient }
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
function parsePresentation(value, field) {
|
|
894
|
+
if (!isRecord(value)) throw new Error(`${field}: expected an object`);
|
|
895
|
+
const mode = value.mode;
|
|
896
|
+
if (mode !== "docked" && mode !== "dialog")
|
|
897
|
+
throw new Error(`${field}.mode: expected "docked" or "dialog"`);
|
|
898
|
+
const cornerValue = value.corner;
|
|
899
|
+
const corner = cornerValue === void 0 ? void 0 : typeof cornerValue === "string" && CORNERS.has(cornerValue) ? cornerValue : (() => {
|
|
900
|
+
throw new Error(
|
|
901
|
+
`${field}.corner: expected top-left, top-right, bottom-left, or bottom-right`
|
|
902
|
+
);
|
|
903
|
+
})();
|
|
904
|
+
const width = optionalNumber(value, "width", { exclusiveMin: 0 });
|
|
905
|
+
const height = optionalNumber(value, "height", { exclusiveMin: 0 });
|
|
906
|
+
const offsetX = optionalNumber(value, "offsetX", { min: 0 });
|
|
907
|
+
const offsetY = optionalNumber(value, "offsetY", { min: 0 });
|
|
908
|
+
return {
|
|
909
|
+
mode,
|
|
910
|
+
...corner === void 0 ? {} : { corner },
|
|
911
|
+
...width === void 0 ? {} : { width },
|
|
912
|
+
...height === void 0 ? {} : { height },
|
|
913
|
+
...offsetX === void 0 ? {} : { offsetX },
|
|
914
|
+
...offsetY === void 0 ? {} : { offsetY }
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
function parseControls(value, field) {
|
|
918
|
+
if (!isRecord(value)) throw new Error(`${field}: expected an object`);
|
|
919
|
+
const collapse = value.collapse === void 0 ? void 0 : value.collapse === true ? true : value.collapse === false ? false : (() => {
|
|
920
|
+
throw new Error(`${field}.collapse: expected a boolean`);
|
|
921
|
+
})();
|
|
922
|
+
const zoom = value.zoom === void 0 ? void 0 : value.zoom === true ? true : value.zoom === false ? false : (() => {
|
|
923
|
+
throw new Error(`${field}.zoom: expected a boolean`);
|
|
924
|
+
})();
|
|
925
|
+
return {
|
|
926
|
+
...collapse === void 0 ? {} : { collapse },
|
|
927
|
+
...zoom === void 0 ? {} : { zoom }
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
function parseSpot(value, field, sceneIds) {
|
|
931
|
+
if (!isRecord(value)) throw new Error(`${field}: expected an object`);
|
|
932
|
+
const id = requiredString(value.id, `${field}.id`);
|
|
933
|
+
const sceneId = requiredString(value.sceneId, `${field}.sceneId`);
|
|
934
|
+
if (!sceneIds.has(sceneId))
|
|
935
|
+
throw new Error(`${field}.sceneId: scene does not exist`);
|
|
936
|
+
const x = requiredNumber(value, "x", { min: 0, max: 1 });
|
|
937
|
+
const y = requiredNumber(value, "y", { min: 0, max: 1 });
|
|
938
|
+
const heading = requiredNumber(value, "heading");
|
|
939
|
+
const icon = optionalString(value, "icon");
|
|
940
|
+
if (icon) resolveResource("https://map.invalid/", icon);
|
|
941
|
+
return {
|
|
942
|
+
id,
|
|
943
|
+
sceneId,
|
|
944
|
+
x,
|
|
945
|
+
y,
|
|
946
|
+
heading,
|
|
947
|
+
...icon === void 0 ? {} : { icon }
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
function parsePanoMap(value, sceneIds, options = {}) {
|
|
951
|
+
if (value === void 0) return void 0;
|
|
952
|
+
try {
|
|
953
|
+
if (!isRecord(value)) throw new Error("map: expected an object");
|
|
954
|
+
if (typeof value.image !== "string" || !options.draft && !value.image.trim())
|
|
955
|
+
throw new Error("map.image: expected a nonempty string");
|
|
956
|
+
const image = value.image;
|
|
957
|
+
if (image.trim()) resolveResource("https://map.invalid/", image);
|
|
958
|
+
const interaction = value.interaction === void 0 ? void 0 : value.interaction === "fixed" || value.interaction === "zoom" ? value.interaction : (() => {
|
|
959
|
+
throw new Error('map.interaction: expected "fixed" or "zoom"');
|
|
960
|
+
})();
|
|
961
|
+
const presentation = value.presentation === void 0 ? void 0 : parsePresentation(value.presentation, "map.presentation");
|
|
962
|
+
const controls = value.controls === void 0 ? void 0 : parseControls(value.controls, "map.controls");
|
|
963
|
+
const iconSize = optionalNumber(value, "iconSize", { exclusiveMin: 0 });
|
|
964
|
+
const maxScale = optionalNumber(value, "maxScale", { min: 1 });
|
|
965
|
+
if (!Array.isArray(value.spots)) throw new Error("map.spots: expected an array");
|
|
966
|
+
const spotIds = /* @__PURE__ */ new Set();
|
|
967
|
+
const spots = value.spots.map((spot, index) => {
|
|
968
|
+
const parsed = parseSpot(spot, `map.spots[${index}]`, sceneIds);
|
|
969
|
+
if (spotIds.has(parsed.id))
|
|
970
|
+
throw new Error(`map.spots[${index}].id: duplicate spot ID`);
|
|
971
|
+
spotIds.add(parsed.id);
|
|
972
|
+
return parsed;
|
|
973
|
+
});
|
|
974
|
+
const sector = value.sector === void 0 ? void 0 : parseSector(value.sector, "map.sector");
|
|
975
|
+
return {
|
|
976
|
+
image,
|
|
977
|
+
...interaction === void 0 ? {} : { interaction },
|
|
978
|
+
...presentation === void 0 ? {} : { presentation },
|
|
979
|
+
...controls === void 0 ? {} : { controls },
|
|
980
|
+
...iconSize === void 0 ? {} : { iconSize },
|
|
981
|
+
...maxScale === void 0 ? {} : { maxScale },
|
|
982
|
+
spots,
|
|
983
|
+
...sector === void 0 ? {} : { sector }
|
|
984
|
+
};
|
|
985
|
+
} catch (cause) {
|
|
986
|
+
if (cause instanceof PanoDataError) throw cause;
|
|
987
|
+
const message = cause instanceof Error ? cause.message : "Invalid map";
|
|
988
|
+
throw new PanoDataError("INVALID_PROJECT", message, {
|
|
989
|
+
field: message.split(":")[0],
|
|
990
|
+
cause
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
function resolvePanoMapAssets(map, baseUrl, resolveAssetUrl) {
|
|
995
|
+
const resolve = (path, spotId) => mapResource(
|
|
996
|
+
path,
|
|
997
|
+
{
|
|
998
|
+
defaultUrl: resolveResource(baseUrl, path),
|
|
999
|
+
kind: "map",
|
|
1000
|
+
sceneId: spotId ?? "",
|
|
1001
|
+
hotspotId: spotId
|
|
1002
|
+
},
|
|
1003
|
+
resolveAssetUrl
|
|
1004
|
+
);
|
|
1005
|
+
return {
|
|
1006
|
+
...map,
|
|
1007
|
+
image: resolve(map.image),
|
|
1008
|
+
spots: map.spots.map(
|
|
1009
|
+
(spot) => spot.icon ? { ...spot, icon: resolve(spot.icon, spot.id) } : { ...spot }
|
|
1010
|
+
)
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
// src/data/project.ts
|
|
1015
|
+
function optionalString2(record, key) {
|
|
1016
|
+
return record[key] === void 0 ? void 0 : requiredString(record[key], key);
|
|
1017
|
+
}
|
|
816
1018
|
function parsePanoProject(value, options = {}) {
|
|
817
1019
|
if (!isRecord(value))
|
|
818
1020
|
throw new PanoDataError("INVALID_PROJECT", "Expected a project object");
|
|
@@ -843,7 +1045,7 @@ function parsePanoProject(value, options = {}) {
|
|
|
843
1045
|
throw new Error(
|
|
844
1046
|
"source: provide exactly one of viewerUrl or viewerConfig"
|
|
845
1047
|
);
|
|
846
|
-
const baseUrl =
|
|
1048
|
+
const baseUrl = optionalString2(src, "baseUrl");
|
|
847
1049
|
const source = src.viewerUrl !== void 0 ? {
|
|
848
1050
|
viewerUrl: requiredString(src.viewerUrl, "source.viewerUrl"),
|
|
849
1051
|
baseUrl
|
|
@@ -883,7 +1085,7 @@ function parsePanoProject(value, options = {}) {
|
|
|
883
1085
|
);
|
|
884
1086
|
return {
|
|
885
1087
|
id,
|
|
886
|
-
title:
|
|
1088
|
+
title: optionalString2(entry, "title"),
|
|
887
1089
|
source,
|
|
888
1090
|
initialView,
|
|
889
1091
|
...viewLimits === void 0 ? {} : { viewLimits },
|
|
@@ -904,7 +1106,7 @@ function parsePanoProject(value, options = {}) {
|
|
|
904
1106
|
}
|
|
905
1107
|
}
|
|
906
1108
|
);
|
|
907
|
-
const initialSceneId =
|
|
1109
|
+
const initialSceneId = optionalString2(value, "initialSceneId") ?? scenes[0]?.id;
|
|
908
1110
|
if (initialSceneId !== void 0 && !ids.has(initialSceneId))
|
|
909
1111
|
throw new PanoDataError(
|
|
910
1112
|
"INVALID_REFERENCE",
|
|
@@ -932,12 +1134,14 @@ function parsePanoProject(value, options = {}) {
|
|
|
932
1134
|
}
|
|
933
1135
|
}
|
|
934
1136
|
}
|
|
1137
|
+
const map = parsePanoMap(value.map, ids, options);
|
|
935
1138
|
return {
|
|
936
1139
|
schemaVersion: 1,
|
|
937
|
-
title:
|
|
1140
|
+
title: optionalString2(value, "title"),
|
|
938
1141
|
initialSceneId,
|
|
939
1142
|
scenes,
|
|
940
|
-
...popups === void 0 ? {} : { popups }
|
|
1143
|
+
...popups === void 0 ? {} : { popups },
|
|
1144
|
+
...map === void 0 ? {} : { map }
|
|
941
1145
|
};
|
|
942
1146
|
} catch (cause) {
|
|
943
1147
|
if (cause instanceof PanoDataError) throw cause;
|
|
@@ -1036,7 +1240,14 @@ async function loadPanoProject(source, options = {}) {
|
|
|
1036
1240
|
title: definition.title,
|
|
1037
1241
|
initialSceneId: definition.initialSceneId,
|
|
1038
1242
|
scenes,
|
|
1039
|
-
...definition.popups === void 0 ? {} : { popups: definition.popups.map((popup) => resolveProjectPopupAssets(popup, root, options.resolvePopupAssetUrl)) }
|
|
1243
|
+
...definition.popups === void 0 ? {} : { popups: definition.popups.map((popup) => resolveProjectPopupAssets(popup, root, options.resolvePopupAssetUrl)) },
|
|
1244
|
+
...definition.map === void 0 ? {} : {
|
|
1245
|
+
map: resolvePanoMapAssets(
|
|
1246
|
+
definition.map,
|
|
1247
|
+
root,
|
|
1248
|
+
options.resolveAssetUrl
|
|
1249
|
+
)
|
|
1250
|
+
}
|
|
1040
1251
|
};
|
|
1041
1252
|
} finally {
|
|
1042
1253
|
signal?.removeEventListener("abort", cancel);
|
|
@@ -1047,8 +1258,10 @@ export {
|
|
|
1047
1258
|
hotspotAction,
|
|
1048
1259
|
loadPanoProject,
|
|
1049
1260
|
loadSceneFromJson,
|
|
1261
|
+
parsePanoMap,
|
|
1050
1262
|
parsePanoProject,
|
|
1051
1263
|
projectHotspotTriggers,
|
|
1264
|
+
resolvePanoMapAssets,
|
|
1052
1265
|
resolveHotspotAssets as resolveProjectHotspotAssets,
|
|
1053
1266
|
resolveProjectPopupAssets,
|
|
1054
1267
|
sceneFromViewerConfig,
|