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 方法则停止漫游并恢复默认的相机控制方式。
 
      // 引入键盘漫游方法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;相关文章:
cesium键盘控制相机位置和姿态
该类主要用于监听键盘事件并在用户按下不同按键时执行相应的相机操作,如改变相机的位置、偏航角、俯仰角和翻滚角,从而实现在三维场景中的漫游。 以下是代码的主要逻辑: 导入Cesium库,并定义一个flags对象,其中包含了…...
 
基于ArrayList实现简单洗牌
前言 在之前的那篇文章中,我们已经认识了顺序表—>http://t.csdnimg.cn/2I3fE 基于此,便好理解ArrayList和后面的洗牌游戏了。 什么是ArrayList? ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表&…...
Paddle实现人脸对比
人脸对比 人脸对比,顾名思义,就是对比两个人脸的相似度。本文将用Paddle实现这一功能。 PS:作者肝了整整3天才稍微搞明白实现方法 数据集准备 这里使用百度AI Studio的开源数据集: 人脸数据_数据集-飞桨AI Studio星河社区 (b…...
 
挖一挖:PostgreSQL Java里的double类型存储到varchar精度丢失问题
前言 大概故事是这样的,PostgreSQL数据库,表结构: create table t1(a varchar);然后使用标准的Java jdbc去插入数据,其基本代码如下: import java.sql.*; public class PgDoubleTest {public static void main(Stri…...
函数对象基本使用
一、函数对象概念 1.重载函数调用操作符的类,其对象常称为函数对象 2.函数对象使用重载的()时,行为类似函数调用,也叫仿函数 本质: 函数对象(仿函数)是一个类,不是一个函数 二、函数对象使用 特点: 函…...
浅谈HTTP
浅谈HTTP 要通过netty实现HTTP服务器(或者客户端),首先你要了解HTTP协议。 HTTP在客户端 - 服务器计算模型中用作请求 - 响应协议。 例如,web浏览器可以是客户端,并且在托管网站的计算机上运行的应用程序可以是服务器。 客户端向服务器提交…...
 
HarmonyOS NEXT应用开发之@Provide装饰器和\@Consume装饰器:与后代组件双向同步
Provide和Consume,应用于与后代组件的双向数据同步,应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递,Provide和Consume摆脱参数传递机制的束缚,实现跨层级传递。 其中Provide装饰的变…...
 
Docker 安装 | 部署MySQL 8.x 初始设置
1、准备工作 如果不想看前面的废话请直接右边目录跳到 运行容器 处 默认你已经有 docker 环境。 Windows 推荐 Docker Desktop (下载地址)并基于 WSL2 运行 Docker 环境 mac 推荐 Orbstack (下载地址)(这个很节省资源&…...
linux三剑客之流编辑器sed
sed(stream editor)是Linux和Unix系统中一个非常强大的文本处理工具。它主要用于对文本数据进行过滤和转换。sed 可以在不打开文件的情况下,直接对输入流进行操作,并且可以将结果输出到标准输出或文件。 基本语法: s…...
 
【Android Studio】上位机-安卓系统手机-蓝牙调试助手
【Android Studio】上位机-安卓系统手机-蓝牙调试助手 文章目录 前言AS官网一、手机配置二、移植工程三、配置四、BUG五、Java语言总结 前言 提示:以下是本篇文章正文内容,下面案例可供参考 AS官网 AS官网 一、手机配置 Android Studio 下真机调试 …...
 
怎样把学浪购买的课程下载下来
如何把学浪已购买的课程下载下来?这里就教大家一个方法,利用一个工具轻轻松松把视频下载下来 这个工具我打包成压缩包了,有需要的自己取一下 链接:https://pan.baidu.com/s/1y7vcqILToULrYApxfEzj_Q?pwdkqvj 提取码:kqvj --来自百度网盘超级会员V1…...
 
SD-WAN如何解决更有性价比地跨境网络问题
云桥通SD-WAN利用智能路由和负载均衡技术,优化数据传输路径,提高网络性能和可靠性。这意味着数据在跨国传输时可以更快到达目的地,减少延迟和丢包率。跨境SD-WAN提高了网络连接速度和质量,使用户能够更快地访问跨国业务所需的资源…...
 
第15章 File类与IO流
一 java.io.File类的使用 1.1 概述 File类及本章下的各种流,都定义在java.io包下。一个File对象代表硬盘或网络中可能存在的一个文件或者文件目录(俗称文件夹),与平台无关。(体会万事万物皆对象)File 能新…...
 
C语言基础语法-教案16(从小白到劝退之结构体初阶)
最近给大家争取到一个 深夜福利 保证你在深夜手机刷到 嘎嘎香~ 那就是 大流量卡 缺点:月租太便宜 185GB~ 100分钟通话时长~ 长期套餐~ 畅想自由的气息 流量自由的同时还拥有超长通话,而且免费领取。 名额有限,咱们废话不多说直接上…...
 
Linux:ip和ip协议的初步认识
文章目录 ip协议基本认识ip协议的报头网段划分ip的类型划分 ip协议基本认识 前面对于TCP的内容已经基本结束了,那么这也就意味着在传输层也已经结束了,那么下一步要进入的是的是网络层,网络层中也有很多种协议,这里主要进行解析的…...
 
Android12 简单的共享内存驱动实现 参考Ashmem
Android12 共享内存驱动实现 SOC:RK3568 system:Android12 概述: 1. 概述 Ashmem(Anonymous Shared Memory,Android 匿名共享内存),它基于 mmap 系统调用,可以让不同进程将同一段…...
物理安全和逻辑安全在信息安全中的重要作用
在信息时代,信息安全已经成为企业和个人不可或缺的重要组成部分。物理安全和逻辑安全作为信息安全的两大支柱,发挥着至关重要的作用。 什么是物理安全和逻辑安全? 物理安全是指通过技术手段,对计算机设备、网络设备、数据中心等…...
每日一题 --- 滑动窗口最大值[力扣][Go]
滑动窗口最大值 题目:239. 滑动窗口最大值 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1࿱…...
TensorBoard可视化+Confustion Matrix Drawing
for later~ 代码阅读 1. 加载trainset import argparse import logging import os import numpy as npimport torch from torch import distributed from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterfrom backbones import get_…...
 
012——LED模块驱动开发(基于I.MX6uLL)
目录 一、 硬件原理图 二、 驱动程序 三、 应用程序 四、 Makefile 五、操作 一、 硬件原理图 又是非常经典的点灯环节 ,每次学新语言第一步都是hello world,拿到新板子或者学习新的操作系统,第一步就是点灯。 LED 的驱动方式࿰…...
 
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
 
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
 
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
 
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
 
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
