cesium键盘控制相机位置和姿态

该类主要用于监听键盘事件并在用户按下不同按键时执行相应的相机操作,如改变相机的位置、偏航角、俯仰角和翻滚角,从而实现在三维场景中的漫游。
以下是代码的主要逻辑:
导入Cesium库,并定义一个flags对象,其中包含了所有可能触发的键盘漫游状态标志。
keyboardRoam 类包含以下方法:
 ###### **`start(viewer, setStep)`: 初始化键盘监听事件,包括keydown和keyup事件,并在每一帧(clock onTick事件)中执行`funcTick`函数以更新相机状态。同时禁用默认的鼠标移动地图和平移相机的功能。**
 ###### **`hprSetting(h, p, r)`: 设置相机的Heading、Pitch、Roll(即偏航角、俯仰角、翻滚角)。**
 ###### **`getFlagFromKeyboard(k)`: 根据按下的键盘按键返回对应的按键名称。**
funcTick函数中,根据flags对象中的状态标志来更新相机的位置和姿态。
quit()方法用于销毁键盘监听事件以及恢复鼠标移动地图和平移相机的功能。
通过实例化 keyboardRoam 类并调用 start 方法,可以启用键盘漫游功能;调用 quit 方法则停止漫游并恢复默认的相机控制方式。
javascript 复制代码
      // 引入键盘漫游方法
      import keyboardRoam from "../utils/roam/keyboardRoam";
      // 键盘控制相机方法初始化
      keyboard = new keyboardRoam();
      // 键盘控制相机方法开始
      keyboard.start(window.viewer, 1)
      // 键盘控制相机方法结束
      keyboard.quit();
javascript 复制代码
import * as Cesium from "cesium";
// 定义事件组
let flags = {
  // 相机位置
  moveForward: false,
  moveBackward: false,
  moveLeft: false,
  moveRight: false,
  moveUp: false,
  moveDown: false,
  translateFront: false,
  translateBehind: false,
  // 相机姿态
  picthUp: false,
  picthDown: false,
  rollLeft: false,
  rollRight: false,
  headingLeft: false,
  headingRight: false,
};
let cameraHeight;
let heading;
let pitch;
let roll;
let funcTick;
/**
 * 键盘漫游
 */
