diff --git a/src/scene/CesiumGlobe.js b/src/scene/CesiumGlobe.js index 2b29082..4e2347d 100644 --- a/src/scene/CesiumGlobe.js +++ b/src/scene/CesiumGlobe.js @@ -356,7 +356,7 @@ export class CesiumGlobe { viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); } - // 右键操作(原生 tilt)松开后自动归位:记录按下前状态,松开时恢复 + // 右键操作(原生 tilt)松开后自动归位 + 拖动角度限制(左右旋转 ±40°,上下倾角 ±20°) _setupRightRestore() { const scene = this.viewer.scene; const camera = this.viewer.camera; @@ -368,6 +368,8 @@ export class CesiumGlobe { position: Cesium.Cartesian3.clone(camera.position), direction: Cesium.Cartesian3.clone(camera.direction), up: Cesium.Cartesian3.clone(camera.up), + heading: camera.heading, + pitch: camera.pitch, }; }, Cesium.ScreenSpaceEventType.RIGHT_DOWN); @@ -382,6 +384,37 @@ export class CesiumGlobe { }, Cesium.ScreenSpaceEventType.RIGHT_UP); this._rightRestoreHandler = handler; + this.viewer.scene.postUpdate.addEventListener(() => this._clampLookAngles()); + } + + // 右键拖拽期间,限制相对起始朝向的旋转/倾角 + _clampLookAngles() { + if (!this._rightRestore) return; + const camera = this.viewer.camera; + const s = this._rightRestore; + const MAX_ROT = (40 * Math.PI) / 180; + const MAX_TILT = (20 * Math.PI) / 180; + + let heading = camera.heading; + let dh = heading - s.heading; + while (dh > Math.PI) dh -= 2 * Math.PI; + while (dh < -Math.PI) dh += 2 * Math.PI; + const rot = Math.max(-MAX_ROT, Math.min(MAX_ROT, dh)); + + const pitch = camera.pitch; + const dp = pitch - s.pitch; + const tilt = Math.max(-MAX_TILT, Math.min(MAX_TILT, dp)); + + if (rot !== dh || tilt !== dp) { + camera.setView({ + destination: camera.position, + orientation: { + heading: s.heading + rot, + pitch: s.pitch + tilt, + roll: camera.roll, + }, + }); + } } // 相机平滑飞至某个标记上空并居中:回到与初始一致的高度与北朝上方向,左键拖拽手感不变