事件
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 当前层级
领取专属 10元无门槛券
私享最新 技术干货