模块
模块常用方法
基础用法
let entity = new Entity(); // 创建一个实体
entity.addObjects(mesh); // 在实体下面增加一个mesh
entity.addTo(app); // 把实体增加至应用中
增加模块
addModule 或 add 增加模块,如果模块已存在,则返回之前的模型,等同于 add
// 增加一个事件模块
entity.add(vjmap3d.EventModule, {
hoverSelect: true
});
获取模块
getModule 获取模块
// 获取事件模块
let mod = entity.getModule(vjmap3d.EventModule);
if (mod) {
// 如果模块存在,调用模块中的方法
mod.removeEvent();
}
移除模块
removeModule 移除模块
// 移除模块
entity.removeModule(vjmap3d.EventModule);
移除所有模块
removeAllModules 移除所有模块
// 移除实体中的所有模块
entity.removeAllModules();
调用模块中的方法
callModules 调用模块中的方法,实体中的所有模块,如果有这个方法,都会调用
// 所有模块都调用应用更新函数,(如果模块中有onAppUpdate方法)
entity.callModules("onAppUpdate", time);
示例:控制网格显示或隐藏
let gridHelper = app.sceneEntity.getModule(vjmap3d.GridHelperModule);
if (gridHelper) {
gridHelper.setVisible(!gridHelper.getVisible())
}
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
scene: {
gridHelper: { visible: true } // 是否显示坐标网格
}
})
let control = new vjmap3d.ButtonGroupControl({
buttons: [
{
id: "grid",
html: "网格隐藏/显示",
title: "显示或隐藏坐标网格",
style: {
width: "100px"
},
onclick: async () => {
let gridHelper = app.sceneEntity.getModule(vjmap3d.GridHelperModule);
if (gridHelper) {
gridHelper.setVisible(!gridHelper.getVisible())
}
}
}
]
});
app.addControl(control, "top-right");
模块生命周期
| 周期 | 描述 |
|---|---|
| onAppStart | 只模块初始化调用一次,调用后就需要从数组删除 |
| onAppBeforeUpdate | 每帧更新前运行 |
| onAppUpdate | 每帧更新 |
| onAppAfterUpdate | 每帧更新后运行 |
| onAppBeforeRender | 每帧渲染前运行 |
| onAppRender | 每帧渲染 |
| onAppAfterRender | 每帧渲染后运行 |
应用模块回调事件
App 模块基类 AppModuleBase , 相关回调事件如下:
| 事件 | 描述 |
|---|---|
| onAppBeforeUpdate | 每帧更新前运行 |
| onAppUpdate | 每帧更新 |
| onAppAfterUpdate | 每帧更新后运行 |
| onAppBeforeRender | 每帧渲染前运行 |
| onAppRender | 每帧渲染 |
| onAppAfterRender | 每帧渲染后运行 |
| onAppBeforeAddEntity | 实体增加前回调 |
| onAppAddEntity | 实体增加回调 |
| onAppBeforeRemoveObject | object3d对象移除前回调 |
| onAppRemoveObject | object3d对象移除回调 |
| onAppBeforeRemoveEntity | 实体移除前回调 |
| onAppRemoveEntity | 实体移除回调 |
实体模块回调事件
Entity 模块基类 EntityModuleBase , 相关回调事件如下:
| 事件 | 描述 |
|---|---|
| onAppBeforeUpdate | 每帧更新前运行 |
| onAppUpdate | 每帧更新 |
| onAppAfterUpdate | 每帧更新后运行 |
| onAppBeforeRender | 每帧渲染前运行 |
| onAppRender | 每帧渲染 |
| onAppAfterRender | 每帧渲染后运行 |
| onAppBeforeAddEntity | 实体增加前回调 |
| onAppAddEntity | 实体增加回调 |
| onAppBeforeRemoveObject | object3d对象移除前回调 |
| onAppRemoveObject | object3d对象移除回调 |
| onAppBeforeRemoveEntity | 实体移除前回调 |
| onAppRemoveEntity | 实体移除回调 |
| onBeforeAdd | 模块被增加至实体并增加至应用前回调 |
| onAdd | 模块被增加至实体并增加至应用时 |
| onBeforeRemove | 模块开始移除前 |
| onRemove | 模块移除时 |
| onRayIntersect | 射线相关检测判断时 |
| onMouseUp | 鼠标抬起 |
| onMouseMove | 鼠标移动 |
| onMouseDown | 鼠标按下 |
| onMouseClick | 鼠标单击 |
| onMouseDblClick | 鼠标双击 |
| onMouseOver | 鼠标指针穿过被选元素或其子元素,均会触发事件 |
| onMouseOut | 鼠标指针离开被选元素或其子元素则触发事件 |
| onMouseEnter | 鼠标指针穿过被选元素时才触发事件 |
| onMouseLeave | 鼠标指针离开被选元素时才触发事件 |
| onPointerDown | 指针按下(PC和移动端) |
| onPointerMove | 指针移动(PC和移动端) |
| onPointerUp | 指针抬起(PC和移动端) |
| onMouseWheel | 鼠标滚轮 |
| onKeyDown | 键盘按下 |
| onKeyUp | 键盘抬起 |
| setupUiConfig | UI设置界面 |
自定义模块
我们可以自定义开发一些模块的功能,把这个模块增加至相关的实体上,让实体拥有这个模块的功能。
比如要让一个实体围绕y轴旋转。可以写这么一个模块,模块需要继承于 EntityModuleBase
class RotateYModule extends vjmap3d.EntityModuleBase {
onAppUpdate() {
this.entity.node.rotateY(-0.01);
}
}
// 当实体增加这个模块后,这个实体会自动绕y轴旋转
entity.add(RotateYModule);
setTimeout(() => {
// 过三十秒后,移动这个模块,实体将停止绕y轴旋转
entity.removeModule(RotateYModule);
}, 30000)
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
scene: {
gridHelper: { visible: true } // 是否显示坐标网格
},
camera: { // 相机设置
viewHelper: { enable: true } // 是否显示视角指示器
}
})
//
let box = new THREE.BoxGeometry(2, 2, 2)
const material = new THREE.MeshStandardMaterial({
color: "#ff0",
side: THREE.DoubleSide
});
let mesh = new THREE.Mesh(box, material);
let entity = vjmap3d.Entity.fromObject3d(mesh);
entity.addTo(app);
class RotateYModule extends vjmap3d.EntityModuleBase {
onAppUpdate() {
this.entity.node.rotateY(-0.01);
}
}
// 当实体增加这个模块后,这个实体会自动绕y轴旋转
entity.add(RotateYModule);
//
setTimeout(() => {
// 过三十秒后,移动这个模块,实体将停止绕y轴旋转
entity.removeModule(RotateYModule);
}, 30000)
模块中事件监听
有以下两种方式:
- 通过实现基类中的事件回调函数实现
如上例中 在 RotateYModule中实现了
onAppUpdate函数,应用每帧更新回调时,会自动回调此函数
class RotateYModule extends vjmap3d.EntityModuleBase {
onAppUpdate() {
this.entity.node.rotateY(-0.01);
}
}
- 监听事件实现
class RotateYModule extends vjmap3d.EntityModuleBase {
constructor(entity) {
super(entity)
// 实体增加至app时
entity.onEntityAwake(app => {
// 监听onAppUpdate事件,并在模块移除的时候自动取消监听
this.addDispose(app.signal.onAppUpdate.add(() => {
this.entity.node.rotateY(-0.01);
}))
});
}
}
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
scene: {
gridHelper: { visible: true } // 是否显示坐标网格
},
camera: { // 相机设置
viewHelper: { enable: true } // 是否显示视角指示器
}
})
//
let box = new THREE.BoxGeometry(2, 2, 2)
const material = new THREE.MeshStandardMaterial({
color: "#ff0",
side: THREE.DoubleSide
});
let mesh = new THREE.Mesh(box, material);
let entity = vjmap3d.Entity.fromObject3d(mesh);
entity.addTo(app);
class RotateYModule extends vjmap3d.EntityModuleBase {
constructor(entity) {
super(entity)
// 实体增加至app时
entity.onEntityAwake(app => {
// 监听onAppUpdate事件,并在模块移除的时候自动取消监听
this.addDispose(app.signal.onAppUpdate.add(() => {
this.entity.node.rotateY(-0.01);
}))
});
}
}
// 当实体增加这个模块后,这个实体会自动绕y轴旋转
entity.add(RotateYModule);
//
setTimeout(() => {
// 过三十秒后,移动这个模块,实体将停止绕y轴旋转
entity.removeModule(RotateYModule);
}, 30000)