前言:在前两篇文章中,我们已完成Vue+Vite+TS+Cesium的环境搭建,并创建了基础三维场景,同时详细讲解了Viewer的option配置参数。在Cesium三维场景中,Camera(相机)是控制视角的核心,相当于我们观察场景的“眼睛”——所有场景可视化效果都依赖Camera的视角呈现。本文作为系列第三篇,将聚焦Camera核心内容:先讲解Camera的基本概念与核心属性,再通过具体代码示例演示几种常用的视角设置方法,最后说明不同设置方法的效果差异,帮助大家灵活控制场景视角。
一、Camera基本概念
在Cesium中,Camera是一个虚拟的“相机”对象,用于定义观察三维场景的视角和姿态。我们在场景中看到的所有内容,都是Camera“拍摄”到的画面。理解Camera的核心属性,是灵活控制视角的基础。
1.1 核心属性(视角控制的关键)
Camera的核心属性决定了其位置和观察姿态,主要包括以下4个:
-
position(位置):Camera在三维空间中的具体坐标,默认使用Cesium笛卡尔坐标系(Cartesian3),也可通过经纬度+高度转换得到。这是控制“相机在哪里”的关键。
-
heading(航向角):相机在水平面上的旋转角度,以正北方向为0度,顺时针旋转为正方向(单位:弧度)。控制“相机水平朝向哪个方向”(如朝东、朝南)。
-
pitch(俯仰角):相机在垂直方向的旋转角度,以水平视角为0度,向下旋转为负,向上旋转为正(单位:弧度)。控制“相机是俯视、平视还是仰视”(如俯视地球、平视地平线)。
-
roll(翻滚角):相机绕自身视线方向的旋转角度,0度为水平状态,顺时针为正,逆时针为负(单位:弧度)。一般用于特殊场景(如飞行模拟),常规三维场景中基本设为0。
补充说明:Cesium中角度与弧度的转换需使用 Cesium.Math.toRadians(角度值) 方法,因为Camera的角度属性仅支持弧度单位。例如:将30度转换为弧度 →Cesium.Math.toRadians(30)。
1.2 Camera与Viewer的关系
在我们前两篇创建的场景中,Camera是Viewer实例的一个属性,可通过 viewer.camera 直接获取和操作,无需单独创建。例如:
// 初始化Viewer后,直接获取Camera实例
const viewer = new Cesium.Viewer(container, options);
const camera = viewer.camera; // 获取Camera对象
二、Camera常用设置方法(附代码示例)
基于前两篇搭建的Vue+Vite+TS环境,以下所有代码均在CesiumBasicViewer.vue组件中扩展实现。核心设置方法分为4种:setView(立即定位)、flyTo(平滑飞行定位)、lookAt(指向目标点)、手动修改属性,分别适用于不同场景需求。
2.1 方法1:setView(立即定位,无动画)
setView 方法用于将相机“瞬间”定位到目标视角,无平滑过渡动画,适用于需要快速切换视角的场景(如初始化默认视角、快速跳转场景)。
核心参数
-
destination:必选,目标位置,支持两种格式:-
Cartesian3:经纬度+高度转换后的笛卡尔坐标(常用,定位具体点)
-
Rectangle:矩形范围(定位一片区域,相机会自动调整高度以完整显示区域)
-
-
orientation:可选,相机姿态(heading+pitch+roll),不设置则使用默认姿态。
代码示例
<script setup lang="ts">
import { onMounted, ref, onUnmounted } from 'vue'
import * as Cesium from 'cesium'
const viewerRef = ref<HTMLDivElement | null>(null)
let viewer: Cesium.Viewer | null = null
onMounted(() => {
if (!viewerRef.value) return
// 初始化Viewer(使用前一篇推荐的option参数)
viewer = new Cesium.Viewer(viewerRef.value, {
homeButton: true,
fullscreenButton: true,
baseLayerPicker: true,
timeline: false,
animation: false,
geocoder: false,
navigationHelpButton: false,
sceneModePicker: false,
scene3DOnly: true,
requestRenderMode: true,
maximumRenderTimeChange: 0.01
})
// setView方法:立即定位到北京(无动画)
viewer.camera.setView({
// 目标位置:北京(经度116.403874,纬度39.914885,高度10000米)
destination: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 10000),
// 相机姿态:航向角0(正北),俯仰角-30°(俯视),翻滚角0
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-30),
roll: Cesium.Math.toRadians(0)
}
})
// 扩展:定位到矩形区域(如中国东部,自动调整高度)
// viewer.camera.setView({
// destination: Cesium.Rectangle.fromDegrees(110, 20, 120, 35), // 西经、南纬、东经、北纬
// orientation: {
// heading: Cesium.Math.toRadians(0),
// pitch: Cesium.Math.toRadians(-45)
// }
// })
})
onUnmounted(() => {
if (viewer) {
viewer.destroy()
viewer = null
}
})
</script>
<template>
<div class="cesium-container" ref="viewerRef"></div>
</template>
<style scoped>
.cesium-container {
width: 100vw;
height: 100vh;
overflow: hidden;
}
</style>
效果说明
启动项目后,相机将直接显示北京区域10000米高度、俯视30度的视角,无任何过渡动画,视角切换瞬间完成。
2.2 方法2:flyTo(平滑飞行定位,推荐)
flyTo 方法是最常用的视角设置方式,相机将以“平滑飞行”的动画形式到达目标视角,视觉体验更友好(如初始化场景、点击定位等交互场景)。其参数与setView 基本一致,额外增加了动画相关配置。
核心参数(新增动画相关)
-
duration:可选,飞行动画持续时间(单位:秒),默认根据距离自动计算。 -
maximumHeight:可选,飞行过程中的最大高度(单位:米),避免飞行过程中视角过低或过高。 -
其他参数(destination、orientation)与 setView 一致。
代码示例
<script setup lang="ts">
import { onMounted, ref, onUnmounted } from 'vue'
import * as Cesium from 'cesium'
const viewerRef = ref<HTMLDivElement | null>(null)
let viewer: Cesium.Viewer | null = null
onMounted(() => {
if (!viewerRef.value) return
viewer = new Cesium.Viewer(viewerRef.value, {
// 沿用推荐的option参数
homeButton: true,
fullscreenButton: true,
baseLayerPicker: true,
timeline: false,
animation: false,
geocoder: false,
navigationHelpButton: false,
sceneModePicker: false,
scene3DOnly: true,
requestRenderMode: true,
maximumRenderTimeChange: 0.01
})
// flyTo方法:平滑飞行到上海(3秒完成)
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(121.4737, 31.2304, 8000), // 上海经纬度+8000米高度
orientation: {
heading: Cesium.Math.toRadians(10), // 航向角10°(轻微朝东)
pitch: Cesium.Math.toRadians(-25), // 俯仰角-25°(俯视)
roll: 0
},
duration: 3, // 飞行时间3秒
maximumHeight: 12000 // 飞行过程中最高12000米
})
})
onUnmounted(() => {
if (viewer) {
viewer.destroy()
viewer = null
}
})
</script>
效果说明
启动项目后,相机会从默认全球视角开始,以平滑的动画飞行3秒,最终到达上海8000米高度、俯视25度的视角,飞行过程中高度不超过12000米,视觉体验流畅自然。
2.3 方法3:lookAt(指向目标点,固定观察)
lookAt 方法用于将相机的视线“固定指向”某个目标点,同时设置相机的位置和姿态。适用于需要持续观察某个固定目标的场景(如观察某个建筑、标记点)。
核心参数
-
target:必选,目标点的笛卡尔坐标(被观察的点)。 -
offset:必选,相机相对于目标点的偏移量(包含位置偏移和姿态偏移)。
代码示例
<script setup lang="ts">
import { onMounted, ref, onUnmounted } from 'vue'
import * as Cesium from 'cesium'
const viewerRef = ref<HTMLDivElement | null>(null)
let viewer: Cesium.Viewer | null = null
onMounted(() => {
if (!viewerRef.value) return
viewer = new Cesium.Viewer(viewerRef.value, {
// 沿用推荐的option参数
homeButton: true,
fullscreenButton: true,
baseLayerPicker: true,
timeline: false,
animation: false,
geocoder: false,
navigationHelpButton: false,
sceneModePicker: false,
scene3DOnly: true,
requestRenderMode: true,
maximumRenderTimeChange: 0.01
})
// 1. 定义目标点:天安门(经纬度转换为笛卡尔坐标)
const target = Cesium.Cartesian3.fromDegrees(116.397470, 39.908692, 50);
// 2. lookAt方法:相机固定指向天安门,位置在目标点东北方向5000米、高度2000米
viewer.camera.lookAt(
target,
new Cesium.Cartesian3(5000, -5000, 2000) // 偏移量:x正方向(东)5000,y负方向(北)5000,z(高度)2000
);
// 3. 可选:调整相机姿态(确保视线指向目标)
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
})
onUnmounted(() => {
if (viewer) {
viewer.destroy()
viewer = null
}
})
</script>
效果说明
相机将固定指向天安门位置,无论如何拖拽旋转视角,视线始终聚焦于天安门;相机位置固定在天安门东北方向5000米、高度2000米处,适合持续观察目标点。
2.4 方法4:手动修改Camera属性(灵活控制)
除了上述封装好的方法,也可直接修改Camera的 position、heading、pitch 等属性,实现更灵活的视角控制(如自定义动画、实时调整视角)。需注意:直接修改属性后,需调用 camera.updateCamera() 使修改生效。
代码示例
<script setup lang="ts">
import { onMounted, ref, onUnmounted } from 'vue'
import * as Cesium from 'cesium'
const viewerRef = ref<HTMLDivElement | null>(null)
let viewer: Cesium.Viewer | null = null
onMounted(() => {
if (!viewerRef.value) return
viewer = new Cesium.Viewer(viewerRef.value, {
// 沿用推荐的option参数
homeButton: true,
fullscreenButton: true,
baseLayerPicker: true,
timeline: false,
animation: false,
geocoder: false,
navigationHelpButton: false,
sceneModePicker: false,
scene3DOnly: true,
requestRenderMode: true,
maximumRenderTimeChange: 0.01
})
const camera = viewer.camera;
// 1. 手动设置相机位置(广州经纬度+12000米高度)
camera.position = Cesium.Cartesian3.fromDegrees(113.2644, 23.1291, 12000);
// 2. 手动设置相机姿态
camera.heading = Cesium.Math.toRadians(0); // 正北
camera.pitch = Cesium.Math.toRadians(-35); // 俯视35度
camera.roll = 0;
// 3. 使修改生效
camera.updateCamera();
})
onUnmounted(() => {
if (viewer) {
viewer.destroy()
viewer = null
}
})
</script>
效果说明
与 setView 类似,视角瞬间切换到广州12000米高度、俯视35度的视角,适合需要精细控制视角属性的场景。
三、常用设置方法效果对比
为了方便大家根据场景选择合适的方法,整理了4种方法的核心差异和适用场景:
| 设置方法 | 核心特点 | 适用场景 | 视觉效果 |
|---|---|---|---|
| setView | 无动画,瞬间定位,参数简单 | 快速切换视角、初始化简单场景 | 视角突变,无过渡 |
| flyTo | 平滑动画,支持自定义飞行时间 | 初始化场景、点击定位、用户交互 | 飞行过渡自然,体验友好(推荐) |
| lookAt | 固定视线指向目标点 | 持续观察某个目标(如建筑、标记点) | 视线聚焦目标,视角旋转时目标不变 |
| 手动修改属性 | 灵活控制单个属性,需手动生效 | 自定义动画、实时微调视角 | 可实现复杂视角变化,需自行控制过渡 |
四、总结
本文基于前两篇的开发环境,详细讲解了Cesium Camera的核心概念和4种常用设置方法:
-
Camera的核心属性(position、heading、pitch、roll)决定了视角的位置和姿态,需注意角度与弧度的转换。
-
setView适合快速定位,flyTo适合友好的交互定位(推荐),lookAt适合固定观察目标,手动修改属性适合灵活自定义视角。
-
所有方法均基于现有Vue+Vite+TS环境实现,代码可直接复用,只需根据业务需求调整目标位置和姿态参数。

3024

被折叠的 条评论
为什么被折叠?



