效果图
上一章我们成功搭建了 Cesium 开发环境并显示了 3D 地球。本章将学习如何控制地球视图,包括相机操作、视角切换和交互控制等核心功能。
1 相机(Camera)基础
Cesium 中的相机相当于用户的 "眼睛",控制着我们看到的地球区域和角度。相机有几个关键参数:
- 位置(position):相机在 3D 空间中的坐标
- 方向(orientation):包含 heading(方位角)、pitch(俯仰角)、roll(翻滚角)
- 视锥体(frustum):控制视野范围和透视效果
2 常用相机操作方法
下面通过示例展示常用的相机控制方法:
<template>
<div class="cesium-container">
<div id="cesiumContainer" class="cesium-viewer"></div>
<!-- 相机控制按钮 -->
<div class="control-panel">
<button @click="flyToBeijing">飞往北京</button>
<button @click="zoomIn">放大</button>
<button @click="zoomOut">缩小</button>
<button @click="rotateLeft">向左旋转</button>
<button @click="toggleMode">切换视角模式</button>
<button @click="resetView">重置视图</button>
</div>
</div>
</template>
<script>
// import Cesium from 'cesium/Cesium';
// import 'cesium/Widgets/widgets.css';
export default {
name: 'CesiumCamera',
data() {
return {
viewer: null,
is3DMode: true, // 当前视角模式
};
},
mounted() {
// 设置 Token
Cesium.Ion.defaultAccessToken =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMGFkODljYy03NDI5LTQ0NDgtYmNmMC1lMjFlMTQ3NmExNjkiLCJpZCI6MzM2MDM0LCJpYXQiOjE3NTYzNDU1NTd9.AkhZoeBAIIPRhFnFDkTRpqERvJYxVpvAG67FJPlaOFI';
// 初始化视图
this.viewer = new Cesium.Viewer('cesiumContainer', {
imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer',
}),
// terrainProvider: Cesium.Terrain.fromWorldTerrain(),
// 保留默认控件,便于对比
homeButton: true,
sceneModePicker: true,
});
// 初始定位到中国
this.viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(105, 35, 5000000),
});
},
methods: {
// 飞抵北京(带动画)
flyToBeijing() {
this.viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(116.404, 39.915, 10000), // 经度、纬度、高度
duration: 3, // 飞行时间(秒)
orientation: {
heading: Cesium.Math.toRadians(0), // 方向角(0表示向北)
pitch: Cesium.Math.toRadians(-60), // 俯仰角(-90表示正视下方)
roll: 0, // 翻滚角
},
});
},
// 放大
zoomIn() {
// 获取当前相机位置
const currentPosition = this.viewer.camera.position;
// 计算新位置(向地球方向移动)
const newPosition = Cesium.Cartesian3.multiplyByScalar(
currentPosition,
0.5, // 距离减半(放大)
new Cesium.Cartesian3()
);
// 移动相机(无动画)
this.viewer.camera.setView({
destination: newPosition,
});
},
// 缩小
zoomOut() {
const currentPosition = this.viewer.camera.position;
const newPosition = Cesium.Cartesian3.multiplyByScalar(
currentPosition,
2.0, // 距离加倍(缩小)
new Cesium.Cartesian3()
);
this.viewer.camera.setView({
destination: newPosition,
});
},
// 向左旋转
rotateLeft() {
this.viewer.camera.rotate(
Cesium.Cartesian3.UNIT_Y,
Cesium.Math.toRadians(10)
);
},
// 切换视角模式(3D/2D/哥伦布视图)
toggleMode() {
this.is3DMode = !this.is3DMode;
if (this.is3DMode) {
this.viewer.scene.mode = Cesium.SceneMode.SCENE3D;
} else {
this.viewer.scene.mode = Cesium.SceneMode.SCENE2D;
// 切换到2D后调整视角
this.viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(105, 35, 5000000),
});
}
},
// 重置视图
resetView() {
this.viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(105, 35, 5000000),
});
this.viewer.scene.mode = Cesium.SceneMode.SCENE3D;
this.is3DMode = true;
},
},
beforeDestroy() {
if (this.viewer) {
this.viewer.destroy();
}
},
};
</script>
<style scoped>
.cesium-container {
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
position: relative;
}
.cesium-viewer {
width: 100%;
height: 100%;
}
/* 控制按钮样式 */
.control-panel {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 10px;
z-index: 10;
padding: 10px;
background: rgba(255, 255, 255, 0.8);
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
button {
padding: 8px 12px;
background: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
button:hover {
background: #0056b3;
}
</style>
Cesium 相机控制示例
3 代码解析
相机定位方法:
flyTo()
:带动画的飞行定位,适合用户交互setView()
:直接跳转定位,无动画,适合初始化
坐标转换:
Cesium.Cartesian3.fromDegrees(longitude, latitude, height)
:将经纬度坐标转换为 Cesium 内部使用的笛卡尔坐标
视角模式:
SCENE3D
:3D 模式,可看到地形起伏SCENE2D
:2D 模式,类似传统平面地图COLUMBUS_VIEW
:哥伦布视图,介于 2D 和 3D 之间的透视模式
相机方向参数:
heading
:方位角,0 表示向北,增加为顺时针旋转pitch
:俯仰角,0 表示水平,负值表示向下看,正值表示向上看roll
:翻滚角,0 表示水平,正值表示向右翻滚
4 交互控制
Cesium 提供了默认的鼠标交互:
- 左键拖动:旋转地球
- 右键拖动:缩放
- 中键拖动:平移
- 滚轮:缩放
- 双击:放大到点击位置
如果需要自定义交互,可以通过 ScreenSpaceEventHandler
实现:
// 示例:禁用默认的左键拖动旋转
this.viewer.scene.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_DRAG
);
// 添加自定义左键点击事件
this.viewer.scene.screenSpaceEventHandler.setInputAction(
(event) => {
// 获取点击位置的经纬度
const position = this.viewer.scene.pickPosition(event.position);
if (position) {
const cartographic = Cesium.Cartographic.fromCartesian(position);
const longitude = Cesium.Math.toDegrees(cartographic.longitude);
const latitude = Cesium.Math.toDegrees(cartographic.latitude);
console.log(`点击位置: 经度 ${longitude.toFixed(2)}, 纬度 ${latitude.toFixed(2)}`);
}
},
Cesium.ScreenSpaceEventType.LEFT_CLICK
);
小结
本文讲解了:
- Cesium 相机的基本概念和参数
- 常用的相机控制方法(定位、缩放、旋转)
- 视角模式切换(3D/2D / 哥伦布视图)
- 基础交互控制和自定义事件