25382538 return values.every(number => Number.isFinite(number) && number > 0) ? values : null;
25392539 }
25402540
2541+ let externalArtifactViewSnapshot = null;
2542+
2543+ function saveRendererViewState() {
2544+ const config = activeConfig || window.BuretteConfig || {};
2545+ const patch = config.renderer === 'xyzrender-external'
2546+ ? { xyz: externalArtifactViewSnapshot?.() }
2547+ : { camera: captureMolstarCameraSnapshot(activeViewer) };
2548+ window.BuretteRendererViewState?.save(config.documentId, patch);
2549+ const viewState = window.BuretteRendererViewState?.read(config.documentId);
2550+ postHostMessage({ type: 'rendererViewStateChanged', viewState });
2551+ return viewState;
2552+ }
2553+ window.addEventListener('pagehide', saveRendererViewState);
2554+ let rendererViewSaveTimer;
2555+ const scheduleRendererViewSave = () => {
2556+ clearTimeout(rendererViewSaveTimer);
2557+ rendererViewSaveTimer = setTimeout(saveRendererViewState, 250);
2558+ };
2559+ window.addEventListener('pointerup', scheduleRendererViewSave);
2560+ window.addEventListener('wheel', scheduleRendererViewSave, { passive: true });
2561+
25412562 function requestRendererSwitch(renderer) {
2563+ const viewState = saveRendererViewState();
25422564 const value = normalizeRenderer(renderer);
25432565 if (requestBrowserDevRendererSwitch(value)) return;
25442566 const orientationRef = value === 'xyzrender-external' ? captureCurrentXyzrenderOrientationRef() : null;
2545- const activeModel = value === 'xyzrender-external' ? activeTrajectoryFrameIndexForRendererSwitch() : null ;
2546- const payload = { type: 'setRenderer', value };
2567+ const activeModel = activeTrajectoryFrameIndexForRendererSwitch();
2568+ const payload = { type: 'setRenderer', value, viewState };
25472569 if (orientationRef) {
25482570 payload.orientationRef = orientationRef.text;
25492571 payload.orientationAtomCount = orientationRef.atomCount;
@@ -13544,9 +13566,10 @@ SOFTWARE.
1354413566 const stage = root.querySelector('.buret-external-artifact-stage');
1354513567 if (!stage) return;
1354613568
13547- let scale = 1;
13548- let translateX = 0;
13549- let translateY = 0;
13569+ const savedView = window.BuretteRendererViewState?.read(activeConfig?.documentId, activeConfig?.rendererViewState).xyz;
13570+ let scale = savedView?.scale ?? 1;
13571+ let translateX = savedView?.x ?? 0;
13572+ let translateY = savedView?.y ?? 0;
1355013573 let dragPointerId = null;
1355113574 let dragClientX = 0;
1355213575 let dragClientY = 0;
@@ -13663,6 +13686,19 @@ SOFTWARE.
1366313686 };
1366413687 installExternalArtifactBaseItemInteractions(root, () => scale);
1366513688 const sheetCleanup = installExternalArtifactSheet(root, stage, toStagePoint, () => scale);
13689+ const baseItem = root.querySelector('.buret-xyzrender-sheet-item-base');
13690+ if (baseItem && savedView?.item) {
13691+ for (const key of ['left', 'top', 'width', 'height']) baseItem.style[key] = `${savedView.item[key]}px`;
13692+ setSheetItemRotation(baseItem, savedView.item.rotation);
13693+ }
13694+ externalArtifactViewSnapshot = () => ({
13695+ scale, x: translateX, y: translateY,
13696+ item: baseItem ? {
13697+ left: baseItem.offsetLeft, top: baseItem.offsetTop,
13698+ width: baseItem.offsetWidth, height: baseItem.offsetHeight,
13699+ rotation: Number(baseItem.dataset.rotation || 0)
13700+ } : null
13701+ });
1366613702
1366713703 root.addEventListener('wheel', onWheel, { passive: false });
1366813704 root.addEventListener('pointerdown', onPointerDown);
@@ -13674,6 +13710,8 @@ SOFTWARE.
1367413710 root.addEventListener('gesturechange', onGestureChange, { passive: false });
1367513711 apply();
1367613712 externalArtifactInteractionsCleanup = () => {
13713+ saveRendererViewState();
13714+ externalArtifactViewSnapshot = null;
1367713715 root.removeEventListener('wheel', onWheel);
1367813716 root.removeEventListener('pointerdown', onPointerDown);
1367913717 root.removeEventListener('pointermove', onPointerMove);
@@ -26104,7 +26142,11 @@ ${config.label || 'structure'} (${formatLabel}${size ? `, ${size}` : ''})`);
2610426142 } catch (error) {
2610526143 debug('Configured Mol* preset failed: ' + (error?.message || String(error)));
2610626144 }
26107- if (!hasMolstarContextFocus(config)) {
26145+ const savedCamera = window.BuretteRendererViewState?.read(config.documentId, config.rendererViewState).camera;
26146+ if (savedCamera && !hasMolstarContextFocus(config) && prepared.kind !== 'mvs') {
26147+ molstarStructureFocusSerial += 1;
26148+ restoreMolstarCameraSnapshotNow(viewer, savedCamera);
26149+ } else if (!hasMolstarContextFocus(config)) {
2610826150 scheduleMolstarStructureFocus(viewer, { reason: 'initial-load', durationMs: 120 });
2610926151 }
2611026152 {
0 commit comments