webgl三维可视化在线开发实用教程

事件

ThingJS 系统内置了很多事件,比点击鼠标、键盘输入、层级变化等。用户可以监听这些事件,在事件回调中进行相应的业务逻辑处理。

事件介绍

全局绑定事件和局部绑定事件

用户的操作以及场景的变化,都将会触发相应的事件。你可以监听这些事件,然后在回调方法中做相应的处理。

全局绑定:通过 app.on 绑定事件,可在全局下添加条件指定针对哪些物体绑定该事件,条件规则同于 query 使用的条件。

注意事项50代码HTML5 Canvas 3D 编辑器优雅搞定

在全局绑定后,新创建的符合条件物体也可以生效。

一些事件也可以不添加条件,不针对特定物体即可生效。

例子1:

app.on("click",function(ev));

上面的例子,不添加条件,鼠标一 click 就触发。

例子2:

app.on("click",".Thing",function(ev));

上面的例子,添加了条件,只有在符合该条件的物体上 click 才会触发,无论是已经存在的 Thing 对象,还是后面新创建的 Thing 对象都会生效。

查看示例

局部绑定:针对一个对象,或者 query 的查询结果(Selector),通过 on 接口绑定事件,我们叫局部绑定。同全局绑定,事件中可以加条件,表示这个事件绑定是针对这个物体子子孙孙的。

也可以不添加条件,表示该事件是针对物体本身的

例子3:

obj.on("click",function(ev));

上面的例子,当这个物体被点击,就会触发

例子 4:

obj.on("click",".Marker",function(ev));

上面的例子,当这个物体子孙里有 Marker 物体,当它被点击就会触发。同全局绑定 Marker 物体,绑定后 obj 的子孙里新创建的 Marker 也响应这个事件。

例子 5:

obj.query(".Marker").on("click",function(ev));

上面的例子,其实就是直接查询 obj 其下所有的 Marker 物体,遍历找到的 Marker,分别使用 on 注册事件。

注意事项

这个方式是对 obj 下每个查询到的 Marker 物体即时绑定的,对于 obj 下后创建的 Marker,是没有影响的。

上面的例子,其实就是直接查询 obj 其下所有的 Thing 物体,遍历找到的 Thing,分别使用类似例子 4 的方式绑定事件。

ThingJS都提供哪些事件

所有事件通过 THING.EventType 命名空间索引,也可以查询 API 中的 EventType 对应的字符串,不区分大小写。

obj.on("click",function(ev));

也可以写成

obj.on(THING.EventType.Click,function(ev));

data 的使用

例子 7:

varcb=function(ev);// 这里将颜色作为参数传给回调函数,在回调函数中通过 ev.data 获取app.query(".Building").on("mouseon",".Thing","#FF0000",cb);app.query(".Thing").on("mouseon",".Thing","#00FF00",cb);

同一个事件注册多个回调

试想一下,如果我们有一个模块在物体 click 时,改变物体颜色,另外一个模块需要在物体 click 时,放大物体。两个模块又是不同人写的,那该如何注册事件呢?

//事件1:obj.on("click",function(ev));//事件2:obj.on("click",function(ev));

这两个事件,都会在 obj 被点击后触发。

但这种多事件注册模式会有些不方便的地方,比如具体指定取消那个事件,需要带上原回调。

varcb=function(ev);app.on("click",".Building",cb);// 卸载app.off("click",".Building",cb);

因此我们更推荐使用[tag]的方式。

tag

如果取消或者暂停事件,都要知道原回调函数,在大部分时候会比较麻烦,我们可以给每个事件打上 tag,在删除或者暂停时,可用 tag 直接指定你要操作的回调。

//模块1中:obj.on("click",function(ev),"模块1");//模块2中:obj.on("click",function(ev),"模块2");//取消"模块1"的事件回调,不影响“模块2”的回调obj.off("click",null,"模块1");

利用 tag 功能,我们还能实现替换一个回调。比如,之前打了 tag 的事件,我们别处需要修改或者暂停这个事件,就可以通过 tag 来实现。

//将上例的“模块1”的回调,改成如下obj.on("click",function(ev),"模块1");

