ThingJS 架构
场景搭建
- 圈地
- 添加自定义建筑
- 设置参考图及其比例(可前置为第一步)
- 设置建筑外立面
- 自定义属性
- 场景导出
场景加载
```javascript // 线上 const app = new Thing.App({ url: “线上场景 URL”, }); // 本地 const app = new Thing.App({
});
<a name="Flibf"></a>## UI 元素创建及引入<a name="XcMXx"></a>### ThingJS 界面体系<a name="XeASG"></a>#### 3D 容器外的 UI 引入方式<a name="LmChE"></a>##### `iframe` 方式引入通过 `document.body.appendChild` 将 `iframe` 嵌入页面(需要对 `iframe` 进行 `position` 定位 )<a name="rwik9"></a>##### `app.domElement.appendChild` 方式引入通过 `app.domElement.appendChild` 方式引入创建的 `element` 元素(需要对其进行 `position` 定位)<a name="qWWyV"></a>#### 3D 容器内的 UI 引入方式<a name="xpeHV"></a>##### 通过 `UIAnchor` 类型创建```javascriptclass CreateUIAnchor {constructor() {this.ui = null;this.init();}// 初始化 UIinit() {const template = `<div class="bubble" id="uianchor"><span>小车</span></div>`;const uiElem = document.createElement("template");uiElem.innerHTML = template;document.querySelector("#div3d").append(uiElem.content.childNodes);this.createUI();}// 创建 UIAnchorcreateUI() {this.ui = app.create({type: "UIAnchor",parent: app.query("car02")[0],element: this.createElement(),localPosition: [0, 2, 0],pivot: [0.5, 1], // UI 元素定位中心, [0, 0] 左上角, [1, 1] 右下角});},// 创建元素createElement() {const originElem = document.querySelector("#uianchor");const newElem = originElem.cloneNode(true);newElem.style.display = "block";app.domElement.insertBefore(newElem, originElem);return newElem;},}
通过 Maker 类型创建
class CreateMarker {constructor() {this.ui = null;this.init();}// 初始化 UIinit() {const template = `<div class="bubble" id="marker"><span>小车</span></div>`;const uiElem = document.createElement("template");uiElem.innerHTML = template;document.querySelector("#div3d").append(uiElem.content.childNodes);this.createUI();}// 创建 UIAnchorcreateUI() {this.ui = app.create({type: "Marker",parent: app.query("car02")[0],element: document,querySelector("#marker"),localPosition: [0, 2, 0],size: 2,});}}
注意:
- 3D容器外的2D界面布局需使用
position定位; - 3D容器内的顶牌,使用绑定
element对象方式创建顶牌时,注意样式编写:- 样式不能写为模块/组件样式,需写为全局样式;
- 顶牌 DOM 元素需要隐藏;
UIAnchor和Marker的区别是,前者不能被 app 实例管理操作;但销毁方式都是使用destory方法。⭐创建物体
参考 《创建/销毁物体》 章节。扩展知识
坐标点位采集
通过监听园区的点击事件,获取点击处的坐标点位。app.on("click", (e) => {console.log(e.pickedPosition);});
创建物体并添加控件
通过app.create创建的物体,可以通过obj.addControl方法添加由new THING.AxisTransformControl(obj, type, options, tag)创建的操作控件,也能通过obj.removeControl(tag)移除已添加的控件。 ```javascript // 单击 app.on(“singleClick”, (ev) => { // 创建物体 app.create({ type: “Thing”, url: “”, localPosition: ev.pickedPosition, // 物体的初始位置为点击的点位(父级的坐标系) scale: [3, 3, 3], // 物体缩放 parent: app.level.current, // 父对象为当前层级对象 complete() { // 物体添加位置移动控件 obj.addControl(createTransCtrl(this, “transform”)); // 物体添加角度调整控件 obj.addControl(createTransCtrl(this, “rotate”)); } }); });
// 创建操作控件
function createTransCtrl(obj, type) {
const tag = ${type}Control;
return new THING.AxisTransformControl(obj, type, {
changeStart() {
console.log(start ${type});
},
changeEnd() {
console.log(${type} end, type === “transform” ? obj.position : obj.angle);
// 物体移除操作控件
obj.removeControl(tag);
},
}, tag);
}
<a name="DZvJZ"></a>## 物体效果设置- 颜色 `obj.style.color = <hex-color> | rgba() | <named-color> | null`- 透明度 `obj.style.opacity = <number>`- 勾边/轮廓 `obj.style.outlineColor = <hex-color> | rgba() | <named-color> | null`- 发光/阴影- 向外 `obj.style.glow = <boolean>`- 向内 `obj.style.innerGlow = <boolean>`- 缩放- 瞬时 `obj.style.scale = [x, y, z]`- 逐渐缩放 `obj.style.scaleTo = [x, y, z]`- 停止缩放 `obj.style.stopScaling()`- ⭐移动```javascript// 移动到目标点obj.moveTo({position: [x, y, z],time: 1000,delayTime: 1000,orientToPath: true, // 移动时朝向移动路径lerpType: null, // 插值方式,默认线性(与 css 的 transition-time-funtion 类似)loopType: THING.loopType.Repeat, // 重复complete(e) {},});// 按路径移动const path = [[0, 0, 0], [1, 2, 3] ...];obj.movePath({path, // 移动路径,非 position 目标点// ....});
扩展知识
⭐自定义类管理设备状态
// 定义类// 自定义安全帽类继承物体类class SafetyHelmet extends THING.Thing {contructor(app) {super(app);},// 添加自定义属性alarmed: flase,// 添加自定义方法alarm() {this.alarmed = true;}}// 注册类,参数是(类型名, 构造函数)THING.factory.registerClass("SafetyHelmet", SafetyHelmet);// 通过自定义类创建物体const sh = app.create({type: "SafetyHelmet",name: "安全帽001",url: "",position: [],// ...});// 查询自定义物体const shs = app.query(".SafetyHelmet");// 给自定义物体注册事件,并调用其方法app.on("click", ".SafetyHelmet", (e) => {e.object.alarm();console.log(e.object.alarmed);});
事件绑定与顶牌控制
事件绑定
ThingJS 中内置的事件有:鼠标事件,键盘事件,层级变化事件等。主要分为全局事件和局部事件;
- 全局事件
app.on(eventName, callback, tagName?)app.on(eventName, condition, callback, tagName?)其中condition可为一种或多种类型,如".Thing"或".Car || .SafetyHelmet"
局部事件
Marker
- 图片
- canvas
- Element
- TextRegion 文本
- WebView: 3D 内嵌页面
- UIAnchor: 2D 界面(不能设置大小和近大远小
size, keepSize,不能通过query查询,无法被程序管理) - Widget: 2D 快捷界面库
层级切换
ThingJS 提供了 SenseLevel 模块,可以通过app.level控制层级。
常用的 API 有:
app.level.chang(obj) |
层级切换到指定对象 |
|---|---|
app.level.back() |
回到上一层级 |
app.level.current |
当前层级对象 |
app.level.previous |
前一个层级对象 |
| EnterLevel | 进入层级事件,内含 4 个响应: - THING.EventTag.LevelSenseOperation 进入层级时的场景控制- THING.EventTag.LevelFly 进入层级时的飞行控制- THING.EventTag.LevelSetBackground 进入层级时的天空背景控制- THING.EventTag.LevelPickedResultFun 进入层级时的 Pick 对象设置 |
| LeaveLevel | 退出层级事件,内含 1 个响应: - THING.EventTag.LevelSenseOperation 进入层级时的场景控制 |
| LevelFlyEnd | 层级切换后相机飞行结束事件 |
⭐相机
相机常用 API
app.camera.position |
摄像机位置 |
|---|---|
app.camera.target |
摄像机目标 |
app.camera.up |
摄像机 UP 方向 默认值为 [0,1,0] |
app.camera.lookAt(<position> | <object> | null) |
摄像机“盯”住某一物体 |
app.camera.fit() |
摄像机自动调整最佳位置(无回调) |
app.camera.flyTo(<position> | <object>) |
设置摄像机飞行 |
app.camera.flying() |
返回 <boolean> 类型的摄像机飞行状态 |
app.camera.stopFlying() |
设置摄像机停止飞行 |
app.camera.rotateAround(<position> | <object>) |
设置摄像机环绕某点/物体飞行 |
app.camera.followObject(<object>) |
设置摄像机跟随某一物体移动 |
app.camera.stopFollowObject() |
设置摄像机停止跟随物体 |
相机交互控制
app.camera.inputEnable |
是否允许相机交互 |
|---|---|
app.camera.enablePan |
是否允许相机平移 |
app.camera.enableRotate |
是否允许相机旋转 |
app.camera.enableZoom |
是否允许相机缩放 |
app.camera.mousePanSpeed = 0.1 |
鼠标平移速度 |
app.camera.keyPanSpeed = 0.1 |
键盘平移速度 |
app.camera.yAngleLimitRange = [0, 360] |
相机水平角度范围 |
app.camera.xAngleLimitRange = [0, 360] |
相机垂直角度范围 |
app.camera.viewMode = "" |
相机模式 - THING.CameraView.TopView 顶视图- THING.CameraView.Normal 3D 视图(默认) |
数据对接
- Ajax
- JSONP
- Axios
- Websocket
