屏幕空间监听事件
1 前言
本文主要解析了ScreenSpaceEventHandler类,并实现了屏幕空间事件的监听。部分内容参考了文章: cesium-事件监听(获取点击位置的经纬度和高度)。添加了部分ts的代码,和对回调函数参数的解析,这些参数一般是屏幕的坐标,通过坐标转换后可以向cesium球体上增加元素,可以实现点击添加点、移动物体等复杂的操作。
cesium探索系列目录
:传送门
2 ScreenSpaceEventHandler类解析
2.1 入参
ScreenSpaceEventHandler类只有一个入参,是创建viewer的canvas的载体。可以通过viewer.scene.canvas获取。
constructor(element?: HTMLCanvasElement)
ScreenSpaceEventHandler实例的创建如下:
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
2.2 方法
destroy()
移除此对象持有的侦听器。
handler.destroy()
一旦一个对象被销毁,则只能调用 isDestroyed方法,调用其他方法会导致DeveloperError异常。
isDestroyed()
如果此对象被销毁,则返回 true;否则为false。
返回:boolean。
getInputAction(type, modifier)
返回要在输入事件上执行的函数。
姓名 | 类型 | 描述 |
---|---|---|
type | number | 输入事件的ScreenSpaceEventType |
modifier | number | type发生事件时持有的keyboardEventModifier键 |
返回:要在输入事件上执行的函数。
removeInputAction(type, modifier)
删除要在输入事件上执行的函数。
姓名 | 类型 | 描述 |
---|---|---|
type | number | 输入事件的ScreenSpaceEventType |
modifier | number | type发生事件时持有的keyboardEventModifier键 |
setInputAction(action, type, modifier)
设置要在输入事件上执行的功能。
姓名 | 类型 | 描述 |
---|---|---|
action | 回调函数 | 当输入事件发生时要执行的函数 |
type | number | 输入事件的ScreenSpaceEventType |
modifier | number | type发生事件时持有的keyboardEventModifier键 |
2.3 屏幕空间事件类型
ScreenSpaceEventType类型的回调函数可以分为五种:
PositionedEventCallback | MotionEventCallback | WheelEventCallback |
TwoPointEventCallback | TwoPointMotionEventCallback
每个回调函数对应的回调参数分别为:
PositionedEvent | MotionEvent | number | TwoPointEvent |
TwoPointMotionEvent
每个回调参数对应的属性定义如下:
// 发生在屏幕上单个位置的事件。
type PositionedEvent = {
position: Cartesian2;
};
// 从一个位置开始到另一个位置结束的事件
type MotionEvent = {
startPosition: Cartesian2;
endPosition: Cartesian2;
};
// 鼠标滚轮的移动量
delta: number
// 发生在屏幕上两个位置的事件。
type TwoPointEvent = {
position1: Cartesian2;
position2: Cartesian2;
};
// 从屏幕上的两个位置开始并移动到另外两个位置的事件。
type TwoPointMotionEvent = {
position1: Cartesian2;
position2: Cartesian2;
previousPosition1: Cartesian2;
previousPosition2: Cartesian2;
};
ScreenSpaceEventType的类型定义如下:
姓名 | 描述 | 回调函数的参数类型 |
---|---|---|
LEFT_DOWN | 鼠标左键按下事件 | PositionedEvent |
LEFT_UP | 鼠标左键向上事件 | PositionedEvent |
LEFT_CLICK | 鼠标左键单击事件 | PositionedEvent |
LEFT_DOUBLE_CLICK | 鼠标左键双击事件 | PositionedEvent |
RIGHT_DOWN | 鼠标右键按下事件 | PositionedEvent |
RIGHT_UP | 鼠标右键向上事件 | PositionedEvent |
RIGHT_CLICK | 鼠标右键单击事件 | PositionedEvent |
MIDDLE_DOWN | 鼠标中键按下事件 | PositionedEvent |
MIDDLE_UP | 鼠标中键向上事件 | PositionedEvent |
MIDDLE_CLICK | 鼠标中键单击事件 | PositionedEvent |
MOUSE_MOVE | 鼠标移动事件 | MotionEvent |
WHEEL | 鼠标滚轮事件 | number |
PINCH_START | 触摸表面上的两指事件的开始 | TwoPointEvent |
PINCH_END | 触摸表面上的两指事件的结束 | TwoPointEvent |
PINCH_MOVE | 触摸表面上两指事件的变化 | TwoPointMotionEvent |
示例
Cesium.ScreenSpaceEventType.LEFT_CLICK
3 示例方法
3.1 监听鼠标左击事件
// 绑定屏幕空间事件
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((event: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {
// 左键单击 Cartesian2 {x: 316.5, y: 352.5}
console.log('shift + 左键单击', event.position);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
3.2 移除鼠标左击事件
// 移除屏幕空间事件
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
3.3 单击添加一个点位
// 鼠标左击屏幕后,在屏幕上添加一个红色的点
const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas)
handler.setInputAction((event: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {
const carCoord = viewer.camera.pickEllipsoid(event.position)
const coord = screenToWgs(viewer, event.position)
console.log('当前的经纬度坐标为:', coord);
viewer.entities.add({
position: carCoord,
point: {
color: Cesium.Color.RED,
pixelSize: 30
}
})
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
使用了一个screenToWgs方法,定义如下:
/**
* 4、将屏幕坐标转换为WGS84坐标系
* @param viewer
* @param cartesian2
* @returns { lng: number, lat: number }
*/
export function screenToWgs(viewer: Cesium.Viewer, cartesian2: Cesium.Cartesian2) {
const cartesian3 = viewer.camera.pickEllipsoid(cartesian2) as Cesium.Cartesian3
const currentPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian3)
const lng = Cesium.Math.toDegrees(currentPosition.longitude)
const lat = Cesium.Math.toDegrees(currentPosition.latitude)
return {
lng,
lat
}
}
3.4 展示效果
最终实现的效果如下: