Skip to content

MouseEvents 鼠标事件管理器

MouseEvents 封装了 Cesium 的 ScreenSpaceEventHandler,提供鼠标移动、左键单击、右键单击事件注册与注销的统一接口,以及拾取信息的便捷解析。


构造函数

ts
constructor(viewer: Cesium.Viewer, options?: MouseEventsOptions)
参数类型默认值描述
viewerCesium.ViewerCesium Viewer 实例,必填
optionsMouseEventsOptions{}可选配置项

MouseEventsOptions

属性类型默认值描述
openOnCreatebooleantrue是否在创建后立即开启事件监听
enablePickbooleantrue是否在事件回调中附加场景拾取结果

事件回调参数

所有事件处理函数接收统一的 CartographicInfo 对象:

ts
interface CartographicInfo {
  /** 地心笛卡尔坐标 */
  cartesian: Cesium.Cartesian3;
  /** 地理坐标(度),包含经度、纬度、高度 */
  cartographic: {
    lon: number;   // 经度(度)
    lat: number;   // 纬度(度)
    height: number; // 高度(米,相对椭球体)
  };
  /** 屏幕像素坐标 */
  windowPos: {
    x: number;
    y: number;
  };
  /** 场景拾取结果(enablePick 为 true 时有效) */
  pickObj?: {
    entity?: Cesium.Entity;       // 拾取到的 Entity
    primitive?: any;              // 拾取到的 Primitive
    id?: any;                     // 拾取对象 ID
    feature?: Cesium.Cesium3DTileFeature; // 3D Tiles 要素
  };
}

方法

onMouseMove(handler: (info: CartographicInfo) => void): void

注册鼠标移动事件。鼠标在场景中移动时持续触发。

ts
mouseEvents.onMouseMove((info) => {
  console.log('光标位置:', info.cartographic.lon, info.cartographic.lat);
});

offMouseMove(handler: (info: CartographicInfo) => void): void

移除已注册的鼠标移动事件处理器。

onLeftClick(handler: (info: CartographicInfo) => void): void

注册左键单击事件。

offLeftClick(handler: (info: CartographicInfo) => void): void

移除已注册的左键单击事件处理器。

onRightClick(handler: (info: CartographicInfo) => void): void

注册右键单击事件。

offRightClick(handler: (info: CartographicInfo) => void): void

移除已注册的右键单击事件处理器。

close(): void

暂停所有事件监听。不销毁实例,可调用 open() 恢复。

open(): void

恢复事件监听(仅在调用 close() 后使用)。

destroy(): void

销毁实例,移除所有事件监听和内部引用。


属性

名称类型描述
isShutdownboolean实例是否已销毁(只读)

代码示例

点击拾取 Entity

ts
import { MouseEvents } from '@air-stack/gis-cesium';

const mouse = new MouseEvents(viewer);

mouse.onLeftClick((info) => {
  const entity = info.pickObj?.entity;

  if (entity) {
    const name = entity.name || entity.id;
    console.log(`拾取到实体:${name}`);

    // 高亮拾取对象
    if (entity.polygon) {
      entity.polygon.material = Cesium.Color.RED.withAlpha(0.6);
    }
  } else {
    console.log('未拾取到实体');
  }
});

鼠标移动坐标显示

ts
const coordDisplay = document.getElementById('coord-display');

mouse.onMouseMove((info) => {
  if (!coordDisplay) return;

  const { lon, lat, height } = info.cartographic;

  coordDisplay.innerHTML = `
    经度:${lon.toFixed(6)}°<br/>
    纬度:${lat.toFixed(6)}°<br/>
    高度:${height.toFixed(2)} m<br/>
    屏幕:(${info.windowPos.x}, ${info.windowPos.y})
  `;
});

右键上下文菜单

ts
const contextMenu = document.getElementById('context-menu');

mouse.onRightClick((info) => {
  if (!contextMenu) return;

  // 定位菜单到鼠标位置
  contextMenu.style.left = `${info.windowPos.x}px`;
  contextMenu.style.top = `${info.windowPos.y}px`;
  contextMenu.style.display = 'block';

  // 显示菜单项
  contextMenu.innerHTML = `
    <div class="menu-item" onclick="doAction('zoom', ${info.cartographic.lon}, ${info.cartographic.lat})">
      缩放到此处
    </div>
    <div class="menu-item" onclick="doAction('mark', ${info.cartographic.lon}, ${info.cartographic.lat})">
      添加标记
    </div>
    <div class="menu-item" onclick="doAction('measure', ${info.cartographic.lon}, ${info.cartographic.lat})">
      从此处测量
    </div>
  `;

  // 点击其他地方关闭菜单
  document.addEventListener('click', () => {
    contextMenu.style.display = 'none';
  }, { once: true });
});

暂停/恢复事件

ts
// 暂停鼠标事件(例如开启绘制工具时)
mouse.close();

// 恢复鼠标事件
mouse.open();

3D Tiles 要素拾取

ts
mouse.onLeftClick((info) => {
  const feature = info.pickObj?.feature;

  if (feature instanceof Cesium.Cesium3DTileFeature) {
    const buildingName = feature.getProperty('name');
    const height = feature.getProperty('height');

    console.log(`建筑:${buildingName},高度:${height} m`);

    // 高亮选中建筑
    feature.color = Cesium.Color.YELLOW.withAlpha(0.5);
  }
});

组合使用 — 左键标记 + 移动显示坐标

ts
const mouse = new MouseEvents(viewer, {
  enablePick: false, // 不需要拾取,提升性能
});

const markers: Cesium.Entity[] = [];

mouse.onMouseMove((info) => {
  document.getElementById('status-bar')!.textContent =
    `${info.cartographic.lon.toFixed(4)}, ${info.cartographic.lat.toFixed(4)}`;
});

mouse.onLeftClick((info) => {
  const marker = viewer.entities.add({
    position: info.cartesian,
    point: {
      pixelSize: 10,
      color: Cesium.Color.RED,
    },
    label: {
      text: `标记 ${markers.length + 1}`,
      font: '14px sans-serif',
      pixelOffset: new Cesium.Cartesian2(0, -16),
    },
  });

  markers.push(marker);
});

console.log('鼠标事件已就绪,共标记了', markers.length, '个点');

注意事项

  1. close()destroy() 的区别close() 仅暂停事件,调用 open() 可以恢复;destroy() 彻底销毁实例,不可恢复。
  2. isShutdowntrue 时调用任何事件注册或 open() 方法均不会生效。
  3. 性能提示onMouseMove 高频触发(约每帧),建议回调中避免复杂计算或 DOM 操作。
  4. enablePick: false 可跳过拾取计算,在仅需坐标场景下可显著提升移动事件性能。
  5. 如果不传递 options,默认开启事件监听和拾取功能。