第四篇:一行代码创建地球?今天我们亲手封装第一个 SDK 模块!
📘 专栏说明
本专栏旨在手把手带你从零开始,基于开源三维地球引擎 Cesium 封装一套功能完善、可复用的 WebGIS 增强型 SDK。内容涵盖核心封装思路、关键代码实现、常用 GIS 功能抽象,以及基于该 SDK 构建的 UI 组件库开发。如果你更关注结果而非实现过程,也可直接使用已发布的成果:
🌟 GitHub仓库 📦 NPM 包 ✨ 公众号:经纬码客(欢迎关注)
💡 建议:即便你打算直接使用 SDK,也推荐订阅本专栏 -- 理解设计思路,才能更灵活地扩展属于你自己的专属 GIS 能力!
由于作者需兼顾全职工作,更新主要安排在晚间或节假日,无法保证高频发布,但会持续迭代,直至 SDK 达到实际项目落地标准。届时将完整开源所有源码,供学习与商用(遵循许可证协议)。
大家好,我是 Cesium 酱(也可以叫我“本猿”),一名在 WebGIS 领域摸爬滚打多年的前端开发者。前几期,我们搭好了项目骨架、配好了打包工具、生成了API文档框架。
但说实话——那都只是“工地”。
今天,我们终于要砌第一块砖了!
这块砖的名字叫:Arc3DLab.Viewer。
它的使命很简单:
✅ 默认关闭所有花里胡哨的按钮
✅ 自动适配中国视角
✅ 支持一键开启帧率、Mapbox 控制模式
✅ 隐藏 Cesium Ion 版权信息(合规前提下)
✅ 让你用一行代码就看到地球!
准备好了吗?打开你的编辑器(我用的 VS Code),我们开始敲代码!
🧱 第一步:明确需求 —— 我们想要什么样的 Viewer?
原生 Cesium.Viewer 虽然强大,但默认配置对国内开发者并不友好:
- 左下和右上角一堆按钮(动画、时间轴、帮助…)
- 初始视角是全球,但我们要聚焦中国
- 必须手动设置 Token
- 想关掉版权信息?得自己找 DOM
于是,我们决定:继承它,改造它,封装它!
✍️ 第二步:定义接口(TypeScript 的优势来了!)
在 src/types/index.ts 中,先定义我们的配置选项:
// src/types/index.ts
import type { Viewer as CesiumViewer } from "cesium"
/**
* Viewer 类的配置选项
* @interface Option
* @extends Cesium.Viewer.ConstructorOptions
*/
export interface Option extends CesiumViewer.ConstructorOptions {
/** Cesium Ion 默认访问令牌 */
defaultKey?: string
/** 是否显示帧率(FPS) */
fpsShow?: boolean
/** 是否启用 Mapbox 风格的交互控制(中键缩放 + 右键旋转) */
mapboxController?: boolean
}
💡 通过 extends Cesium.Viewer.ConstructorOptions,我们保留所有原生配置能力,只新增我们需要的字段。
🛠️ 第三步:创建核心类 —— Viewer.ts
新建文件 src/core/Viewer.ts,开始写我们的增强类:
// src/core/Viewer.ts
import * as Cesium from "cesium"
import { Option } from "../types"
import { BaseLayer } from "./BaseLayer" // 后续会讲,这里先假设有一个默认底图
// 设置默认相机视角为中国区域
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = new Cesium.Rectangle(
Cesium.Math.toRadians(70), // 西边界(经度)
Cesium.Math.toRadians(-15), // 南边界(纬度)
Cesium.Math.toRadians(140), // 东边界
Cesium.Math.toRadians(80) // 北边界
)
export class Viewer extends Cesium.Viewer {
constructor(container: Element | string, public options?: Option) {
super(container, {
// —————— 默认关闭所有 UI 控件 ——————
animation: false,
fullscreenButton: false,
geocoder: false,
homeButton: false,
infoBox: false,
sceneModePicker: false,
timeline: false,
baseLayerPicker: false,
navigationHelpButton: false,
vrButton: false,
selectionIndicator: false,
// —————— 性能与渲染优化 ——————
sceneMode: Cesium.SceneMode.SCENE3D,
scene3DOnly: true,
shouldAnimate: true,
orderIndependentTranslucency: true,
shadows: false,
// —————— WebGL 上下文优化 ——————
contextOptions: {
webgl: {
antialias: true,
alpha: true,
powerPreference: "high-performance",
failIfMajorPerformanceCaveat: true,
preserveDrawingBuffer: false,
},
requestWebgl1: false,
},
// —————— 使用自定义默认底图(支持离线) ——————
baseLayer: BaseLayer.DefaultSingleImg,
// —————— 合并用户传入的配置 ——————
...options,
})
// 初始化基础配置
this.initBaseConfig()
}
private initBaseConfig() {
// 1. 设置 Cesium Ion Token(优先使用用户传入的)
Cesium.Ion.defaultAccessToken = this.options?.defaultKey || "你的默认Token"
// 2. 开启地形深度检测(地下物体不可见)
this.scene.globe.depthTestAgainstTerrain = true
// 3. 时间流速设为正常
this.clock.multiplier = 1
// 4. 禁止相机穿地(碰撞检测)
this.scene.screenSpaceCameraController.enableCollisionDetection = true
// 5. 隐藏 Cesium 版权信息
;(this.cesiumWidget.creditContainer as any).style.display = "none"
// 6. 高分辨率设备适配
this.resolutionScale = window.devicePixelRatio
// 7. Mapbox 交互模式(中键缩放 + 右键旋转)
if (this.options?.mapboxController) {
this.scene.screenSpaceCameraController.zoomEventTypes = [
Cesium.CameraEventType.WHEEL,
Cesium.CameraEventType.MIDDLE_DRAG,
Cesium.CameraEventType.PINCH,
]
this.scene.screenSpaceCameraController.tiltEventTypes = [
Cesium.CameraEventType.RIGHT_DRAG,
Cesium.CameraEventType.PINCH,
{ eventType: Cesium.CameraEventType.RIGHT_DRAG, modifier: Cesium.KeyboardEventModifier.CTRL },
{ eventType: Cesium.CameraEventType.MIDDLE_DRAG, modifier: Cesium.KeyboardEventModifier.CTRL },
]
}
// 8. 是否显示帧率
this.scene.debugShowFramesPerSecond = this.options?.fpsShow || false
}
}
⚠️ 注意:隐藏版权信息需确保你有合法使用权!本 SDK 仅作技术演示。
⭕这里面细心的小伙伴肯定发现了 BaseLayer.DefaultSingleImg 这个对象,没错这也是我们自定义的底图选项,下一期我们会仔细介绍!

