从‘Hello World’到3D地球:用Cesium.js和VSCode创建你的第一个Web三维项目
从‘Hello World’到3D地球:用Cesium.js和VSCode创建你的第一个Web三维项目
想象一下,你正在VSCode中编写一段简单的代码,几秒钟后,一个完整的3D地球在你的浏览器中旋转起来——这就是现代Web开发的魔力。Cesium.js让这种体验变得触手可及,就像当年我们第一次在屏幕上打印出"Hello World"一样简单而令人兴奋。
1. 为什么选择Cesium.js作为Web三维开发的起点
在众多WebGL框架中,Cesium.js以其独特的地球可视化能力脱颖而出。它不像Three.js那样需要从零开始构建场景,也不像Mapbox那样受限于二维地图思维。Cesium提供了开箱即用的3D地球体验,同时保持足够的灵活性。
核心优势对比 :
| 特性 | Cesium.js | Three.js | 传统地图库 |
|---|---|---|---|
| 3D地球支持 | 原生完整支持 | 需自行实现 | 仅2D/2.5D |
| 地理坐标系 | 内置WGS84 | 需额外扩展 | 完整支持 |
| 性能优化 | 专为地理数据设计 | 通用3D优化 | 针对平面优化 |
| 学习曲线 | 中等 | 陡峭 | 平缓 |
安装Cesium只需要下载一个构建好的文件夹,这比配置Webpack或处理npm依赖要简单得多。对于想快速看到3D效果的前端开发者来说,这种零配置体验至关重要。
2. 四步搭建你的第一个Cesium地球
让我们用最精简的方式启动项目。确保你已经准备好:
- 最新版VSCode
- 现代浏览器(推荐Chrome)
- 稳定的网络连接(首次加载需要获取地形数据)
2.1 项目结构准备
在VSCode中新建一个空文件夹,然后下载Cesium的Build版本。你只需要保留以下结构:
/your-project
/Cesium <-- 下载的Build文件夹
index.html
提示:直接从Cesium官网下载的Build包约80MB,包含所有必需资源和压缩后的代码。
2.2 基础HTML模板
创建一个包含以下代码的 index.html 文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>我的第一个Cesium地球</title>
<script src="./Cesium/Cesium.js"></script>
<style>
@import url(./Cesium/Widgets/widgets.css);
html, body, #cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
const viewer = new Cesium.Viewer('cesiumContainer', {
timeline: false, // 隐藏时间轴
animation: false, // 隐藏动画控件
baseLayerPicker: false // 禁用底图选择器
});
</script>
</body>
</html>
这段代码做了四件关键事情:
- 引入Cesium核心JS文件
- 加载Cesium的默认CSS样式
- 创建用于容纳地球的div容器
- 初始化Viewer实例
2.3 实时预览开发
在VSCode中,我强烈推荐使用Live Server扩展来运行这个页面:
- 安装Live Server扩展
- 右键点击index.html选择"Open with Live Server"
- 浏览器会自动打开并显示3D地球
注意:直接双击HTML文件在浏览器中打开会导致Cesium的资源加载失败,必须通过HTTP服务器访问。
3. 深入理解Cesium.Viewer
Viewer是Cesium的核心对象,理解它的配置选项能让你快速定制地球外观。
3.1 常用初始化参数
const viewer = new Cesium.Viewer('cesiumContainer', {
imageryProvider: new Cesium.IonImageryProvider({ assetId: 3845 }), // 使用Bing地图
terrainProvider: Cesium.createWorldTerrain(), // 使用Cesium世界地形
skyBox: false, // 禁用星空背景
sceneMode: Cesium.SceneMode.SCENE3D, // 强制3D模式
navigationHelpButton: false // 隐藏导航帮助按钮
});
参数解析表 :
| 参数名 | 类型 | 默认值 | 作用 |
|---|---|---|---|
| imageryProvider | Object | Ion默认影像 | 控制地图底图 |
| terrainProvider | Object | 无地形 | 启用3D地形 |
| skyBox | Boolean | true | 是否显示星空 |
| sceneMode | Number | SCENE3D | 初始视图模式 |
| navigationHelpButton | Boolean | true | 是否显示帮助按钮 |
3.2 动态调整视角
初始化后,你可以通过camera对象控制视角:
// 飞到指定经纬度和高度
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(116.4, 39.9, 1000000),
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-90),
roll: 0
}
});
// 或者直接设置homeButton的视角
viewer.homeButton.viewModel.command.beforeExecute.addEventListener(function(e) {
e.cancel = true;
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(103.8, 1.35, 5000000)
});
});
4. 从Demo到真实项目的最佳实践
当你想把这个小demo发展为正式项目时,需要考虑以下几个关键点:
4.1 项目结构优化
推荐的生产环境结构:
/src
/assets # 静态资源
/components # Vue/React组件
/libs # 第三方库
/Cesium # 构建后的Cesium
main.js # 主入口
package.json
4.2 现代前端框架集成
以Vue为例,在main.js中初始化Cesium:
import '../libs/Cesium/Widgets/widgets.css'
let viewer
export function initCesium(containerId) {
viewer = new Cesium.Viewer(containerId)
return viewer
}
export function getViewer() {
return viewer
}
然后在Vue组件中使用:
<template>
<div id="cesium-container"></div>
</template>
<script>
import { initCesium } from '../libs/cesium-init'
export default {
mounted() {
this.viewer = initCesium('cesium-container')
// 添加自定义逻辑...
},
beforeDestroy() {
// 清理资源
}
}
</script>
4.3 性能优化技巧
- 按需加载资源 :不要一次性加载所有地形和影像
- 使用Web Workers :处理密集计算
- 合理管理实体 :及时销毁不再需要的Primitive和Entity
- 利用Cesium Ion :托管你的3D模型和地理数据
// 示例:分块加载地形
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
url: 'https://assets.agi.com/stk-terrain/world',
requestWaterMask: true,
requestVertexNormals: true
});
5. 超越基础:创意扩展方向
掌握了基础之后,你可以尝试这些有趣的项目:
5.1 实时数据可视化
// 添加动态变化的点
const position = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883);
const redPoint = viewer.entities.add({
position: position,
point: {
pixelSize: 20,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2
}
});
// 让点动起来
setInterval(() => {
const offset = Math.random() * 0.01;
redPoint.position = Cesium.Cartesian3.fromDegrees(
-75.59777 + offset,
40.03883 + offset
);
}, 1000);
5.2 3D模型集成
// 加载glTF模型
const model = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.4, 39.9),
model: {
uri: './models/airplane.glb',
minimumPixelSize: 128,
maximumScale: 20000
}
});
// 模型动画控制
viewer.clock.onTick.addEventListener(function() {
model.orientation = Cesium.Quaternion.fromHeadingPitchRoll(
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(Date.now() / 100),
0,
0
)
);
});
5.3 高级着色器效果
// 自定义地表材质
viewer.entities.add({
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0),
material: new Cesium.StripeMaterialProperty({
evenColor: Cesium.Color.WHITE,
oddColor: Cesium.Color.BLUE,
repeat: 10
})
}
});
在实际项目中,我发现最实用的技巧是合理使用Cesium的事件系统。比如监听相机移动事件可以实现很多酷炫效果:
viewer.camera.moveStart.addEventListener(function() {
console.log('相机开始移动');
});
viewer.camera.moveEnd.addEventListener(function() {
console.log('相机停止移动', viewer.camera.position);
});
更多推荐


所有评论(0)