worldorbit 3.0.5 → 3.0.6
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 +2 -2
- package/dist/browser/viewer/dist/embed.js +86 -13
- package/dist/browser/viewer/dist/viewer.js +217 -12
- package/dist/unpkg/viewer/dist/embed.js +86 -13
- package/dist/unpkg/viewer/dist/viewer.js +217 -12
- package/dist/unpkg/worldorbit-editor.min.js +273 -223
- package/dist/unpkg/worldorbit-markdown.min.js +10 -10
- package/dist/unpkg/worldorbit-viewer.min.js +259 -209
- package/dist/unpkg/worldorbit.js +290 -21
- package/dist/unpkg/worldorbit.min.js +263 -213
- package/package.json +1 -1
- package/packages/viewer/dist/embed.js +86 -13
- package/packages/viewer/dist/viewer.js +217 -12
package/dist/unpkg/worldorbit.js
CHANGED
|
@@ -39546,6 +39546,7 @@ void main() {
|
|
|
39546
39546
|
let cameraRoot = null;
|
|
39547
39547
|
let runtime3d = null;
|
|
39548
39548
|
let minimapRoot = null;
|
|
39549
|
+
let labelRoot = null;
|
|
39549
39550
|
let tooltipRoot = null;
|
|
39550
39551
|
let suppressClick = false;
|
|
39551
39552
|
let activePointerId = null;
|
|
@@ -39570,7 +39571,7 @@ void main() {
|
|
|
39570
39571
|
if (previousTabIndex === null) {
|
|
39571
39572
|
container.tabIndex = 0;
|
|
39572
39573
|
}
|
|
39573
|
-
|
|
39574
|
+
installViewerOverlayStyles();
|
|
39574
39575
|
container.classList.add("wo-viewer-container");
|
|
39575
39576
|
container.style.touchAction = behavior.touch ? "none" : previousTouchAction;
|
|
39576
39577
|
if (!container.style.position) {
|
|
@@ -40120,6 +40121,8 @@ void main() {
|
|
|
40120
40121
|
stopAnimationLoop();
|
|
40121
40122
|
runtime3d?.destroy();
|
|
40122
40123
|
runtime3d = null;
|
|
40124
|
+
labelRoot?.remove();
|
|
40125
|
+
labelRoot = null;
|
|
40123
40126
|
tooltipRoot?.remove();
|
|
40124
40127
|
tooltipRoot = null;
|
|
40125
40128
|
minimapRoot?.remove();
|
|
@@ -40150,6 +40153,7 @@ void main() {
|
|
|
40150
40153
|
svgElement = null;
|
|
40151
40154
|
cameraRoot = null;
|
|
40152
40155
|
minimapRoot = null;
|
|
40156
|
+
labelRoot = null;
|
|
40153
40157
|
tooltipRoot = null;
|
|
40154
40158
|
if (is3DView()) {
|
|
40155
40159
|
spatialScene = spatialScene ?? renderSpatialSceneFromInput(currentInput, renderOptions, providedSpatialScene);
|
|
@@ -40168,6 +40172,10 @@ void main() {
|
|
|
40168
40172
|
minimapRoot.dataset.worldorbitMinimapRoot = "true";
|
|
40169
40173
|
container.append(minimapRoot);
|
|
40170
40174
|
}
|
|
40175
|
+
labelRoot = document.createElement("div");
|
|
40176
|
+
labelRoot.className = "wo-viewer-label-root";
|
|
40177
|
+
labelRoot.dataset.worldorbitLabelRoot = "true";
|
|
40178
|
+
container.append(labelRoot);
|
|
40171
40179
|
if (behavior.tooltipMode !== "disabled") {
|
|
40172
40180
|
tooltipRoot = document.createElement("div");
|
|
40173
40181
|
tooltipRoot.className = "wo-viewer-tooltip-root";
|
|
@@ -40179,6 +40187,7 @@ void main() {
|
|
|
40179
40187
|
if (!is3DView() && (!svgElement || !cameraRoot)) {
|
|
40180
40188
|
throw new Error("Interactive viewer could not locate the rendered SVG camera root.");
|
|
40181
40189
|
}
|
|
40190
|
+
suppressStaticLabelLayers();
|
|
40182
40191
|
state = resetView ? is3DView() ? { ...DEFAULT_VIEWER_STATE } : fitViewerState(scene, { ...DEFAULT_VIEWER_STATE }, constraints) : sanitizeState(state);
|
|
40183
40192
|
applySelection(state.selectedObjectId && getObjectById(state.selectedObjectId) ? state.selectedObjectId : null, false);
|
|
40184
40193
|
applyHover(hoveredObjectId && getObjectById(hoveredObjectId) ? hoveredObjectId : null, false);
|
|
@@ -40213,19 +40222,24 @@ void main() {
|
|
|
40213
40222
|
return;
|
|
40214
40223
|
}
|
|
40215
40224
|
cameraRoot.setAttribute("transform", composeViewerTransform(scene, state));
|
|
40225
|
+
updateScreenLabels();
|
|
40216
40226
|
updateMinimap();
|
|
40217
40227
|
updateTooltip();
|
|
40218
40228
|
}
|
|
40219
40229
|
function applySelection(objectId, emitCallback = true) {
|
|
40220
40230
|
if (!is3DView() && state.selectedObjectId) {
|
|
40221
|
-
container.
|
|
40231
|
+
for (const element of container.querySelectorAll(`[data-object-id="${cssEscape(state.selectedObjectId)}"]`)) {
|
|
40232
|
+
element.classList.remove("wo-object-selected");
|
|
40233
|
+
}
|
|
40222
40234
|
}
|
|
40223
40235
|
state = {
|
|
40224
40236
|
...state,
|
|
40225
40237
|
selectedObjectId: objectId && getObjectById(objectId) ? objectId : null
|
|
40226
40238
|
};
|
|
40227
40239
|
if (!is3DView() && state.selectedObjectId) {
|
|
40228
|
-
container.
|
|
40240
|
+
for (const element of container.querySelectorAll(`[data-object-id="${cssEscape(state.selectedObjectId)}"]`)) {
|
|
40241
|
+
element.classList.add("wo-object-selected");
|
|
40242
|
+
}
|
|
40229
40243
|
}
|
|
40230
40244
|
syncAtlasHighlights();
|
|
40231
40245
|
updateTooltip();
|
|
@@ -40558,14 +40572,17 @@ void main() {
|
|
|
40558
40572
|
};
|
|
40559
40573
|
}
|
|
40560
40574
|
function project2DTooltipPoint(renderObject) {
|
|
40561
|
-
if (!svgElement) {
|
|
40562
|
-
return null;
|
|
40563
|
-
}
|
|
40564
40575
|
const anchor = {
|
|
40565
40576
|
x: renderObject.anchorX ?? renderObject.x,
|
|
40566
40577
|
y: renderObject.anchorY ?? renderObject.y - Math.max(renderObject.visualRadius, renderObject.radius)
|
|
40567
40578
|
};
|
|
40568
|
-
|
|
40579
|
+
return project2DScenePointToContainer(anchor);
|
|
40580
|
+
}
|
|
40581
|
+
function project2DScenePointToContainer(point) {
|
|
40582
|
+
if (!svgElement) {
|
|
40583
|
+
return null;
|
|
40584
|
+
}
|
|
40585
|
+
const viewportPoint = projectWorldPoint(point);
|
|
40569
40586
|
const svgRect = svgElement.getBoundingClientRect();
|
|
40570
40587
|
const containerRect = container.getBoundingClientRect();
|
|
40571
40588
|
return {
|
|
@@ -40664,9 +40681,145 @@ void main() {
|
|
|
40664
40681
|
state,
|
|
40665
40682
|
timeSeconds: animationState.timeSeconds
|
|
40666
40683
|
});
|
|
40684
|
+
updateScreenLabels();
|
|
40667
40685
|
updateMinimap();
|
|
40668
40686
|
updateTooltip();
|
|
40669
40687
|
}
|
|
40688
|
+
function suppressStaticLabelLayers() {
|
|
40689
|
+
if (is3DView()) {
|
|
40690
|
+
return;
|
|
40691
|
+
}
|
|
40692
|
+
container.querySelector('[data-layer-id="labels"]')?.setAttribute("display", "none");
|
|
40693
|
+
for (const element of container.querySelectorAll(".wo-event-label")) {
|
|
40694
|
+
element.setAttribute("display", "none");
|
|
40695
|
+
}
|
|
40696
|
+
}
|
|
40697
|
+
function updateScreenLabels() {
|
|
40698
|
+
if (!labelRoot) {
|
|
40699
|
+
return;
|
|
40700
|
+
}
|
|
40701
|
+
const descriptors = buildScreenLabelDescriptors();
|
|
40702
|
+
labelRoot.replaceChildren(...descriptors.map((descriptor) => createScreenLabelElement(descriptor)));
|
|
40703
|
+
labelRoot.hidden = descriptors.length === 0;
|
|
40704
|
+
}
|
|
40705
|
+
function buildScreenLabelDescriptors() {
|
|
40706
|
+
const descriptors = [];
|
|
40707
|
+
const visibleObjectIds = getVisibleObjectIds();
|
|
40708
|
+
if (layerEnabled("labels")) {
|
|
40709
|
+
for (const label of scene.labels) {
|
|
40710
|
+
if (label.hidden || !visibleObjectIds.has(label.objectId)) {
|
|
40711
|
+
continue;
|
|
40712
|
+
}
|
|
40713
|
+
const point = is3DView() ? runtime3d?.projectObjectToContainer(label.objectId) ?? null : project2DScenePointToContainer({ x: label.x, y: label.y });
|
|
40714
|
+
if (!point) {
|
|
40715
|
+
continue;
|
|
40716
|
+
}
|
|
40717
|
+
descriptors.push({
|
|
40718
|
+
key: `object:${label.renderId}`,
|
|
40719
|
+
kind: "object",
|
|
40720
|
+
point: is3DView() ? { x: point.x, y: point.y - 18 } : point,
|
|
40721
|
+
textAnchor: label.textAnchor,
|
|
40722
|
+
objectId: label.objectId,
|
|
40723
|
+
primaryText: label.label,
|
|
40724
|
+
secondaryText: label.secondaryLabel,
|
|
40725
|
+
secondaryOffset: Math.max(label.secondaryY - label.y, 12)
|
|
40726
|
+
});
|
|
40727
|
+
}
|
|
40728
|
+
}
|
|
40729
|
+
if (!is3DView() && layerEnabled("events")) {
|
|
40730
|
+
for (const event of scene.events) {
|
|
40731
|
+
if (event.hidden || !isEventVisible(event, visibleObjectIds)) {
|
|
40732
|
+
continue;
|
|
40733
|
+
}
|
|
40734
|
+
const point = project2DScenePointToContainer({ x: event.x, y: event.y - 10 });
|
|
40735
|
+
if (!point) {
|
|
40736
|
+
continue;
|
|
40737
|
+
}
|
|
40738
|
+
descriptors.push({
|
|
40739
|
+
key: `event:${event.renderId}`,
|
|
40740
|
+
kind: "event",
|
|
40741
|
+
point,
|
|
40742
|
+
textAnchor: "middle",
|
|
40743
|
+
primaryText: event.event.label || event.event.id
|
|
40744
|
+
});
|
|
40745
|
+
}
|
|
40746
|
+
}
|
|
40747
|
+
return descriptors;
|
|
40748
|
+
}
|
|
40749
|
+
function isEventVisible(event, visibleObjectIds) {
|
|
40750
|
+
return event.objectIds.some((objectId) => visibleObjectIds.has(objectId));
|
|
40751
|
+
}
|
|
40752
|
+
function createScreenLabelElement(descriptor) {
|
|
40753
|
+
const element = document.createElement("div");
|
|
40754
|
+
element.className = `wo-viewer-label wo-viewer-label-${descriptor.kind}`;
|
|
40755
|
+
element.dataset.worldorbitScreenLabel = "true";
|
|
40756
|
+
element.dataset.labelKey = descriptor.key;
|
|
40757
|
+
element.dataset.anchor = descriptor.textAnchor;
|
|
40758
|
+
element.style.left = `${descriptor.point.x}px`;
|
|
40759
|
+
element.style.top = `${descriptor.point.y}px`;
|
|
40760
|
+
if (descriptor.objectId) {
|
|
40761
|
+
element.dataset.objectId = descriptor.objectId;
|
|
40762
|
+
for (const className of resolveScreenLabelClasses(descriptor.objectId)) {
|
|
40763
|
+
element.classList.add(className);
|
|
40764
|
+
}
|
|
40765
|
+
}
|
|
40766
|
+
const primary = document.createElement("span");
|
|
40767
|
+
primary.className = "wo-viewer-label-primary";
|
|
40768
|
+
if (descriptor.kind === "object") {
|
|
40769
|
+
primary.style.fontSize = `${14 * scene.scaleModel.labelMultiplier}px`;
|
|
40770
|
+
}
|
|
40771
|
+
primary.textContent = descriptor.primaryText;
|
|
40772
|
+
element.append(primary);
|
|
40773
|
+
if (descriptor.secondaryText) {
|
|
40774
|
+
const secondary = document.createElement("span");
|
|
40775
|
+
secondary.className = "wo-viewer-label-secondary";
|
|
40776
|
+
secondary.style.fontSize = `${11 * scene.scaleModel.labelMultiplier}px`;
|
|
40777
|
+
secondary.style.marginTop = `${Math.max(descriptor.secondaryOffset ?? 12, 10) - 10}px`;
|
|
40778
|
+
secondary.textContent = descriptor.secondaryText;
|
|
40779
|
+
element.append(secondary);
|
|
40780
|
+
}
|
|
40781
|
+
return element;
|
|
40782
|
+
}
|
|
40783
|
+
function layerEnabled(id) {
|
|
40784
|
+
return renderOptions.layers?.[id] !== false;
|
|
40785
|
+
}
|
|
40786
|
+
function resolveScreenLabelClasses(objectId) {
|
|
40787
|
+
const classes = [];
|
|
40788
|
+
const selectedDetails = buildObjectDetails(state.selectedObjectId);
|
|
40789
|
+
const hoveredDetails = buildObjectDetails(hoveredObjectId);
|
|
40790
|
+
if (state.selectedObjectId === objectId) {
|
|
40791
|
+
classes.push("wo-object-selected");
|
|
40792
|
+
}
|
|
40793
|
+
if (selectedDetails) {
|
|
40794
|
+
const selectedChain = /* @__PURE__ */ new Set([
|
|
40795
|
+
selectedDetails.objectId,
|
|
40796
|
+
...selectedDetails.renderObject.childIds,
|
|
40797
|
+
...selectedDetails.renderObject.ancestorIds
|
|
40798
|
+
]);
|
|
40799
|
+
const selectedAncestors = new Set(selectedDetails.ancestors.map((ancestor) => ancestor.objectId));
|
|
40800
|
+
if (selectedChain.has(objectId)) {
|
|
40801
|
+
classes.push("wo-chain-selected");
|
|
40802
|
+
}
|
|
40803
|
+
if (selectedAncestors.has(objectId)) {
|
|
40804
|
+
classes.push("wo-ancestor-selected");
|
|
40805
|
+
}
|
|
40806
|
+
}
|
|
40807
|
+
if (hoveredDetails) {
|
|
40808
|
+
const hoveredChain = /* @__PURE__ */ new Set([
|
|
40809
|
+
hoveredDetails.objectId,
|
|
40810
|
+
...hoveredDetails.renderObject.childIds,
|
|
40811
|
+
...hoveredDetails.renderObject.ancestorIds
|
|
40812
|
+
]);
|
|
40813
|
+
const hoveredAncestors = new Set(hoveredDetails.ancestors.map((ancestor) => ancestor.objectId));
|
|
40814
|
+
if (hoveredChain.has(objectId)) {
|
|
40815
|
+
classes.push("wo-chain-hover");
|
|
40816
|
+
}
|
|
40817
|
+
if (hoveredAncestors.has(objectId)) {
|
|
40818
|
+
classes.push("wo-ancestor-hover");
|
|
40819
|
+
}
|
|
40820
|
+
}
|
|
40821
|
+
return classes;
|
|
40822
|
+
}
|
|
40670
40823
|
function create3DFocusState(objectId) {
|
|
40671
40824
|
const target = spatialScene?.focusTargets.find((entry) => entry.objectId === objectId);
|
|
40672
40825
|
if (!target) {
|
|
@@ -40918,7 +41071,7 @@ void main() {
|
|
|
40918
41071
|
}
|
|
40919
41072
|
return value.replace(/["\\]/g, "\\$&");
|
|
40920
41073
|
}
|
|
40921
|
-
function
|
|
41074
|
+
function installViewerOverlayStyles() {
|
|
40922
41075
|
if (typeof document === "undefined" || document.getElementById(TOOLTIP_STYLE_ID)) {
|
|
40923
41076
|
return;
|
|
40924
41077
|
}
|
|
@@ -40953,6 +41106,56 @@ void main() {
|
|
|
40953
41106
|
height: 100%;
|
|
40954
41107
|
min-height: 320px;
|
|
40955
41108
|
}
|
|
41109
|
+
.wo-viewer-label-root {
|
|
41110
|
+
position: absolute;
|
|
41111
|
+
inset: 0;
|
|
41112
|
+
z-index: 8;
|
|
41113
|
+
pointer-events: none;
|
|
41114
|
+
overflow: hidden;
|
|
41115
|
+
}
|
|
41116
|
+
.wo-viewer-label {
|
|
41117
|
+
position: absolute;
|
|
41118
|
+
display: grid;
|
|
41119
|
+
gap: 2px;
|
|
41120
|
+
color: #edf6ff;
|
|
41121
|
+
font-family: "Segoe UI Variable", "Segoe UI", sans-serif;
|
|
41122
|
+
line-height: 1.15;
|
|
41123
|
+
text-shadow: 0 1px 2px rgba(7, 16, 25, 0.65), 0 0 18px rgba(7, 16, 25, 0.18);
|
|
41124
|
+
white-space: nowrap;
|
|
41125
|
+
}
|
|
41126
|
+
.wo-viewer-label[data-anchor="middle"] { transform: translate(-50%, 0); }
|
|
41127
|
+
.wo-viewer-label[data-anchor="end"] { transform: translate(-100%, 0); }
|
|
41128
|
+
.wo-viewer-label-primary {
|
|
41129
|
+
font-size: 14px;
|
|
41130
|
+
font-weight: 600;
|
|
41131
|
+
letter-spacing: 0.02em;
|
|
41132
|
+
}
|
|
41133
|
+
.wo-viewer-label-secondary {
|
|
41134
|
+
font-size: 11px;
|
|
41135
|
+
font-weight: 500;
|
|
41136
|
+
color: rgba(237, 246, 255, 0.72);
|
|
41137
|
+
}
|
|
41138
|
+
.wo-viewer-label-event {
|
|
41139
|
+
color: #ffce8a;
|
|
41140
|
+
text-transform: uppercase;
|
|
41141
|
+
letter-spacing: 0.04em;
|
|
41142
|
+
}
|
|
41143
|
+
.wo-viewer-label-event .wo-viewer-label-primary {
|
|
41144
|
+
font-size: 10px;
|
|
41145
|
+
font-weight: 700;
|
|
41146
|
+
}
|
|
41147
|
+
.wo-viewer-label.wo-object-selected .wo-viewer-label-primary,
|
|
41148
|
+
.wo-viewer-label.wo-chain-selected .wo-viewer-label-primary,
|
|
41149
|
+
.wo-viewer-label.wo-chain-hover .wo-viewer-label-primary {
|
|
41150
|
+
color: #ffce8a;
|
|
41151
|
+
}
|
|
41152
|
+
.wo-viewer-label.wo-object-selected .wo-viewer-label-secondary {
|
|
41153
|
+
color: #8fcaff;
|
|
41154
|
+
}
|
|
41155
|
+
.wo-viewer-label.wo-ancestor-selected .wo-viewer-label-primary,
|
|
41156
|
+
.wo-viewer-label.wo-ancestor-hover .wo-viewer-label-primary {
|
|
41157
|
+
opacity: 0.82;
|
|
41158
|
+
}
|
|
40956
41159
|
.wo-viewer-tooltip-root {
|
|
40957
41160
|
position: absolute;
|
|
40958
41161
|
z-index: 12;
|
|
@@ -41087,6 +41290,7 @@ void main() {
|
|
|
41087
41290
|
}
|
|
41088
41291
|
function mountWorldOrbitEmbeds(root = document, options = {}) {
|
|
41089
41292
|
const viewers = /* @__PURE__ */ new Map();
|
|
41293
|
+
const cleanupCallbacks = [];
|
|
41090
41294
|
const elements = [...root.querySelectorAll(EMBED_SELECTOR)];
|
|
41091
41295
|
for (const element of elements) {
|
|
41092
41296
|
const payload = deserializePayloadFromElement(element);
|
|
@@ -41100,14 +41304,16 @@ void main() {
|
|
|
41100
41304
|
const initialSelectionObjectId = options.viewer?.initialSelectionObjectId ?? payload.options?.initialSelectionObjectId;
|
|
41101
41305
|
const minimap = options.viewer?.minimap ?? payload.options?.minimap;
|
|
41102
41306
|
const viewMode = options.viewer?.viewMode ?? payload.options?.viewMode ?? embedModeToViewMode(mode);
|
|
41307
|
+
const measureViewport = () => resolveEmbedViewport(element, payload.scene, options);
|
|
41103
41308
|
if (mode === "interactive-2d" || mode === "interactive-3d") {
|
|
41104
41309
|
try {
|
|
41310
|
+
const viewport = measureViewport();
|
|
41105
41311
|
const viewer = createInteractiveViewer(element, {
|
|
41106
41312
|
...options.viewer,
|
|
41107
41313
|
scene: payload.scene,
|
|
41108
41314
|
spatialScene: payload.spatialScene,
|
|
41109
|
-
width:
|
|
41110
|
-
height:
|
|
41315
|
+
width: viewport.width,
|
|
41316
|
+
height: viewport.height,
|
|
41111
41317
|
padding: options.padding ?? payload.scene.padding,
|
|
41112
41318
|
preset,
|
|
41113
41319
|
theme,
|
|
@@ -41123,6 +41329,13 @@ void main() {
|
|
|
41123
41329
|
viewer.setAtlasState(payload.options.atlasState);
|
|
41124
41330
|
}
|
|
41125
41331
|
viewers.set(element, viewer);
|
|
41332
|
+
cleanupCallbacks.push(bindEmbedResize(element, () => {
|
|
41333
|
+
const nextViewport = measureViewport();
|
|
41334
|
+
viewer.setRenderOptions({
|
|
41335
|
+
width: nextViewport.width,
|
|
41336
|
+
height: nextViewport.height
|
|
41337
|
+
});
|
|
41338
|
+
}));
|
|
41126
41339
|
options.onMount?.(viewer, element);
|
|
41127
41340
|
} catch (error2) {
|
|
41128
41341
|
if (error2 instanceof WorldOrbit3DUnavailableError && mode === "interactive-3d") {
|
|
@@ -41133,17 +41346,22 @@ void main() {
|
|
|
41133
41346
|
}
|
|
41134
41347
|
}
|
|
41135
41348
|
} else {
|
|
41136
|
-
|
|
41137
|
-
|
|
41138
|
-
|
|
41139
|
-
|
|
41140
|
-
|
|
41141
|
-
|
|
41142
|
-
|
|
41143
|
-
|
|
41144
|
-
|
|
41145
|
-
|
|
41146
|
-
|
|
41349
|
+
const renderStaticEmbed = () => {
|
|
41350
|
+
const viewport = measureViewport();
|
|
41351
|
+
element.innerHTML = renderSceneToSvg(payload.scene, {
|
|
41352
|
+
width: viewport.width,
|
|
41353
|
+
height: viewport.height,
|
|
41354
|
+
padding: options.padding ?? payload.scene.padding,
|
|
41355
|
+
preset,
|
|
41356
|
+
theme,
|
|
41357
|
+
layers,
|
|
41358
|
+
filter: initialFilter,
|
|
41359
|
+
selectedObjectId: initialSelectionObjectId ?? null,
|
|
41360
|
+
subtitle
|
|
41361
|
+
});
|
|
41362
|
+
};
|
|
41363
|
+
renderStaticEmbed();
|
|
41364
|
+
cleanupCallbacks.push(bindEmbedResize(element, renderStaticEmbed));
|
|
41147
41365
|
options.onMount?.(null, element);
|
|
41148
41366
|
}
|
|
41149
41367
|
element.dataset.worldorbitMounted = "true";
|
|
@@ -41151,14 +41369,65 @@ void main() {
|
|
|
41151
41369
|
return {
|
|
41152
41370
|
viewers: [...viewers.values()],
|
|
41153
41371
|
destroy() {
|
|
41372
|
+
for (const cleanup of cleanupCallbacks) {
|
|
41373
|
+
cleanup();
|
|
41374
|
+
}
|
|
41154
41375
|
for (const [element, viewer] of viewers.entries()) {
|
|
41155
41376
|
viewer.destroy();
|
|
41156
41377
|
element.removeAttribute("data-worldorbit-mounted");
|
|
41157
41378
|
}
|
|
41379
|
+
for (const element of elements) {
|
|
41380
|
+
element.removeAttribute("data-worldorbit-mounted");
|
|
41381
|
+
}
|
|
41158
41382
|
viewers.clear();
|
|
41159
41383
|
}
|
|
41160
41384
|
};
|
|
41161
41385
|
}
|
|
41386
|
+
function resolveEmbedViewport(element, scene, options) {
|
|
41387
|
+
const rect = element.getBoundingClientRect();
|
|
41388
|
+
const width = sanitizeViewportDimension(options.width) ?? sanitizeViewportDimension(element.clientWidth) ?? sanitizeViewportDimension(rect.width) ?? scene.width;
|
|
41389
|
+
const explicitHeight = sanitizeViewportDimension(options.height) ?? sanitizeViewportDimension(element.clientHeight) ?? sanitizeViewportDimension(rect.height);
|
|
41390
|
+
const fallbackHeight = Math.max(Math.round(width * (scene.height / Math.max(scene.width, 1))), Math.min(scene.height, 240));
|
|
41391
|
+
return {
|
|
41392
|
+
width,
|
|
41393
|
+
height: explicitHeight ?? fallbackHeight
|
|
41394
|
+
};
|
|
41395
|
+
}
|
|
41396
|
+
function sanitizeViewportDimension(value) {
|
|
41397
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.round(value) : null;
|
|
41398
|
+
}
|
|
41399
|
+
function bindEmbedResize(element, callback) {
|
|
41400
|
+
let lastWidth = -1;
|
|
41401
|
+
let lastHeight = -1;
|
|
41402
|
+
const run = () => {
|
|
41403
|
+
const rect = element.getBoundingClientRect();
|
|
41404
|
+
const nextWidth = Math.round(Math.max(element.clientWidth || rect.width, 0));
|
|
41405
|
+
const nextHeight = Math.round(Math.max(element.clientHeight || rect.height, 0));
|
|
41406
|
+
if (nextWidth === lastWidth && nextHeight === lastHeight) {
|
|
41407
|
+
return;
|
|
41408
|
+
}
|
|
41409
|
+
lastWidth = nextWidth;
|
|
41410
|
+
lastHeight = nextHeight;
|
|
41411
|
+
callback();
|
|
41412
|
+
};
|
|
41413
|
+
run();
|
|
41414
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
41415
|
+
const observer = new ResizeObserver(() => {
|
|
41416
|
+
run();
|
|
41417
|
+
});
|
|
41418
|
+
observer.observe(element);
|
|
41419
|
+
return () => {
|
|
41420
|
+
observer.disconnect();
|
|
41421
|
+
};
|
|
41422
|
+
}
|
|
41423
|
+
const handleWindowResize = () => {
|
|
41424
|
+
run();
|
|
41425
|
+
};
|
|
41426
|
+
window.addEventListener("resize", handleWindowResize);
|
|
41427
|
+
return () => {
|
|
41428
|
+
window.removeEventListener("resize", handleWindowResize);
|
|
41429
|
+
};
|
|
41430
|
+
}
|
|
41162
41431
|
function deserializePayloadFromElement(element) {
|
|
41163
41432
|
const serialized = element.dataset.worldorbitPayload;
|
|
41164
41433
|
if (!serialized) {
|