【cesium知识梳理】3.各类事件

2,303 阅读5分钟

之前断断续续学过、用过cesium,没有系统化的总结沉淀,现在总结一下,方便平时复习回顾。

Cesium中的事件大概可以分为3类

1.屏幕空间事件处理程序(Screen Space Event Handler)

2.屏幕空间相机控制器(Screen Space Camera Controller)

3.场景渲染事件

其中,Screen Space Event Handler 还可以分为鼠标事件键盘事件,下面逐一介绍。

1.屏幕空间事件处理程序(Screen Space Event Handler)

1.1鼠标事件

cesium为鼠标的左键,右键,滚轮以及鼠标的移动都设计了相关的API,还包括了触屏相关的事件。具体来说有:

鼠标左键:按下、弹起、单击、双击;

鼠标右键:按下、弹起、单击;

鼠标移动;

鼠标滚轮:按下、弹起、单击、滚动;

触控屏双指:开始、移动、结束

image.png

image.png

image.png

我们上一段代码,操作示意

var viewer = new Cesium.Viewer("cesiumContainer", {
            geocoder: true,  //是否显示地名查找工具
            homeButton: true,    //是否显示首页位置工具
        });

let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
//两个参数,一个回调,一个事件类型
handler.setInputAction(function (event) {
    console.log('左键按下:', event.position);
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);

// 移除屏幕空间事件
//handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);

实例化一个ScreenSpaceEventHandler对象,传入参数viewer.scene.canvas,在handler.setInputAction中传入2个参数,第一个就是事件的回调函数,第二个要说明事件的类型,代码中展示的是鼠标左键按下事件, 我们在回调函数中写上,打印坐标。

其他的点击事件,也是同样的情况,只要把事件类型更换即可

image.png

鼠标移动事件

var handler = new Cesium.ScreenSpaceEventHandler(
        viewer.scene.canvas
);
handler.setInputAction(function (event) {
        console.log("鼠标正在移动", event);
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

打印出来是这样,有一个起始位置和结束位置,这里需要注意一下

image.png

鼠标滚轮事件

鼠标滚轮,打印出来是这样,轮子向前滚,就是125,向后滚就是-125.

let handler = new Cesium.ScreenSpaceEventHandler(
        viewer.scene.canvas
);
handler.setInputAction(function (event) {
        console.log("鼠标滚轮正在滚动", event);
}, Cesium.ScreenSpaceEventType.WHEEL);

image.png

1.2键盘事件

Cesium中,键盘事件主要包括

Shift键被按住

Ctrl键被按住

Alt键被按住

3种类型, 但是它们不能单独使用,而是需要配 合鼠标事件一起使用,如鼠标左键+Shift键、鼠标右键+Alt键等。

image.png

代码如下,需要在设置事件类型时,将键盘类型和鼠标类型一起传入,用逗号隔开

var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        handler.setInputAction(function (event) {
            console.log('alt+鼠标左键点击:', event.position);
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK,Cesium.KeyboardEventModifier.ALT);
     // 移除屏幕空间事件
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK, Cesium.KeyboardEventModifier.ALT);

2相机事件

cesium默认的相机事件也是非常丰富的,有4种,如下:

image.png

分别是,鼠标左键按下并拖动(DRAG就是单词drag,拖动的意思)、鼠标右键按下并拖动,鼠标中键按下拖动,鼠标滚轮滚动。

这几个操作所产生的效果如下:

image.png

如上图所示,LEFT_DRAG, 即为鼠标左键按下并拖动

在3D视图下,会让相机绕地球旋转(但是我们人在电脑前看到的效果是地球自己在旋转),在其他视图下,是地图平移的效果

其他的以此类推,值得一提的是,CTRL键+鼠标左键按下并拖动,效果是倾斜地球。

如果想修改这些默认的相机事件,需要用到viewer.scene.screenSpaceCameraController,并且不需要实例化,直接修改相应的参数就可以,一些参数如下:

image.png

具体该如何修改默认相机事件呢?

我们举一个例子:

image.png

在上个图中,LEFT_DRAG ,鼠标右键按下并拖动,他的默认效果是缩放,那我们想把它的功能改为【相机倾斜视角】,掌管【相机倾斜视角】的参数是tiltEventTypes,可以这么做:

var viewer = new Cesium.Viewer("cesiumContainer", {
    geocoder: true, //是否显示地名查找工具
    fullscreenButton: true, //是否显示全屏按钮工具
});
//相机倾斜视角的功能 设置为 鼠标右键拖拽控制
viewer.scene.screenSpaceCameraController.tiltEventTypes =
Cesium.CameraEventType.RIGHT_DRAG;

如果想让多个操作实现同一功能,例如鼠标右键、CTRL+鼠标右键、CTRL+鼠标左键都可以控制相机倾斜,那只需用一个数组即可:

var viewer = new Cesium.Viewer("cesiumContainer", {
    geocoder: true, //是否显示地名查找工具
    fullscreenButton: true, //是否显示全屏按钮工具
});
//相机倾斜视角的功能 设置为 鼠标右键拖拽控制
viewer.scene.screenSpaceCameraController.tiltEventTypes =
[
    Cesium.CameraEventType.RIGHT_DRAG,
    //CTRL+鼠标左键
    {
        eventType: Cesium.CameraEventType.LEFT_DRAG,
        modifier: Cesium.KeyboardEventModifier.CTRL,
    },
    //CTRL+鼠标右键
    {
        eventType: Cesium.CameraEventType.RIGHT_DRAG,
        modifier: Cesium.KeyboardEventModifier.CTRL,
    },
];

3.场景渲染事件

Cesium的场景渲染事件主要包括4种,

1.Scene.preUpdate 场景更新前事件,即更新或呈现场景之前将引发的事件

2.Scene.postUpdate 场景更新后事件,即更新场景之后及渲染场景之前立即引发的事件

3.Scene.preRender 场景渲染前事件,即更新场景之后及渲染场景之前将引发的事件

4.Scene.postRender 场景渲染后事件,即渲染场景之后立即引发的事件

他们的执行顺序也是由上到下,依次进行。

preRender: 预渲染事件,在场景预处理之后,相机视角确定之前调用。此事件在场景开始渲染之前调用,因此可以使用此事件来执行一些初始化或准备工作,例如:获取视口或获取相机参数。

postRender: 渲染后事件,在场景完成渲染之后调用。此事件可以用于处理场景渲染的逻辑,例如:处理绘制、设置绘制命令等。

preUpdate: 预更新事件,在更新前的准备工作阶段调用。此事件在执行场景更新之前调用,可以使用此事件来检查更新是否需要执行,例如:检查更新是否需要更新相机或场景。

postUpdate: 更新后事件,在更新完成后调用。此事件在执行场景更新之后调用,可以使用此事件来处理更新后的逻辑,例如:处理相机或场景的更新结果。

在代码中使用,需要用addEventListener进行绑定用removeEventListener进行解绑

// 需要回调的函数
    function callbackpreUpdate(event) {
            console.log("callbackpreUpdate  111");
    }
    function callbackpostUpdate(event) {
            console.log("callbackpostUpdate   222");
    }
    function callbackpreRender(event) {
            console.log("callbackpreRender   333");
    }
    function callbackpostRender(event) {
            console.log("callbackpostRender   4444");
    }
    // 注册更新之前执行回调函数
    viewer.scene.preUpdate.addEventListener(callbackpreUpdate);
    viewer.scene.postUpdate.addEventListener(callbackpostUpdate);
    viewer.scene.preRender.addEventListener(callbackpreRender);
    viewer.scene.postRender.addEventListener(callbackpostRender);

    // 注销之前所注册的回调函数
    viewer.scene.preUpdate.removeEventListener(callbackpreUpdate);
    viewer.scene.postUpdate.removeEventListener(callbackpostUpdate);
    viewer.scene.preRender.removeEventListener(callbackpreRender);
    viewer.scene.postRender.removeEventListener(callbackpostRender);

image.png