Cesium用wsad进行场景漫游(九)

2023-01-14

先看效果,wsadqe控制方向升降,鼠标拖动屏幕也可以控制方向

 

 整理下思路:

1. 使用movement变量控制是否进行漫游

2.1 进行漫游则先将enableRotate等全部取消

2.2 绑定Cesium.ScreenSpaceEventType.LEFT_DOWN等事件,用于计算鼠标移动并改变镜头方向,同时根据鼠标是否按下判断鼠标移动是否可以改变镜头方向

2.3 document.addEventListener监听按下的键盘按钮,进行相应的camera.moveForward等方法

3. 不进行漫游则恢复enableRotate等

 

代码如下:在vue中将其包装为一个Ismovement方法

    //是否漫游模式
    Ismovement(){
      var that = this;
      this.movement = !this.movement;

      //如果进行漫游
      if(this.movement){
        var ellipsoid = this.viewer.scene.globe.ellipsoid;

        //先将鼠标控制事件全部取消
        this.viewer.scene.screenSpaceCameraController.enableRotate = false;
        this.viewer.scene.screenSpaceCameraController.enableTranslate = false;
        this.viewer.scene.screenSpaceCameraController.enableZoom = false;
        this.viewer.scene.screenSpaceCameraController.enableTilt = false;
        this.viewer.scene.screenSpaceCameraController.enableLook = false;

        var startMousePosition;
        var mousePosition;

        //控制方向
        var flags = {
          looking : false,
          moveForward : false,
          moveBackward : false,
          moveUp : false,
          moveDown : false,
          moveLeft : false,
          moveRight : false
        };

        //按下左键的同时克隆一个鼠标点击的位置
        this.viewer.screenSpaceEventHandler.setInputAction(function(movement) {
          flags.looking = true;
          mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position);
        }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

        //记录鼠标移动的终点
        this.viewer.screenSpaceEventHandler.setInputAction(function(movement) {
          mousePosition = movement.endPosition;
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        //looking改为false,意思是此时鼠标移动不会改变镜头方向
        this.viewer.screenSpaceEventHandler.setInputAction(function(position) {
          flags.looking = false;
        }, Cesium.ScreenSpaceEventType.LEFT_UP);

        //获得按下的哪个按钮
        function getFlagForKeyCode(keyCode) {
          switch (keyCode) {
          case 'W'.charCodeAt(0):
            return 'moveForward';
          case 'S'.charCodeAt(0):
            return 'moveBackward';
          case 'Q'.charCodeAt(0):
            return 'moveUp';
          case 'E'.charCodeAt(0):
            return 'moveDown';
          case 'D'.charCodeAt(0):
            return 'moveRight';
          case 'A'.charCodeAt(0):
            return 'moveLeft';
          default:
            return undefined;
          }
        }

        //keydown如果长时间按下某个键,则重复触发按键按下事件。
        document.addEventListener('keydown', this.down = function(e){
          var flagName = getFlagForKeyCode(e.keyCode);
          if (typeof flagName !== 'undefined') {
            flags[flagName] = true;
          }
        }, false);

        document.addEventListener('keyup', this.up =(e)=>{
          var flagName = getFlagForKeyCode(e.keyCode);
          if (typeof flagName !== 'undefined') {
            flags[flagName] = false;
          }
        }, false);

        //实时获取cesium clock的tick每一帧的时间,十分常用的功能
        this.viewer.clock.onTick.addEventListener(function(clock) {
          
          var camera = that.viewer.camera;

          // 镜头旋转
          if (flags.looking) {
            //获取画布的高度宽度
            var width = that.viewer.canvas.clientWidth;
            var height = that.viewer.canvas.clientHeight;

            //相当于转动灵敏度,越大转动越快
            var lookFactor =0.06;

            //x和y是鼠标按下后移动的xy距离与画布长宽的比例
            var x = (mousePosition.x - startMousePosition.x) / width;
            var y = -(mousePosition.y - startMousePosition.y) / height;
            
            camera.setView({
              //根据摄像头现在的朝向和刚才移动的比例进行方向更新
              orientation: {
                  heading : camera.heading + x*lookFactor, 
                  pitch : camera.pitch + y*lookFactor,    
                  roll : 0.0                             
              }
            })
          }

          // 根据高度来决定镜头移动的速度
          var cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
          var moveRate = cameraHeight / 100.0;

          if (flags.moveForward) {
            camera.moveForward(moveRate);
          }
          if (flags.moveBackward) {
            camera.moveBackward(moveRate);
          }
          if (flags.moveUp) {
            camera.moveUp(moveRate);
          }
          if (flags.moveDown) {
            camera.moveDown(moveRate);
          }
          if (flags.moveLeft) {
            camera.moveLeft(moveRate);
          }
          if (flags.moveRight) {
            camera.moveRight(moveRate);
          }
        });
      }else{
        //取消漫游
        this.viewer.scene.screenSpaceCameraController.enableRotate = true;
        this.viewer.scene.screenSpaceCameraController.enableTranslate = true;
        this.viewer.scene.screenSpaceCameraController.enableZoom = true;
        this.viewer.scene.screenSpaceCameraController.enableTilt = true;
        this.viewer.scene.screenSpaceCameraController.enableLook = true;
        this.viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN)
        this.viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
        this.viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP)
        document.removeEventListener('keydown',this.down,false)
        document.removeEventListener('keyup',this.up,false)
    
      }
    },

 

 

为了方便测试,这里用一个button进行控制是否漫游

<el-button @click="Ismovement" >漫游模式</el-button>

 

posted @ 2023-01-14 16:13  一摩尔时光  阅读(718)  评论(1编辑  收藏  举报