系统内置了一些 tag ,供外部控制(暂停、恢复)。

比较典型的例子是 EnterLevel 事件,该事件会触发多个内置响应,如层级切换后的场景控制、飞行控制、背景变化等。

因此我们更推荐使用tag的方式。

查看示例

优先级:

还是刚才的例子,两个都是 click 事件,如果我们希望保证模块 2 的事件先于模块 1 触发,该如何设置?

//模块1:obj.on("click",function(ev),"模块1");//模块2:obj.on("click",function(ev),"模块2",51);

在模块 2 的事件回调中,又添加了一个参数`priority`,我们设置为 51,一般事件默认的优先级是 50,设置的越大,越优先触发。

注册单次事件

如果需要一个事件只执行一次,就需要卸载掉,你可以使用 one 这个接口代替 on,参数和 on 是一样的。但是,如下情况需要注意:

我们提供 priority 的能力:

// 下例中是给每个楼层的注册了一次 EnterLevel 事件,即 每个楼层第一次进入时 都会响应app.one(THING.EventType.EnterLevel,'.Floor',function(ev))// 如果只给某个楼层注册 如下varfloor=app.query('.Floor')[0];floor.one(THING.EventType.EnterLevel,function(ev))

移除,暂停事件

卸载事件

当我们想卸载一个事件的时候使用 off 接口。

例子 1:

app.on("click",function(event));// 卸载app.off("click");

例子 2:

app.on("click",".Building",function(event));// 卸载app.off("click",".Building");

例子 3:

varcb=function(event)app.on("click",".Building",cb);// 卸载app.off("click",".Building",cb);

例子 4:

app.on("click",".Building",function(event));app.on("click",".Building",function(event),"tag1");app.on("click",".Building",function(event),"tag2");// 卸载app.off("click",".Building");

这样就把所有的 building 下的 click 事件都清除了。

假设这个物体有多个 marker,我们找到其中一个卸载掉事件,不影响其他 marker,和后创建的 marker。

注意事项

off 第二个参数必须传条件,如果没有条件,又需要传 tag ,需要将条件传 null。

`one` 注册的事件,也是用`off`来去除。

暂停事件

如果`off`掉一个事件,要想恢复,有时候比较难,你找不到之前的回调方法了。面对这种情况,我们提供 `pauseEvent`方法,用于暂停事件,它的控制方法和标准类似于 off。

例子 5:

app.on("click",".Building",function(event),"tag1");// 暂停app.pauseEvent("click",".Building","tag1");

例子 6:

marker.pauseEvent("click", null, tag);

要想恢复事件响应,使用 `resumeEvent` 方法

app.resumeEvent("click", ".Building", "tag1");

自定义事件

ThingJS 内置了很多事件,但如果自己写模块的时候,也需要触发事件,该如何操作?外部注册还是使用 on,在需要触发的地方我们使用 trigger 接口来对外触发事件。

比如你在写一个报警管理器:

classAlamrManagerenable(){......app.trigger("AlarmEnable")......}setObjAlarm(obj,alarmLevel){......obj.trigger("alarm",{"level":alarmLevel})......}}

外部注册如下:

app.on("AlarmEnable",function(ev){......})app.query(".Thing").on("alarm",function(ev)......})

事件清单

EventType ,可点击此处查看。

事件中的事件名以及事件参数部分如下图所示:

内部事件

Complete 通知 App 初始化完成

Resize 通知视口大小变化

Resize.size 窗口宽高([0]:宽度, [1]:高度)

Update 通知 App 更新

Progress 通知加载进度更新

Progress.progress 加载进度(0~1)

BeforeLoad 通知将要加载物体

BeforeLoad.object 要加载的物体

Load 通知加载

Load.campus 园区

Load.buildings 园区建筑物

Unload 通知卸载

Unload.url 场景资源路径

Click 通知鼠标点击

Click.picked 是否成功拾取到物体

Click.object 当前拾取物体

Click.pickedPosition 获取拾取点坐标

DBLClick 通知鼠标双击

DBLClick.button 鼠标按键[0: 左键, 1: 中键, 2: 右键]

DBLClick.picked 是否成功拾取到物体

DBLClick.object 当前拾取物体

