cesium-相机修改默认的操作方式

基础框架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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值