class keyboardRoam {
  /**
   * 键盘漫游加载方法
   * @param: 使用键盘控制地图漫游,
   * @param {Cesium.Viewer} viewer -cesium地图容器
   * @param {Number} setStep -相机视角移动步长
   */
  start(viewer, setStep) {
    let that = this;
    // 添加键盘监听事件
    document.addEventListener(
      "keydown",
      (this.down = function (e) {
        let flagName = that.getFlagFromKeyboard(e);
        if (typeof flagName !== "undefined") {
          flags[flagName] = true;
        }
      }),
      false
    );
    // 相机将保持锁定在当前位置。此标志仅适用于2D和Columbus视图模式。
    viewer.scene.screenSpaceCameraController.enableTranslate = false;
    // 相机将锁定到当前标题。这个标志只适用于3D和哥伦布视图。
    viewer.scene.screenSpaceCameraController.enableTilt = false;
    document.addEventListener(
      "keyup",
      (this.up = function (e) {
        let flagName = that.getFlagFromKeyboard(e);
        if (typeof flagName !== "undefined") {
          flags[flagName] = false;
        }
      }),
      false
    );
    console.log(funcTick, '0000');
    // 为每一帧添加监听事件
    let m = viewer.clock.onTick.addEventListener(  // 键盘按下事件
      funcTick = () => {
        let camera = viewer.camera;
        let ellipsoid = viewer.scene.globe.ellipsoid;
        cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
        // 根据相机高度设置移动距离
        let moveRate = (cameraHeight / 150.0) * setStep;
        heading = viewer.camera.heading;
        pitch = viewer.camera.pitch;
        roll = viewer.camera.roll;
        // 根据事件调整相机
        // 相机的偏航角、翻滚角和俯仰角
        // 偏航角
        if (flags.headingLeft) {
          that.hprSetting(-0.005 * setStep, 0, 0);
        }
        if (flags.headingRight) {
          that.hprSetting(0.005 * setStep, 0, 0);
        }
        // 俯仰角
        if (flags.picthUp) {
          that.hprSetting(0, 0.01 * setStep, 0);
        }
        if (flags.picthDown) {
          that.hprSetting(0, -0.01 * setStep, 0);
        }
        // 翻滚角
        if (flags.rollLeft) {
          that.hprSetting(0, 0, 0.01 * setStep);
        }
        if (flags.rollRight) {
          that.hprSetting(0, 0, -0.01 * setStep);
        }
        // 向中心点靠近
        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);
        }
        // 相机向前平移
        if (flags.translateFront) {
          camera.rotateDown(Math.PI / 3600000 * setStep)
        }
        // 相机向后平移
        if (flags.translateBehind) {
          camera.rotateUp(Math.PI / 3600000 * setStep)
        }
      });
    return m;
  }
  // 相机翻滚角设置方法
  hprSetting(h, p, r) {
    viewer.camera.setView({
      orientation: {
        heading: heading + h,
        pitch: pitch + p,
        roll: roll + r,
      },
    });
  }
  // 监听键盘按下和松开的状态
  getFlagFromKeyboard(k) {
    switch (k.key) {
      // 按字符的Unicode编码
      // 相机姿态
      case "ArrowUp":
        return "picthUp";
      case "ArrowDown":
        return "picthDown";
      case "ArrowLeft":
        return "headingLeft";
      case "ArrowRight":
        return "headingRight";
      case "j":
        return "rollRight";
      case "l":
        return "rollLeft";
      // 相机向屏幕中心点前进后退
      case "i":
        return "moveForward";
      case "k":
        return "moveBackward";
      // 相机前后左右上下平移
      case "w":
        return "translateFront";
      case "s":
        return "translateBehind";
      case "a":
        return "moveLeft";
      case "d":
        return "moveRight";
      case "q":
        return "moveUp";
      case "e":
        return "moveDown";
      default:
        return undefined;
    }
  }
  /**
   * 销毁键盘漫游事件
   */
  quit() {
    document.removeEventListener("keydown", this.down, false);
    document.removeEventListener("keyup", this.up, false);
    viewer.clock.onTick.removeEventListener(funcTick);
    // 解除禁用鼠标移动地图事件
    viewer.scene.screenSpaceCameraController.enableTranslate = true;
    // 解除视图锁定事件。
    viewer.scene.screenSpaceCameraController.enableTilt = true;
  }
}
export default keyboardRoam;
相关推荐
汪洪墩2 小时前
【Mars3d】设置backgroundImage、map.scene.skyBox、backgroundImage来回切换
开发语言·javascript·python·ecmascript·webgl·cesium
supermapsupport7 小时前
iClent3D for Cesium 实现无人机巡检飞行效果
gis·cesium·supermap·webgis
不浪brown9 小时前
仅需3行代码!带你做一个3D卫星轨道飞行动画
cesium
传说故事1 天前
相机内外参知识
数码相机·相机·相机参数
白嫖叫上我2 天前
Cesium 无人机航线规划(航点航线)
无人机·cesium
汇能感知3 天前
如何测量分辨率
经验分享·笔记·科技·相机
BJ-Giser4 天前
前端解析超图的iserver xml
前端·可视化·cesium
我码玄黄4 天前
在Cesium中加载OD线
前端·javascript·cesium
supermapsupport4 天前
iClient3D for Cesium 实现限高分析
3d·vue·gis·cesium·supermap·webgis
白嫖叫上我5 天前
Cesium 无人机航线规划(区域航线)
无人机·cesium