ScreenSpaceEventHandler
把鼠标、触摸、滚轮的原始事件翻译成 Cesium 的语义事件:单击、双击、拖拽、缩放。 所有交互功能都从它开始。
element 通常传 viewer.scene.canvas。
传整个容器也能用,但画布上有叠加的 DOM 控件时事件可能被它们吃掉。
方法
| 方法 | 说明 |
|---|---|
setInputAction(action, type, modifier) | 绑定回调。同一类型重复绑定会覆盖前一个 |
removeInputAction(type, modifier) | 解绑。不传 modifier 只会解绑无修饰键的绑定 |
getInputAction(type, modifier) | 取出已绑定的回调 |
hasInputAction(type, modifier) | 判断是否绑过 |
destroy() | 销毁所有绑定。单页应用切换页面时必须调用 |
isDestroyed() | 是否已销毁 |
事件类型
| 常量 | 触发条件 | movement 字段 |
|---|---|---|
LEFT_CLICK | 左键单击 | position |
LEFT_DOUBLE_CLICK | 左键双击 | position |
LEFT_DOWN / LEFT_UP | 按下、抬起 | position |
RIGHT_CLICK | 右键单击 | position |
MIDDLE_CLICK | 中键单击 | position |
MOUSE_MOVE | 指针移动 | startPosition、endPosition |
WHEEL | 滚轮 | delta,正负表示方向 |
PINCH_START / PINCH_MOVE / PINCH_END | 双指手势 | distance |
修饰键
同一个鼠标事件可以按修饰键分成多组,互不覆盖:
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (movement) {
console.log('左键', movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
handler.setInputAction(function (movement) {
console.log('Shift + 左键', movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK, Cesium.KeyboardEventModifier.SHIFT);
拾取坐标的完整写法
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (click) {
// 有地形时优先取地形交点
var ray = viewer.camera.getPickRay(click.position);
var cartesian = viewer.scene.globe.pick(ray, viewer.scene);
// 没有地形时退化为与椭球面求交
if (!Cesium.defined(cartesian)) {
cartesian = viewer.camera.pickEllipsoid(
click.position, viewer.scene.globe.ellipsoid
);
}
if (!Cesium.defined(cartesian)) return;
var c = Cesium.Cartographic.fromCartesian(cartesian);
console.log(
Cesium.Math.toDegrees(c.longitude).toFixed(6),
Cesium.Math.toDegrees(c.latitude).toFixed(6),
c.height.toFixed(1)
);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
两种拾取的区别。globe.pick 打在地形上,返回真实地表点;
camera.pickEllipsoid 只和光滑椭球求交,拿到的是椭球面上的点。
有地形的场景两者高度能差几百米。
与默认交互冲突
Viewer 内部已经给双击绑定了「缩放定位」、给左键绑定了「选中要素」。 自己加双击逻辑时,两者会同时触发,表现为画面一边响应自己的代码一边拉近:
// 先移除默认的双击行为
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
);
// 再绑定自己的
handler.setInputAction(function (click) { /* ... */ },
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
需要保留选中但去掉 infoBox 弹窗时,可以直接把 Viewer 的
infoBox: false 关掉,而不是去改事件绑定。
销毁
每创建一个 handler 都会在 canvas 上注册监听。路由切换时只清空场景、 不销毁 handler,旧的回调仍然会执行,并且持有已经销毁的 viewer 引用, 控制台会出现访问已销毁对象的报错。离开页面时统一调用:
handler.destroy(); // 解绑事件
viewer.destroy(); // 释放 WebGL 资源
经纬志(2026)。《ScreenSpaceEventHandler》。https://www.jingweizhi.com/cesium/api/screen-space-event-handler.html(访问日期 2026-11-03)。