基础框架vue3 + vite。
在操作cesium时,默认使用鼠标左键按住拖动,或者中键安装拖动,在操作上来说是挺便利的,但是有些习惯键盘的操作,那么就可以做如下修改。
cesium默认用鼠标操作场景的转换 ,修改为用键盘操作上下左右移动。废话不多,代码如下:
<template>
<div id="cesiumContainer" style="height: 100vh;"></div>
<div id="toolbar" style="position: fixed;top:20px;left:220px;">
<el-breadcrumb :separator-icon="ArrowRight">
<el-breadcrumb-item>场景</el-breadcrumb-item>
<el-breadcrumb-item>相机教程</el-breadcrumb-item>
</el-breadcrumb>
<div id="latlng_show" style="width:100vw;position:absolute;top:30px;left:15px;z-index:1;font-size:15px;">
<div style="width:auto;height:30px;margin-left: 20px;">
<span style="color:#fff">点击cesium显示屏开始</span>
</div>
<div style="width:auto;height:30px;margin-left: 20px;">
<span style="color:#fff">w/s - 场景坐标向前/向后移动</span>
</div>
<div style="width:auto;height:30px;margin-left: 20px;">
<span style="color:#fff">a/d - 场景坐标向左/向右移动</span>
</div>
<div style="width:auto;height:30px;margin-left: 20px;">
<span style="color:#fff">q/e - 场景坐标向上/向下移动</span>
</div>
<div style="width:auto;height:30px;margin-left: 20px;">
<span style="color:#fff">鼠标左键按下加上鼠标移动可更改查看方向</span>
</div>
</div>
</div>
</template>
<script setup>
import {ArrowRight} from '@element-plus/icons-vue'
import {onMounted, ref} from "vue";
import * as Cesium from "cesium";
import InitCesium from "../js/InitCesiumHide.js";
let viewer = null;
let points = ref({
position: null
});
onMounted(() => {
let initCesium = new InitCesium('cesiumContainer');
viewer = initCesium.initViewer({});
flyToRight2();
let scene = viewer.scene;
let canvas = scene.canvas;
// 重点在画布上
canvas.setAttribute('tabindex', '0');
canvas.onclick = function () {
canvas.focus();
}
let ellipsoid = scene.globe.ellipsoid;
// 禁用默认事件处理程序 屏幕空间控制
scene.screenSpaceCameraController.enableRotate = false;// 旋转
scene.screenSpaceCameraController.enableTranslate = false;
scene.screenSpaceCameraController.enableZoom = false;
scene.screenSpaceCameraController.enableTilt = false;
scene.screenSpaceCameraController.enableLook = false;
let startMousePosition;
let mousePosition;
const flags = {
looking: false,
moveForward: false,
moveBackward: false,
moveUp: false,
moveDown: false,
moveLeft: false,
moveRight: false
};
let handler = new Cesium.ScreenSpaceEventHandler(canvas);
handler.setInputAction(function (movement) {
flags.looking = true;
mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
handler.setInputAction(function (movement) {
mousePosition = movement.endPosition;
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(function (position) {
flags.looking = false;
}, Cesium.ScreenSpaceEventType.LEFT_UP);
document.addEventListener('keydown', function (e) {
let flagName = getFlagForKeyCode(e.key.toUpperCase());
if (typeof flagName !== 'undefined') {
flags[flagName] = true;
}
}, false);
document.addEventListener('keyup', function (e) {
let flagName = getFlagForKeyCode(e.key.toUpperCase());
if (typeof flagName !== 'undefined') {
flags[flagName] = false;
}
}, false);
viewer.clock.onTick.addEventListener(function (clock) {
let camera = viewer.camera;
if (flags.looking) {
let width = canvas.clientWidth;
let height = canvas.clientHeight;
// 坐标(0.0,0.0)将是单击鼠标的位置
let x = (mousePosition.x - startMousePosition.x) / width;
let y = -(mousePosition.y - startMousePosition.y) / height;
let lookFactor = 0.05;
camera.lookRight(x * lookFactor);
camera.lookUp(y * lookFactor);
}
// 根据相机到椭球表面的距离更改移动速度。
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);
}
});
})
const getFlagForKeyCode = (keyCode) => {
switch (keyCode) {
case 'W':
return 'moveForward';
case 'S':
return 'moveBackward';
case 'Q':
return 'moveUp';
case 'E':
return 'moveDown';
case 'D':
return 'moveRight';
case 'A':
return 'moveLeft';
default:
return undefined;
}
}
const flyToRight2 = async () => {
let tileset = await Cesium.Cesium3DTileset.fromUrl('/src/assets/tileset/12/tileset.json', {});
update3dtilesMaxtrix(tileset);
viewer.scene.primitives.add(tileset);
viewer.flyTo(tileset);
}
function update3dtilesMaxtrix(tileSet) {
//调整参数
let params = {
tx: 113.06265738392063, //模型中心X轴坐标(经度,单位:十进制度)
ty: 22.646603971034342, //模型中心Y轴坐标(纬度,单位:十进制度)
tz: 45, //模型中心Z轴坐标(高程,单位:米)
rx: 0, //X轴(经度)方向旋转角度(单位:度)
ry: 0, //Y轴(纬度)方向旋转角度(单位:度)
rz: 2, //Z轴(高程)方向旋转角度(单位:度)
scale: 1.35, //缩放比例
};
//旋转
const mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.rx));
const my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.ry));
const mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.rz));
const rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
const rotationY = Cesium.Matrix4.fromRotationTranslation(my);
const rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
//平移
const position = Cesium.Cartesian3.fromDegrees(
params.tx,
params.ty,
params.tz
);
const m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
//旋转、平移矩阵相乘
Cesium.Matrix4.multiply(m, rotationX, m);
Cesium.Matrix4.multiply(m, rotationY, m);
Cesium.Matrix4.multiply(m, rotationZ, m);
//比例缩放
const scale = Cesium.Matrix4.fromUniformScale(params.scale);
Cesium.Matrix4.multiply(m, scale, m);
// console.log("矩阵m:", m);
//赋值给tileset
tileSet._root.transform = m;
}
</script>
<style scoped>
#cesiumContainer {
overflow: hidden;
}
</style>
<style>
.el-breadcrumb__inner, .el-breadcrumb__separator {
color: #ffffff !important;
}
</style>