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;
相关推荐
哈市雪花3 天前
相机:Camera原理讲解(使用OpenGL+QT开发三维CAD)
qt·3d·交互·相机·图形学·opengl·视角
一个有理想的摸鱼选手4 天前
CesiumLite-开箱即用的轻量化三维地图包(持续更新中...)
gis·cesium
不浪brown14 天前
重磅开源!Cesium实现高度雾仿真,谁再说Cesium做不出好效果?
cesium
青山Coding15 天前
Cesium基础(五)实体创建与拖拽
前端·cesium
Mapmost18 天前
全新升级!3DTiles加载速度Mapmost完胜Cesium
性能优化·webgl·cesium
不浪brown18 天前
告别静态水面的平庸!Cesium中实现水面倒影+动态流向的逼真水特效
cesium
汪洪墩19 天前
使用Mars3d加载热力图的时候,出现阴影碎片
开发语言·前端·javascript·vue.js·cesium
springfe010120 天前
Cesium 3D地图 图元 圆柱 图片实现
前端·cesium
卓小帅的博客21 天前
解决电脑第一排按键功能失效的问题
电脑·键盘
不浪brown22 天前
浏览器3D渲染卡成PPT?6个性能优化指标,你都知道吗?
three.js·cesium