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

       该类主要用于监听键盘事件并在用户按下不同按键时执行相应的相机操作,如改变相机的位置、偏航角、俯仰角和翻滚角,从而实现在三维场景中的漫游。
以下是代码的主要逻辑:
  1. 导入Cesium库,并定义一个flags对象,其中包含了所有可能触发的键盘漫游状态标志。
  2. keyboardRoam 类包含以下方法:
    • start(viewer, setStep): 初始化键盘监听事件,包括keydown和keyup事件,并在每一帧(clock onTick事件)中执行funcTick函数以更新相机状态。同时禁用默认的鼠标移动地图和平移相机的功能。
    • hprSetting(h, p, r): 设置相机的Heading、Pitch、Roll(即偏航角、俯仰角、翻滚角)。
    • getFlagFromKeyboard(k): 根据按下的键盘按键返回对应的按键名称。
  3. funcTick函数中,根据flags对象中的状态标志来更新相机的位置和姿态。
  4. quit()方法用于销毁键盘监听事件以及恢复鼠标移动地图和平移相机的功能。
通过实例化 keyboardRoam 类并调用 start 方法,可以启用键盘漫游功能;调用 quit 方法则停止漫游并恢复默认的相机控制方式。
      // 引入键盘漫游方法import keyboardRoam from "../utils/roam/keyboardRoam";// 键盘控制相机方法初始化keyboard = new keyboardRoam();// 键盘控制相机方法开始keyboard.start(window.viewer, 1)// 键盘控制相机方法结束keyboard.quit();
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;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/786040.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux gcc day2

mkdir -p 递归的创建目录 rm or rmdir: rmdir :是用来删除空目录的 实际上我们更加常用的是rm命令 rm可以删除普通文件,也可以删除目录,目录是从某次开始就是一棵树就是递归,所以就要递归删除 rm -r [文件名] 递归删除目录或者目…

linux系统命令chkconfig详解,管理系统服务的工具-查看、启用、禁用和设置系统服务的启动级别

目录 一、chkconfig命令介绍 二、命令的主要作用 1、管理服务的启动和停止: 2、配置运行级别: 3、简化系统管理: 4、查看服务状态: 三、命令语法 1、基本语法 2、运行级别 四、获取帮助 1、通过help获取 2、通过man获…

Azure入门实践-如何创建两个虚拟网络的对等连接

在Azure中创建两个虚拟网络(Virtual Network, VNet)之间的对等连接(VNet Peering)可以让这两个虚拟网络中的资源像在同一个网络中一样相互通信。以下是详细的步骤: 1. 登录到Azure门户 打开浏览器,访问Az…

基于“遥感+”蓝碳储量估算、红树林信息提取实践技术应用与科研论文写作

原文链接:基于“遥感”蓝碳储量估算、红树林信息提取实践技术应用与科研论文写作https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247599633&idx5&sn1398cde523f9c5e036e4d478fc1d3388&chksmfa8207f6cdf58ee0a3a2bf652e7ac5cf65636b05f9e3306…

备战蓝桥杯Day36 - 动态规划 - 三角形最小路径和问题

一、什么是动态规划 通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推的方式解决。 哪些问题可以使用动态规划? 1、具有最优子结构:问题的最优解所包含的子结构的解也是最优的 2、具有无后效性:未来…

java项目依赖的依赖加载不到

1、描述: 一个项目包含多个子模块,并且可以根据profiles切换环境。 然后依赖的依赖就是加载不到 上面flow-es-6.8是我封装的一个环境。 2、解决: profiles里要加上默认一个环境配置,如下红色部分: 虽然我在idea右边maven中的profiles选项…

【ElementUI】详细分析DatePicker 日期选择器

目录 前言1. 通用Demo2. 快捷键3. 参数 前言 对于全栈玩家,各个组件都需相应了解才可做好前后端的CRUD 以下为实战结合Element官网的心得体会 如图所示: 1. 通用Demo 如果只想要一个选择日期,而不是范围,Demo如下:…

Docker搭建LNMP环境实战(09):安装mariadb

1、编写mariadb部署配置文件 在文件夹:/mnt/hgfs/dockers/test_site/compose下创建文件:test_site_mariadb.yml,内容如下: version: "3.5" services:test_site_mariadb:container_name: test_site_mariadbimage: mari…

