From a562ad9369ead7ac61a23cc967dbd33c0b36e4aa Mon Sep 17 00:00:00 2001 From: Zzc <1373857752@qq.com> Date: Mon, 24 Nov 2025 17:00:50 +0800 Subject: [PATCH] =?UTF-8?q?perf(screen):=20=E4=BC=98=E5=8C=96=E5=8F=8C?= =?UTF-8?q?=E5=9C=B0=E5=9B=BE=E6=AF=94=E8=BE=83=E4=B8=AD=E7=9A=84=E7=9B=B8?= =?UTF-8?q?=E6=9C=BA=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构相机同步以使用单向(从右到左)同步并结合postRender以获得更好的性能。禁用左侧查看器的所有交互以防止意外更改。直接传递位置引用而非克隆以实现最佳效率。 --- .../composables/useDualMapCompare.js | 49 ++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/packages/screen/src/views/3DSituationalAwarenessRefactor/composables/useDualMapCompare.js b/packages/screen/src/views/3DSituationalAwarenessRefactor/composables/useDualMapCompare.js index 1dfd86d..05e6a61 100644 --- a/packages/screen/src/views/3DSituationalAwarenessRefactor/composables/useDualMapCompare.js +++ b/packages/screen/src/views/3DSituationalAwarenessRefactor/composables/useDualMapCompare.js @@ -6,6 +6,7 @@ import { use3DTiles } from './use3DTiles' * 双地图对比模式 * 使用两个独立的Cesium Viewer实现并排对比 * 左侧显示灾前场景,右侧显示灾后场景 + * 单向相机同步:右侧主地图驱动,左侧对比地图跟随 */ export function useDualMapCompare() { /** 左侧Viewer引用 */ @@ -58,17 +59,25 @@ export function useDualMapCompare() { // 移除默认的Cesium logo和版权信息 viewer.cesiumWidget.creditContainer.style.display = 'none' + // 完全禁用左侧Viewer的所有交互(只作为对比显示) + viewer.scene.screenSpaceCameraController.enableRotate = false + viewer.scene.screenSpaceCameraController.enableTranslate = false + viewer.scene.screenSpaceCameraController.enableZoom = false + viewer.scene.screenSpaceCameraController.enableTilt = false + viewer.scene.screenSpaceCameraController.enableLook = false + leftViewer.value = viewer - console.log('[useDualMapCompare] 左侧Viewer初始化成功') + console.log('[useDualMapCompare] 左侧Viewer初始化成功(交互已禁用)') return viewer } /** - * 设置相机同步 - * 右侧相机移动时,左侧相机跟随 - * @param {Cesium.Viewer} rightViewerInstance - 右侧Viewer(主地图) - * @param {Cesium.Viewer} leftViewerInstance - 左侧Viewer(对比地图) + * 设置单向相机同步(右→左) + * 右侧主地图驱动,左侧对比地图跟随 + * 使用 postRender 实现逐帧同步,直接传递 position 引用以获得最佳性能 + * @param {Cesium.Viewer} rightViewerInstance - 右侧Viewer(主地图,驱动者) + * @param {Cesium.Viewer} leftViewerInstance - 左侧Viewer(对比地图,跟随者) */ const setupCameraSync = (rightViewerInstance, leftViewerInstance) => { if (!rightViewerInstance || !leftViewerInstance) { @@ -76,18 +85,23 @@ export function useDualMapCompare() { return } - console.log('[useDualMapCompare] 设置相机同步(右侧主地图 → 左侧对比地图)...') + console.log('[useDualMapCompare] 设置单向相机同步(右→左)...') - // 监听右侧相机变化 - const syncCamera = () => { + /** + * 相机同步处理函数 + * 在右侧 Viewer 的 postRender 中调用,将右侧相机状态同步到左侧 + */ + const handleCameraSync = () => { + // 检查 Viewer 是否有效 if (!leftViewerInstance || leftViewerInstance.isDestroyed()) return + if (!rightViewerInstance || rightViewerInstance.isDestroyed()) return const rightCamera = rightViewerInstance.camera - const leftCamera = leftViewerInstance.camera - // 同步位置和方向 - leftCamera.setView({ - destination: rightCamera.position.clone(), + // 直接传递 position 引用(不 clone),获得最佳性能 + // Cesium 内部会处理拷贝,且在单向同步场景下安全 + leftViewerInstance.camera.setView({ + destination: rightCamera.position, orientation: { heading: rightCamera.heading, pitch: rightCamera.pitch, @@ -96,16 +110,17 @@ export function useDualMapCompare() { }) } - // 添加监听器 - rightViewerInstance.camera.changed.addEventListener(syncCamera) + // 只在右侧 Viewer 的 postRender 中注册同步函数 + // 确保右侧相机更新完成后再同步到左侧 + rightViewerInstance.scene.postRender.addEventListener(handleCameraSync) // 保存移除函数 cameraSyncRemover = () => { - rightViewerInstance.camera.changed.removeEventListener(syncCamera) + rightViewerInstance.scene.postRender.removeEventListener(handleCameraSync) console.log('[useDualMapCompare] 相机同步已移除') } - console.log('[useDualMapCompare] 相机同步设置完成') + console.log('[useDualMapCompare] 单向相机同步设置完成') } /** @@ -155,7 +170,7 @@ export function useDualMapCompare() { } }) - // 设置相机同步(右侧主地图 → 左侧对比地图) + // 设置相机同步(单向:右→左) setupCameraSync(rightViewerInstance, leftViewerInstance) // 异步加载灾前模型到左侧(不阻塞对比模式启用)