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;
相关推荐
undefined&&懒洋洋3 天前
Cesium使用flyToBoundingSphere实现倾斜相机视角观察物体
前端·javascript·cesium·webgis
GIS瞧葩菜6 天前
GeoSever发布图层(保姆姬)
wms·geoserver·cesium
新中地GIS开发老师6 天前
地理信息科学专业想搞GIS开发:学前端还是后端?
前端·javascript·arcgis·前端框架·cesium
图灵追慕者7 天前
机器视觉中光源镜头和相机的关系
数码相机·相机·机器视觉·光源·镜头
cyt涛10 天前
WebSocket—双向实时通信
网络·websocket·网络协议·实时·通信·双向·持久性
赤瞳&12 天前
电脑连接海康相机并在PictureBox和HWindowControl中分别显示。
c#·相机
qbbmnnnnnn13 天前
【WebGis开发 - Cesium】三维可视化项目教程---图层管理拓展图层顺序调整功能
vue.js·webgl·三维可视化·cesium·vue3.0·webgis·vuedraggable
卧蚕土豆14 天前
【有啥问啥】张正友标定法浅谈
计算机视觉·相机·1024程序员节
smiler15 天前
cesium两种方式实现贴地
前端·cesium
双子座断点15 天前
QT 机器视觉 1.相机类型
qt·计算机视觉·相机