当前位置:网站首页>Cesium keyboard and mouse control camera roaming (source code + principle explanation)
Cesium keyboard and mouse control camera roaming (source code + principle explanation)
2022-07-23 21:34:00 【Giser Xiaohui】
Cesium Keyboard and mouse control camera roaming ( Source code + Principle explanation )
On major blog platforms ,Cesium Using the keyboard to control the camera roaming source code, many people have posted the source code , In the process of browsing these source codes, I found that the methods adopted by everyone are basically the same , Most of the code is a model , There are even some blog posts that partially delete the code , Lead to incomprehensible situations . The common problem with these blogs is that there is no explanation , It's very unfriendly to new people .
This paper uses the same idea to complete the keyboard and mouse while controlling the camera roaming function , And attach necessary instructions , Recommended collection .
1 The effect achieved
- Keyboard control :w, Camera forward ; s, Camera back ;a, Camera shift left ;d, The camera moves to the right ;q, Move the camera up ;e, The camera moves down .
- Mouse control : Hold down the left mouse button and move the mouse in a certain direction to turn the camera lens in that direction .
2 Realize the idea
Turn on the keyboard and mouse to control the camera roaming :
- Disable the default camera operation mode , Prevent mouse action conflicts ;
- Set marker for camera walkthrough ;
- Add mouse listening Events , Monitor and hold down the mouse movement to change the roaming flag ;
- Add keyboard monitoring events , Monitor the keyboard to change the roaming flag ;
- Add render event , Render according to the change of roaming mark .
Turn off the keyboard and mouse to control the camera roaming :
- Remove mouse listening Events ;
- Remove keyboard listening Events ;
- Remove render Events ;
- Enable the default camera operation mode .
3 Source code and description
3.1 HTML Code
<div id="cesiumContainer" style="width:100%;height:100%"></div>
3.2 JavaScript Code
// Initialize the earth widget
let viewer = new Cesium.Viewer('cesiumContainer');
// Declare variables , The following code may be used many times
let scene = viewer.scene;
let canvas = viewer.canvas; // This is used here viewer.canvas or viewer.scene.canvas Fine , Is the same canvas object
let camera = viewer.camera;
let ellipsoid = viewer.scene.globe.ellipsoid;
// Declare camera walk mark
let flags = null;
// Statement handler
let handler = null;
/** * Enter keyboard and mouse roaming mode */
function enterKeyBoardMouseRoamingMode() {
console.log(' Enter roaming mode ');
// 1. Disable the default camera operation mode
scene.screenSpaceCameraController.enableRotate = false;
scene.screenSpaceCameraController.enableTranslate = false;
scene.screenSpaceCameraController.enableZoom = false;
scene.screenSpaceCameraController.enableTilt = false;
scene.screenSpaceCameraController.enableLook = false;
// 2. Initialize the marker of camera roaming
flags = {
looking: false, // Whether you are adjusting the viewing angle with the mouse
startPosition: null, // Where the mouse pointer starts to move
endPosition: null, // Where the mouse pointer stops moving
moveForward: false, // Whether to move forward
moveBackward: false, // Whether to move backward
moveLeft: false, // Move left
moveRight: false, // Whether to move to the right
moveUp: false, // Whether to move up
moveDown: false, // Whether to move down
}; // Camera walkthrough marker
// 3. Add mouse listening Events
handler = new Cesium.ScreenSpaceEventHandler(canvas);
// Left key press
handler.setInputAction((movement) => {
flags.looking = true;
flags.startPosition = Cesium.Cartesian3.clone(movement.position);
flags.endPosition = Cesium.Cartesian3.clone(movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
// Mouse movement
handler.setInputAction((movement) => {
flags.endPosition = movement.endPosition;
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// Click pop-up
handler.setInputAction(() => {
flags.looking = false;
}, Cesium.ScreenSpaceEventType.LEFT_UP);
// 4. Add keyboard monitoring events
// Keyboard press event
document.addEventListener('keydown', keyDown, false);
// Keyboard bounce event
document.addEventListener('keyup', keyUp, false);
// 5. Add render event
viewer.clock.onTick.addEventListener(renderEvent);
}
// DOM Add a button to turn on keyboard and mouse roaming mode , Use absolute positioning to put it in the upper left corner of the screen , Used for testing
let enterButton = document.createElement('button');
enterButton.innerText = ' Turn on ';
enterButton.style.position = 'absolute';
enterButton.style.left = '20px';
enterButton.style.top = '20px';
enterButton.onclick = enterKeyBoardMouseRoamingMode;
document.body.appendChild(enterButton);
/** * Exit keyboard and mouse roaming mode */
function exitKeyBoardMouseRoamingMode() {
console.log(' Exit roaming ');
// 1. Remove mouse listening Events
if (handler) {
handler.destroy();
handler = null;
}
// 2. Remove keyboard listening Events
document.removeEventListener('keydown', keyDown, false);
document.removeEventListener('keyup', keyUp, false);
// 3. Remove render Events
viewer.clock.onTick.removeEventListener(renderEvent);
// 4. Enables the default camera operation mode
scene.screenSpaceCameraController.enableRotate = true;
scene.screenSpaceCameraController.enableTranslate = true;
scene.screenSpaceCameraController.enableZoom = true;
scene.screenSpaceCameraController.enableTilt = true;
scene.screenSpaceCameraController.enableLook = true;
}
// DOM Add a button to turn off keyboard and mouse roaming mode , Use absolute positioning to put it in the upper left corner of the screen , Used for testing
let exitButton = document.createElement('button');
exitButton.innerText = ' close ';
exitButton.style.position = 'absolute';
exitButton.style.left = '70px';
exitButton.style.top = '20px';
exitButton.onclick = exitKeyBoardMouseRoamingMode;
document.body.appendChild(exitButton);
/** * Press the keyboard */
function keyDown(event) {
let flagName = getFlagFromKeyCode(event.keyCode);
if (typeof flagName !== 'undefined') {
flags[flagName] = true;
}
}
/** * The keyboard bounced up */
function keyUp(event) {
let flagName = getFlagFromKeyCode(event.keyCode);
if (typeof flagName !== 'undefined') {
flags[flagName] = false;
}
}
/** * Rendering function */
function renderEvent() {
// Lens turn
if (flags.looking) {
let width = viewer.canvas.clientWidth;
let height = viewer.canvas.clientHeight;
let lookFactor = 0.05; // Lens steering coefficient , The more sensitive the coefficient is , Take here 0.05 It's moderate
let x = (flags.endPosition.x - flags.startPosition.x) / width;
let y = -(flags.endPosition.y - flags.startPosition.y) / height;
// To calculate the x,y after , There are two ways to implement the lens , Tested sensory style 1 Smoother
// The way 1
camera.lookRight(x * lookFactor);
camera.lookUp(y * lookFactor);
// The way 2
// camera.setView({
// orientation: {
// heading: camera.heading + x * lookFactor,
// pitch: camera.pitch + y * lookFactor,
// roll: 0.0,
// },
// });
}
// Determine the speed of lens movement according to the height
let cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
let moveRate = cameraHeight / 100.0;
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);
}
}
/** * Get... From the keyboard code flag Mark */
function getFlagFromKeyCode(keyCode) {
switch (keyCode) {
case 'W'.charCodeAt(0):
return 'moveForward';
case 'S'.charCodeAt(0):
return 'moveBackward';
case 'Q'.charCodeAt(0):
return 'moveUp';
case 'E'.charCodeAt(0):
return 'moveDown';
case 'D'.charCodeAt(0):
return 'moveRight';
case 'A'.charCodeAt(0):
return 'moveLeft';
default:
return undefined;
}
}
4 Without mouse control
If we only need keyboard control in our project, we can simplify the code as follows :
4.1 HTML Code
<div id="cesiumContainer" style="width:100%;height:100%"></div>
4.2 JavaScript Code
// Initialize the earth widget
let viewer = new Cesium.Viewer('cesiumContainer');
// Declare variables , The following code may be used many times
let camera = viewer.camera;
let ellipsoid = viewer.scene.globe.ellipsoid;
// Declare camera walk mark
let flags = null;
/** * Enter keyboard roaming mode */
function enterKeyBoardMouseRoamingMode() {
console.log(' Enter roaming mode ');
// 1. Initialize the marker of camera roaming
flags = {
moveForward: false, // Whether to move forward
moveBackward: false, // Whether to move backward
moveLeft: false, // Move left
moveRight: false, // Whether to move to the right
moveUp: false, // Whether to move up
moveDown: false, // Whether to move down
}; // Camera walkthrough marker
// 2. Add keyboard monitoring events
// Keyboard press event
document.addEventListener('keydown', keyDown, false);
// Keyboard bounce event
document.addEventListener('keyup', keyUp, false);
// 3. Add render event
viewer.clock.onTick.addEventListener(renderEvent);
}
// DOM Add a button to turn on keyboard and mouse roaming mode , Use absolute positioning to put it in the upper left corner of the screen , Used for testing
let enterButton = document.createElement('button');
enterButton.innerText = ' Turn on ';
enterButton.style.position = 'absolute';
enterButton.style.left = '20px';
enterButton.style.top = '20px';
enterButton.onclick = enterKeyBoardMouseRoamingMode;
document.body.appendChild(enterButton);
/** * Exit keyboard roaming mode */
function exitKeyBoardMouseRoamingMode() {
console.log(' Exit roaming ');
// 1. Remove keyboard listening Events
document.removeEventListener('keydown', keyDown, false);
document.removeEventListener('keyup', keyUp, false);
// 2. Remove render Events
viewer.clock.onTick.removeEventListener(renderEvent);
}
// DOM Add a button to turn off keyboard and mouse roaming mode , Use absolute positioning to put it in the upper left corner of the screen , Used for testing
let exitButton = document.createElement('button');
exitButton.innerText = ' close ';
exitButton.style.position = 'absolute';
exitButton.style.left = '70px';
exitButton.style.top = '20px';
exitButton.onclick = exitKeyBoardMouseRoamingMode;
document.body.appendChild(exitButton);
/** * Press the keyboard */
function keyDown(event) {
let flagName = getFlagFromKeyCode(event.keyCode);
if (typeof flagName !== 'undefined') {
flags[flagName] = true;
}
}
/** * The keyboard bounced up */
function keyUp(event) {
let flagName = getFlagFromKeyCode(event.keyCode);
if (typeof flagName !== 'undefined') {
flags[flagName] = false;
}
}
/** * Rendering function */
function renderEvent() {
// Determine the speed of lens movement according to the height
let cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
let moveRate = cameraHeight / 100.0;
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);
}
}
/** * Get... From the keyboard code flag Mark */
function getFlagFromKeyCode(keyCode) {
switch (keyCode) {
case 'W'.charCodeAt(0):
return 'moveForward';
case 'S'.charCodeAt(0):
return 'moveBackward';
case 'Q'.charCodeAt(0):
return 'moveUp';
case 'E'.charCodeAt(0):
return 'moveDown';
case 'D'.charCodeAt(0):
return 'moveRight';
case 'A'.charCodeAt(0):
return 'moveLeft';
default:
return undefined;
}
}
5 Extended reading
If you have difficulty understanding this blog post , Please browse the following blog posts , Help you understand Cesium In the event .
Cesium Details of the incident
Cesium Core class Viewer- Viewer details
边栏推荐
- 【arxiv】第一次上传论文小记
- 手机股票开户安全吗?
- Leetcode hot topic hot52-100
- Cluster chat server: creation of project directory
- Identify some positions in the parenthesis sequence
- 集群聊天服务器:集群与分布式理论
- 221. Largest square ● &1277. Square submatrix with statistics all 1 ● ●
- Green Tao theorem (3): anti uniform functions and their generated sigma Algebras
- 1061 Dating
- 博客总排名为918
猜你喜欢

Cluster chat server: Framework Design of model data layer and encapsulation of database code

宇树A1机器狗手势控制

大三实习生,字节跳动面经分享,已拿Offer

Yushu A1 robot dog gesture control

博客总排名为918

集群聊天服务器:如何解决跨服务器通信问题 | redis发布-订阅

Leetcode hot topic hot52-100

集群聊天服务器:工程目录的创建

Serveur de chat de Cluster: conception de la table de base de données

TCP half connection queue and full connection queue (the most complete in History)
随机推荐
vite3学习记录
Day109.尚医通:集成Nacos、医院列表、下拉列表查询、医院上线功能、医院详情查询
Cluster chat server: creation of project directory
Synchro esp32c3 Hardware Configuration Information serial port Print Output
Unity - 3D mathematics -vector3
scala编程(中级进阶实验应用)
合宙ESP32C3硬件配置信息串口打印输出
Chapter 2 Regression
OOM机制
剑指Offer第二版:字符串(简单)
OpenCV图像处理——拉普拉斯金字塔
Failed to introspect class feignclientfactorybean exception troubleshooting
Kubevela offline installation
One of QT desktop whiteboard tools (to solve the problem of unsmooth curve -- Bezier curve)
Pay more attention to which securities company has the lowest commission? Is it safe to open an account online?
googletest
Protocol buffers 的问题和滥用
北大清华2022年在各地录取人数排名
Unity solves that animation is not available: the animationclip 'xxx' used by the animation component 'xxx' must be marked as legacy
1062 Talent and Virtue