导语

相信很多做 WebGIS 开发的同学,都遇到过类似的需求:

公司做gis平台,需要实现模型的交互式编辑功能,在网上找开源项目,或费劲自己封装一套工具,结果发现要么工具简陋,bug满天飞,坐标错乱;要么交互体验不理想,不能满足要求。

在 Unity、Blender 或者是 Three.js 编辑器里,我们习惯了用Gizmo(变换控制器)来随心所欲地操作物体。但在 Cesium 的开源生态里,一直缺乏一个轻量、高性能且开箱即用的同类型工具。

平移模式
UE5引擎中的变换工具

今天,给大家推荐一款开源神器:cesium-transform-gizmo。它可能就是你一直在寻找的那块拼图。


🚀 什么是 cesium-transform-gizmo?

cesium-transform-gizmo 是一款专为 CesiumJS 打造的高性能、交互式模型变换控制器。

它完全使用 TypeScript 编写,为你的 Cesium 应用提供类似于 3D 建模软件的操作体验。无论是 Model (gltf/glb) 还是 3D Tileset,都可以通过它进行丝滑的平移、旋转和缩放。


✨ 核心亮点

1. 经典的交互体验,零学习成本

项目复刻了主流 3D 编辑器的操作逻辑:

**平移 (Translate)**:支持沿 X/Y/Z 轴锁定移动,也支持平面移动。

平移模式

**旋转 (Rotate)**:扇形旋转设计,带 90 度象限智能吸附功能,操作手感极佳。

旋转模式

**缩放 (Scale)**:支持轴向缩放和中心整体缩放。

缩放模式

2. 高性能设计

面对海量数据的 3D 场景,性能是第一要素。该控件基于几何体复用与高效的射线检测算法,确保即使在复杂的场景下,也能保持高帧率运行,不会成为性能瓶颈。

3. TypeScript / JavaScript 双剑合璧

无论你是 TypeScript 资深玩家,还是 JavaScript 入门新手,都能无缝接入。

  • 对于 TS 用户:提供完整的 .d.ts 类型定义,享受极致的代码提示和类型安全。
  • 对于 JS 用户:零配置,开箱即用。API 设计简单直观,无需任何额外学习成本,像使用原生 JS 库一样丝滑。

4. 高度可定制

不喜欢默认的颜色?觉得控制轴太小?都可以通过配置项自定义外观,完美融入你的 UI 风格。


💻 30秒快速上手

不用复杂的配置,只需要简单的几行代码即可集成。

第一步:安装依赖

1
2
npm install cesium-transform-gizmo
# 或者 yarn add cesium-transform-gizmo

第二步:初始化并绑定

(注:以下代码同时适用于 JavaScript 和 TypeScript 项目)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import * as Cesium from "cesium"
import Gizmo from "cesium-transform-gizmo"

// 1. 创建 Cesium Viewer
const viewer = new Cesium.Viewer("cesiumContainer")

// 2.加载模型
const model = await Cesium.Model.fromGltf({ url: "path/to/model.gltf" })
viewer.scene.primitives.add(model)

// 3.实例化gizmo并绑定要操作的模型
const gizmo = new Gizmo({
viewer,
object: model,
mode: "translate",
onUpdate: (state) => {
console.log("变换状态更新:", state)
},
})

第三步:实现点击拾取(进阶)

配合 Cesium 的事件系统,你也可以轻松实现“点击谁,编辑谁”的效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);

handler.setInputAction((event) => {
const picked = viewer.scene.pick(event.position);

// 如果点到了模型或3D Tiles,就让 Gizmo 附着上去
if (Cesium.defined(picked) &&
(picked.primitive instanceof Cesium.Model ||
picked.primitive instanceof Cesium.Cesium3DTileset)) {
gizmo.bindObject(picked.primitive);
} else {
// 点空白处隐藏 Gizmo
gizmo.bindObject(null);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

🎯 为什么需要你的 Star?

开源不易,cesium-transform-gizmo 致力于填补 Cesium 生态在交互编辑领域的空白。

如果你觉得这个工具对你的工作有帮助,或者看好它的未来发展,请移步 GitHub 为项目点亮一颗 Star ⭐️。你的支持是作者持续更新、修复 Bug 和添加新功能(如更复杂的坐标系支持、吸附功能等)的最大动力!

👇 项目传送门

https://github.com/cyanfish/cesium-transform-gizmo


📝 互动话题

你在 Cesium 开发中还遇到过哪些“坑”?或者希望这个 Gizmo 工具增加什么新功能?欢迎在评论区留言交流!