经纬志
首页 / Cesium / API 文档

ScreenSpaceEventHandler

先看结论

把鼠标、触摸、滚轮的原始事件翻译成 Cesium 的语义事件:单击、双击、拖拽、缩放。 所有交互功能都从它开始。

最后验证 2026-11-03 · CesiumJS 1.121 · 更新 2026-10-27 · 引用本文
new Cesium.ScreenSpaceEventHandler(element)

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)。