逐步学习Go-Select多路复用

概述 这里又有多路复用,但是Go中的这个多路复用不同于网络中的多路复用。在Go里,select用于同时等待多个通信操作(即多个channel的发送或接收操作)。Go中的channel可以参考我的文章:逐步学习Go-并发通道chan(channel)…

JS基本类型作用域作用域链

#### 作用域链 作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。看一个例子 js var a 1 function fn () {var b a 1console.log(b) } fn() ### 从代码执行来看 首先在创建fn函数时,会创建一个预先包含全局变量对象的作用域链&am…

Gparted工具 初始化磁盘

Gparted工具 初始化磁盘 1、安装 没有此工具请先安装: yum install epel-release yum install gparted yum install yum-utils git gnome-common gcc-c yum-builddep gparted 2、打开Gparted工具,初始化磁盘 使用具有root权限的普通用户打开gparted&…

HWOD:整型数组排序

一、知识点 while(1){}表示永久循环 使用break结束循环 二、题目 1、描述 输入整型数组和排序标识&#xff0c;对其元素按照升序或降序进行排序 2、数据范围 1<n<1000 0<val<100000 3、输入 第一行输入数组元素个数 第二行输入待排序的数组&#x…

电商技术揭秘二:电商平台推荐系统的实现与优化

文章目录 一、推荐系统的重要性1.1 提升用户体验1.1.1 个性化推荐增强用户满意度1.1.2 减少用户选择困难 1.2 增加销售额1.2.1 促进交叉销售和捆绑销售1.2.2 提高用户购买转化率 1.3 数据分析与用户行为理解1.3.1 挖掘用户偏好和购买习惯1.3.2 为产品开发和库存管理提供数据支持…

npm ERR! code CERT_HAS_EXPIRED 淘宝镜像失效

近期vue安装失败&#xff0c;具体如下&#xff1a; 1.先npm cache clean --force 再下载 插件后缀加上 --legacy-peer-deps 2.certificate has expired npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.o…

rollup 插件的使用及常用插件介绍

rollup 插件的使用及常用插件介绍 如果我们需要打包更为复杂的代码&#xff0c;就需要配置一些插件来实现。比如导入使用 NPM 安装的模块、使用 Babel 编译代码、处理 JSON 文件等等。 插件使用 rollup 是用于打包 JavaScript 的工具&#xff0c;如果我们想处理其他文件&…

Windows安装禅道系统结合Cpolar实现公网访问内网BUG管理服务

文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名5.1 配置二级子域名6. 使用固定二级子域名远程 前言 BUG管理软件,作为软件测试工程师的必备工具之一。在…

943: 顺序表插入操作的实现

学习版 【C语言】 需要扩充数组 【C】 #include <iostream> #include <vector> #include <algorithm> using namespace std; class MyLinkedList { public:struct LinkedNode{int val;LinkedNode* next;LinkedNode(int x) :val(x), next(NULL) {}};MyLin…

TypeScript语法快速上手

TypeScript语法 对比ts编译器类型注解新增类型数组自定义类型注解函数类型对象类型元组类型类型推断枚举类型 对比 最大区别&#xff1a;ts能在编译时就能发现类型错误的问题&#xff0c;而js只有在系统运行时再通过异常中断来发现 ts的底层仍是js&#xff0c;但ts能够有效减少…

代码随想录算法训练营第二十七天|131.分割回文串、93.复原IP地址

文档链接&#xff1a;https://programmercarl.com/ LeetCode131.分割回文串 题目链接&#xff1a;https://leetcode.cn/problems/palindrome-partitioning/ 思路&#xff1a;把回溯的树画出来就好很多。startIndex用来控制切割的位置 例如对于字符串abcdef&#xff1a; 组…

深度学习入门:从理论到实践的全面指南

深度学习入门&#xff1a;从理论到实践的全面指南 引言第一部分&#xff1a;深度学习基础第二部分&#xff1a;数学基础第三部分&#xff1a;编程和工具第四部分&#xff1a;构建你的第一个模型第五部分&#xff1a;深入学习结语 引言 大家好&#xff0c;这里是程序猿代码之路。…