🔌 第四步:导出模块,让别人能用
修改 src/index.ts:
// src/index.ts
export { Viewer } from "./core/Viewer"
// 后续会在这里导出更多模块
然后运行:
npm run build
如果成功,你会在 dist/ 目录看到打包后的文件!

在 demo-html/index.html 中添加:
<div id="map" style="width:100%;height:100vh;"></div>
<script type="module">
import { Viewer } from '../dist/arc3dlab.esm.js'
// 一行代码!创建地球
const viewer = new Viewer('map', {
fpsShow: true,
mapboxController: true,
defaultKey: '你的 Cesium Ion Token'
})
</script>
- - 刷新页面 - -
🎉 一个干净、聚焦中国、无干扰按钮的三维地球出现了!
🤝 这只是开始!
这个 Viewer 类目前还很简单,但它是我们 SDK 的第一块基石。
后续我们可以自定义:
- 添加
destroy()方法做资源清理 - 封装
flyToChina()快捷方法 - 支持自动加载离线底图(关于离线这块,确实不太友好,没办法浏览器安全通病)
而这一切,由你我共同完成。
如果你有想法:
- “能不能加个自动 Token 管理?”
- “我希望默认开启抗锯齿!”
欢迎来 GitHub 提 Issue!
你的每一个建议,都可能成为下一行代码。
🌟 项目开源,欢迎Star✨!
GitHub:https://github.com/jianlei-wang/Arc3DLab_SDK
NPM:https://www.npmjs.com/package/arc3dlab
Cesium 酱の百宝箱 · 第 4 篇
代码不多,但每行都有意义。
2026 年伊始,与你共写第一行可用之码。
浙公网安备 33010602011771号