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;
相关推荐
qbbmnnnnnn18 分钟前
【WebGis开发 - Cesium】如何确保Cesium场景加载完毕
前端·javascript·vue.js·gis·cesium·webgis·三维可视化开发
余生H4 天前
拿下奇怪的前端报错:某些多摄手机拉取部分摄像头视频流会导致应用崩溃,该如何改善呢?
前端·javascript·webrtc·html5·webview·相机
汪洪墩4 天前
循环生成管道线PolylineVolumeEntity,生成一个添加一个
vue.js·3d·地图·cesium·webgis
hylreg5 天前
根据给定的相机和镜头参数,估算相机的内参。
相机·相机模型参数
roman_fan7 天前
基于RealSense D435相机实现手部姿态重定向
机器人·相机
roman_fan10 天前
基于 RealSense D435相机实现手部姿态检测
目标检测·相机
方永锐11 天前
切换笔记本键盘的启用与禁用状态
windows·笔记本电脑·键盘·批处理
风翼靓崽12 天前
记一次键盘f2和f5键被自动触发情况
计算机外设·键盘
用你的胜利博我一笑吧12 天前
supermap iclient3d for cesium中entity使用
前端·javascript·vue.js·3d·cesium·supermap