支持预览界面接收场景基点
This commit is contained in:
@@ -96,10 +96,24 @@ type ParentImportScenePayload = {
|
||||
rawOperationTree: string;
|
||||
};
|
||||
|
||||
type ParentBasePointMessage = {
|
||||
type?: string;
|
||||
message?: string;
|
||||
payload?: {
|
||||
modelId?: string;
|
||||
modelName?: string;
|
||||
basePoint?: PreviewBasePoint;
|
||||
};
|
||||
};
|
||||
|
||||
export type ModelPreviewOptions = {
|
||||
onImportScene?: (payload: PreviewImportScenePayload) => Promise<void> | void;
|
||||
};
|
||||
|
||||
const BASE_POINT_SUBSCRIBE_MESSAGE = "DMT_MODEL_LIBRARY_BASE_POINT_SUBSCRIBE";
|
||||
const BASE_POINT_UNSUBSCRIBE_MESSAGE = "DMT_MODEL_LIBRARY_BASE_POINT_UNSUBSCRIBE";
|
||||
const BASE_POINT_UPDATE_MESSAGE = "DMT_MODEL_LIBRARY_BASE_POINT_UPDATE";
|
||||
const BASE_POINT_ERROR_MESSAGE = "DMT_MODEL_LIBRARY_BASE_POINT_ERROR";
|
||||
const zeroBasePoint: PreviewResolvedBasePoint = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -117,6 +131,8 @@ let runtime: PreviewRuntime | null = null;
|
||||
let activePreviewContext: PreviewLoadContext | null = null;
|
||||
let previewEnvironmentTexturePromise: Promise<Texture> | null = null;
|
||||
let previewPlayback: PreviewPlaybackState = createEmptyPlaybackState();
|
||||
let basePointBridgeBound = false;
|
||||
let basePointSubscribed = false;
|
||||
|
||||
export function openModelPreview(
|
||||
model: ModelItem,
|
||||
@@ -202,6 +218,7 @@ export function openModelPreview(
|
||||
.on("open:after", () => {popup
|
||||
console.log(popup)
|
||||
bindProcessPlaceholder(operations);
|
||||
bindBasePointSelection();
|
||||
bindImportScene(model, operations, options.onImportScene);
|
||||
if (canWrite) bindThumbnailCapture(model.id, onThumbnailSaved);
|
||||
requestAnimationFrame(() => {
|
||||
@@ -210,7 +227,10 @@ export function openModelPreview(
|
||||
});
|
||||
});
|
||||
})
|
||||
.on("close:after", () => disposePreview());
|
||||
.on("close:after", () => {
|
||||
unsubscribeBasePointSelection();
|
||||
disposePreview();
|
||||
});
|
||||
}
|
||||
|
||||
export function setPreviewBasePoint(basePoint: PreviewBasePoint, enabled = true) {
|
||||
@@ -301,6 +321,68 @@ function resolveParentOrigin() {
|
||||
return "*";
|
||||
}
|
||||
|
||||
function isAllowedParentOrigin(origin: string) {
|
||||
const expectedOrigin = resolveParentOrigin();
|
||||
return expectedOrigin === "*" || origin === expectedOrigin || isLocalDmtParentOrigin(origin);
|
||||
}
|
||||
|
||||
function isLocalDmtParentOrigin(origin: string) {
|
||||
try {
|
||||
const url = new URL(origin);
|
||||
const isLocalHost = url.hostname === "localhost" || url.hostname === "127.0.0.1";
|
||||
return isLocalHost && url.port === "3000";
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function bindBasePointSelection() {
|
||||
bindBasePointBridge();
|
||||
const checkbox = document.querySelector<HTMLInputElement>("#previewUseBasePoint");
|
||||
checkbox?.addEventListener("change", () => {
|
||||
if (checkbox.checked) {
|
||||
subscribeBasePointSelection();
|
||||
} else {
|
||||
unsubscribeBasePointSelection();
|
||||
}
|
||||
});
|
||||
if (checkbox?.checked) subscribeBasePointSelection();
|
||||
}
|
||||
|
||||
function bindBasePointBridge() {
|
||||
if (basePointBridgeBound) return;
|
||||
basePointBridgeBound = true;
|
||||
window.addEventListener("message", (event) => {
|
||||
const data = event.data as ParentBasePointMessage;
|
||||
if (data?.type !== BASE_POINT_UPDATE_MESSAGE && data?.type !== BASE_POINT_ERROR_MESSAGE) return;
|
||||
if (!isAllowedParentOrigin(event.origin)) return;
|
||||
if (data.type === BASE_POINT_ERROR_MESSAGE) {
|
||||
notify(data.message || "请先在主场景中选择模型或坐标");
|
||||
return;
|
||||
}
|
||||
if (data.payload?.basePoint) {
|
||||
setPreviewBasePoint(data.payload.basePoint, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function subscribeBasePointSelection() {
|
||||
if (!window.parent || window.parent === window) return;
|
||||
basePointSubscribed = true;
|
||||
window.parent.postMessage({
|
||||
type: BASE_POINT_SUBSCRIBE_MESSAGE
|
||||
}, resolveParentPostMessageOrigin());
|
||||
}
|
||||
|
||||
function unsubscribeBasePointSelection() {
|
||||
if (!basePointSubscribed) return;
|
||||
basePointSubscribed = false;
|
||||
if (!window.parent || window.parent === window) return;
|
||||
window.parent.postMessage({
|
||||
type: BASE_POINT_UNSUBSCRIBE_MESSAGE
|
||||
}, resolveParentPostMessageOrigin());
|
||||
}
|
||||
|
||||
function parseModelOperations(value: string): PreviewOperation[] {
|
||||
try {
|
||||
const dbValue = JSON.parse(value || "{}") as Partial<OperationTreeDB>;
|
||||
|
||||
Reference in New Issue
Block a user