DBLClick.pickedPosition 获取拾取点坐标

SingleClick 通知鼠标单击

SingleClick.picked 是否成功拾取到物体

SingleClick.object 当前拾取物体

SingleClick.pickedPosition 获取拾取点坐标

MouseUp 通知鼠标键抬起

MouseUp.picked 是否成功拾取到物体

MouseUp.object 当前拾取物体

MouseUp.pickedPosition 获取拾取点坐标

MouseDown 通知鼠标键按下

MouseDown.picked 是否成功拾取到物体

MouseDown.object 当前拾取物体

MouseDown.pickedPosition 获取拾取点坐标

MouseMove 通知鼠标移动

MouseDown.picked 是否成功拾取到物体

MouseDown.object 当前拾取物体

MouseDown.pickedPosition 获取拾取点坐标

MouseMove 通知鼠标移动

MouseMove.picked 是否成功拾取到物体

MouseMove.object 当前拾取物体

MouseMove.pickedPosition 获取拾取点坐标

MouseWheel 通知鼠标滚轮事件

MouseWheel.delta 判断滚轮方向, (负数: 向前滚动, 正数: 向后滚动)

MouseEnter 通知鼠标首次移入物体

MouseEnter.object 当前拾取物体

MouseOver 通知鼠标首次移入物体, 会一直传递到父物体

MouseOver.object 当前拾取物体

DragStart 通知物体拖拽开始

DragStart.object 当前拾取物体

DragStart.pickedPosition 获取拾取点坐标

Drag 通知物体拖拽进行中

Drag.object 当前拾取物体

Drag.pickedPosition 获取拾取点坐标

DragEnd 通知物体拖拽结束

DragEnd.object 当前拾取物体

DragEnd.pickedPosition 获取拾取点坐标

KeyDown 通知键盘按键按下

KeyDown.key 键值 ID

KeyPress 通知键盘按键一直被按下

KeyPress.key 键值 ID

KeyUp 通知键盘按键抬起

KeyUp.key 键值 ID

CameraChangeStart 通知摄像机位置变动开始

CameraChangeStart.target 摄像机观察点世界坐标信息

CameraChangeStart.position 摄像机世界坐标信息

CameraChangeEnd 通知摄像机位置变动结束

CameraChangeEnd.target 摄像机观察点世界坐标信息

CameraChangeEnd.position 摄像机世界坐标信息

CameraChange 通知摄像机位置变动中

CameraChange.target 摄像机观察点世界坐标信息

CameraChange.position 摄像机世界坐标信息

CameraViewChange 通知摄像机观察模式改动

CameraViewChange.view 摄像机类型

Create 通知物体创建完成

Create.object 物体

Expand 通知物体被展开

Expand.object 物体

Unexpand 通知物体被合并

Unexpand.object 物体

PickChange 通知物体拾取对象更新

THING.Selector} PickChange.objects 当前拾取物体列表

PickChange.previousObjects 之前的拾取物体列表

AreaPickStart 通知框选开始

AreaPicking 通知框选中

AreaPicking.objects 拾取物体列表

AreaPickEnd 通知框选结束

Select 通知物体被选择

Select.objects 物体列表

Deselect 通知物体被取消选择

Deselect.objects 物体列表

SelectionChange 通知物体选择集合更新

SelectionChange.objects 物体集合

LevelChange 通知场景层次发生改变

LevelChange.level 当前层级标识

LevelChange.current 当前层级

LevelChange.previous 上一层级

EnterLevel 通知进入物体层级

EnterLevel.object 当前层级

EnterLevel.current 当前层级

EnterLevel.previous 上一层级

LeaveLevel 通知退出物体层级

LeaveLevel.object 当前层级

LeaveLevel.current 当前层级

LeaveLevel.previous 上一层级(离开的层级)

LevelFlyEnd 通知摄像机飞入物体层级进入完成

EnterLevel.object 当前层级

EnterLevel.current 当前层级

EnterLevel.previous 上一层级

LevelFlyEnd 通知摄像机飞入物体层级进入完成

LevelFlyEnd.object 当前层级

LevelFlyEnd.current 当前层级

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20191225A0GCTF00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券