236 lines
6.0 KiB
JavaScript
236 lines
6.0 KiB
JavaScript
|
/*
|
|||
|
* @Description: 使用键盘控制地图漫游
|
|||
|
* @Version: 1.0
|
|||
|
* @Author: Julian
|
|||
|
* @Date: 2022-04-07 16:04:07
|
|||
|
* @LastEditors: Julian
|
|||
|
* @LastEditTime: 2022-04-07 18:40:40
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @description: 使用键盘控制地图漫游初始化
|
|||
|
* @param {*} _viewer
|
|||
|
* @return {*}
|
|||
|
*/
|
|||
|
function keyboardMapRoamingInit(_viewer) {
|
|||
|
// 添加键盘监听事件
|
|||
|
document.addEventListener('keydown', keyDown.bind(_viewer), false);
|
|||
|
document.addEventListener('keyup', keyUp.bind(_viewer), false);
|
|||
|
|
|||
|
// 为每一帧添加监听事件
|
|||
|
_viewer && _viewer.clock.onTick.addEventListener(function () {
|
|||
|
keyboardMapRoamingRender(_viewer);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
// 定义事件组
|
|||
|
let flags = {
|
|||
|
// 相机位置
|
|||
|
moveForward: false,
|
|||
|
moveBackward: false,
|
|||
|
moveLeft: false,
|
|||
|
moveRight: false,
|
|||
|
moveUp: false,
|
|||
|
moveDown: false,
|
|||
|
// 相机姿态
|
|||
|
lookUp: false,
|
|||
|
lookDown: false,
|
|||
|
lookLeft: false,
|
|||
|
lookRight: false,
|
|||
|
twistLeft: false,
|
|||
|
twistRight: false,
|
|||
|
// 缩放
|
|||
|
zoomIn: false,
|
|||
|
zoomOut: false
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// 相机位置:W:向前;S:向后;D:向右;A:向左;Q:升高;E:降低;
|
|||
|
// 相机姿态:↑:抬头;↓:低头;←:左转;→:右转;0:顺时针;.:逆时针
|
|||
|
// 缩放:+:放大,-:缩小;
|
|||
|
|
|||
|
/**
|
|||
|
* @description: 根据键盘输入字符返回事件信息
|
|||
|
* @param {*} key
|
|||
|
* @return {*}
|
|||
|
*/
|
|||
|
function getFlagFromKeyboard(key) {
|
|||
|
switch (key) {
|
|||
|
// 按字符的Unicode编码
|
|||
|
// 相机位置
|
|||
|
case 87:
|
|||
|
return 'moveForward';
|
|||
|
case 83:
|
|||
|
return 'moveBackward';
|
|||
|
case 68:
|
|||
|
return 'moveRight';
|
|||
|
case 65:
|
|||
|
return 'moveLeft';
|
|||
|
case 81:
|
|||
|
return 'moveUp';
|
|||
|
case 69:
|
|||
|
return 'moveDown';
|
|||
|
// 相机姿态
|
|||
|
case 38:
|
|||
|
return 'lookUp';
|
|||
|
case 40:
|
|||
|
return 'lookDown';
|
|||
|
case 37:
|
|||
|
return 'lookLeft';
|
|||
|
case 39:
|
|||
|
return 'lookRight';
|
|||
|
case 96:
|
|||
|
return 'twistLeft';
|
|||
|
case 110:
|
|||
|
return 'twistRight';
|
|||
|
// 缩放
|
|||
|
case 107:
|
|||
|
return 'zoomIn';
|
|||
|
case 109:
|
|||
|
return 'zoomOut';
|
|||
|
default:
|
|||
|
return undefined;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @description: 键盘按下
|
|||
|
* @param {*} event
|
|||
|
* @return {*}
|
|||
|
*/
|
|||
|
function keyDown(event) {
|
|||
|
let _viewer = this
|
|||
|
// 判断是否有输入框聚焦
|
|||
|
function isInputFocused() {
|
|||
|
const activeElement = document.activeElement;
|
|||
|
return (activeElement.tagName.toLowerCase() === 'input' && activeElement.type !== 'checkbox') ||
|
|||
|
activeElement.tagName.toLowerCase() === 'textarea' ||
|
|||
|
activeElement.getAttribute('role') === 'textarea';
|
|||
|
}
|
|||
|
|
|||
|
if (isInputFocused()) {
|
|||
|
// console.log('页面上有输入框已经获取焦点');
|
|||
|
} else if (_viewer.trackedEntity) {
|
|||
|
// console.log('视角跟随中');
|
|||
|
} else if (_viewer._firstPersonView) {
|
|||
|
// console.log('第一人称视角中');
|
|||
|
} else if (_viewer._disableKeyboardEvent) {
|
|||
|
// console.log('禁用键盘事件');
|
|||
|
} else if (event.ctrlKey && event.altKey) {
|
|||
|
if (event.key === 'v' || event.key === 'V') {
|
|||
|
let camera = _viewer.camera
|
|||
|
_viewer._CAMERA_SHORTCUT_VIEW = {
|
|||
|
orientation: { heading: camera.heading, pitch: camera.pitch, roll: camera.roll },
|
|||
|
position: { x: camera.position.x, y: camera.position.y, z: camera.position.z }
|
|||
|
}
|
|||
|
localStorage.setItem('CAMERA_SHORTCUT_VIEW', JSON.stringify(_viewer._CAMERA_SHORTCUT_VIEW))
|
|||
|
}
|
|||
|
if (event.key === 'f' || event.key === 'F') {
|
|||
|
let CAMERA_SHORTCUT_VIEW = localStorage.getItem('CAMERA_SHORTCUT_VIEW')
|
|||
|
_viewer._CAMERA_SHORTCUT_VIEW = JSON.parse(CAMERA_SHORTCUT_VIEW)
|
|||
|
if (_viewer._CAMERA_SHORTCUT_VIEW && _viewer._CAMERA_SHORTCUT_VIEW.position && _viewer._CAMERA_SHORTCUT_VIEW.orientation) {
|
|||
|
_viewer.camera.flyTo({
|
|||
|
destination: _viewer._CAMERA_SHORTCUT_VIEW.position,
|
|||
|
orientation: _viewer._CAMERA_SHORTCUT_VIEW.orientation
|
|||
|
})
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
// console.log('页面上没有输入框获取焦点');
|
|||
|
let flagName = getFlagFromKeyboard(event.keyCode);
|
|||
|
if (typeof flagName !== 'undefined') {
|
|||
|
flags[flagName] = true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @description: 键盘弹起
|
|||
|
* @param {*} event
|
|||
|
* @return {*}
|
|||
|
*/
|
|||
|
function keyUp(event) {
|
|||
|
let flagName = getFlagFromKeyboard(event.keyCode);
|
|||
|
if (typeof flagName !== 'undefined') {
|
|||
|
flags[flagName] = false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @description: 根据事件调整相机
|
|||
|
* @param {*} _viewer
|
|||
|
* @return {*}
|
|||
|
*/
|
|||
|
function keyboardMapRoamingRender(_viewer) {
|
|||
|
if(!_viewer.scene.screenSpaceCameraController.enableTilt) {
|
|||
|
return
|
|||
|
}
|
|||
|
let camera = _viewer.camera;
|
|||
|
let ellipsoid = _viewer.scene.globe.ellipsoid;
|
|||
|
let cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
|
|||
|
|
|||
|
// 根据相机高度设置移动距离,比默认距离移动效果更好
|
|||
|
let moveRate = cameraHeight / 20.0;
|
|||
|
let rotationRate = moveRate / 500000 / Cesium.Math.toDegrees(camera.pitch);
|
|||
|
|
|||
|
if (flags.moveForward) {
|
|||
|
// camera.moveForward(moveRate);
|
|||
|
camera.rotate(camera.right, -rotationRate);
|
|||
|
}
|
|||
|
if (flags.moveBackward) {
|
|||
|
// camera.moveBackward(moveRate);
|
|||
|
camera.rotate(camera.right, rotationRate);
|
|||
|
}
|
|||
|
if (flags.moveLeft) {
|
|||
|
// camera.moveLeft(moveRate);
|
|||
|
camera.rotate(camera.up, -rotationRate);
|
|||
|
}
|
|||
|
if (flags.moveRight) {
|
|||
|
// camera.moveRight(moveRate);
|
|||
|
camera.rotate(camera.up, rotationRate);
|
|||
|
}
|
|||
|
if (flags.moveUp) {
|
|||
|
camera.moveUp(moveRate);
|
|||
|
}
|
|||
|
if (flags.moveDown) {
|
|||
|
camera.moveDown(moveRate);
|
|||
|
}
|
|||
|
if (flags.lookUp) {
|
|||
|
camera.lookUp();
|
|||
|
}
|
|||
|
if (flags.lookDown) {
|
|||
|
camera.lookDown();
|
|||
|
}
|
|||
|
if (flags.lookLeft) {
|
|||
|
camera.lookLeft();
|
|||
|
}
|
|||
|
if (flags.lookRight) {
|
|||
|
camera.lookRight();
|
|||
|
}
|
|||
|
if (flags.twistLeft) {
|
|||
|
camera.twistLeft();
|
|||
|
}
|
|||
|
if (flags.twistRight) {
|
|||
|
camera.twistRight();
|
|||
|
}
|
|||
|
// 根据相机高度设置缩放参数
|
|||
|
if (flags.zoomIn) {
|
|||
|
let height = cameraHeight / 2
|
|||
|
if (height < 1) {
|
|||
|
height = 0
|
|||
|
}
|
|||
|
camera.zoomIn(height);
|
|||
|
}
|
|||
|
if (flags.zoomOut) {
|
|||
|
let height = cameraHeight / 2
|
|||
|
if ((cameraHeight + cameraHeight) >= 50000000) {
|
|||
|
height = 50000000 - cameraHeight
|
|||
|
}
|
|||
|
camera.zoomOut(height);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
export { keyboardMapRoamingInit }
|