文章目录
- 第一部分:ThingJS基础入门
- 第一章 ThingJS概述与技术架构
- 1.1 ThingJS平台简介
- 1.2 技术架构解析
- 1.3 开发环境配置
- 第二章 基础概念与核心API
- 2.1 核心对象模型
- 2.2 场景创建与管理
- 2.3 对象操作基础
- 第三章 基础开发实战
- 3.1 第一个ThingJS应用
- 3.2 事件系统详解
- 3.3 基础动画实现
- 第二部分:ThingJS中级开发
- 第四章 场景设计与优化
- 4.1 复杂场景构建
- 4.2 性能优化策略
- 第五章 高级交互实现
- 5.1 复杂事件处理
- 5.2 UI系统集成
- 第六章 数据可视化
- 6.1 数据驱动场景
- 6.2 高级可视化技术
- 第三部分:ThingJS高级精通
- 第七章 自定义扩展开发
- 7.1 自定义组件开发
- 7.2 着色器开发
- 第八章 项目架构与工程化
- 8.1 大型项目组织
- 8.2 性能分析与调优
- 第九章 实战项目:智慧园区综合管理系统
- 9.1 项目需求分析
- 9.2 系统实现
- 第四部分:扩展与未来
- 第十章 ThingJS高级主题
- 10.1 跨平台开发
- 10.2 与GIS系统集成
- 第十一章 最佳实践与常见问题
- 11.1 性能优化清单
- 11.2 常见问题解决方案
第一部分:ThingJS基础入门
第一章 ThingJS概述与技术架构
1.1 ThingJS平台简介
ThingJS是优锘科技推出的面向物联网的三维可视化开发平台,基于WebGL技术构建,专注于解决物联网应用中的"最后一公里"可视化问题。该平台自2016年发布以来,已广泛应用于智慧城市、工业互联网、园区管理、电力能源等众多领域。
核心特点:
- 低代码开发:提供可视化编排工具和丰富的API,降低3D可视化开发门槛
- 跨平台支持:基于Web标准,一次开发可运行于PC、移动端及大屏设备
- 性能优化:采用层级细节(LOD)技术和智能加载机制,支持大规模场景渲染
- 生态完善:拥有模型市场、插件系统和开发者社区支持
1.2 技术架构解析
整体架构:
[应用层] ←→ [ThingJS API] ←→ [核心引擎] ←→ [渲染层]↑ ↑[扩展插件] [资源管理系统]
核心组件:
- 场景图系统(Scene Graph):基于树状结构管理所有3D对象
- 实体组件系统(ECS):通过组件化方式扩展对象功能
- 材质系统:支持PBR(物理渲染)和传统材质
- 动画系统:包含骨骼动画、变形动画和粒子系统
- 物理引擎:集成轻量级碰撞检测系统
1.3 开发环境配置
基础环境准备:
# 推荐开发环境
Node.js 14+ (LTS版本)
Visual Studio Code 或 WebStorm
Chrome/Firefox最新版# 安装ThingJS CLI工具
npm install -g @thingjs/cli# 创建新项目
thingjs create my-first-project
cd my-first-project
npm install
npm run serve
项目目录结构:
├── public/ # 静态资源
├── src/
│ ├── assets/ # 项目资源
│ ├── components/ # 自定义组件
│ ├── configs/ # 配置文件
│ ├── scenes/ # 场景脚本
│ ├── styles/ # 样式文件
│ ├── utils/ # 工具函数
│ └── main.js # 应用入口
├── thingjs.config.js # 构建配置
└── package.json
第二章 基础概念与核心API
2.1 核心对象模型
对象层次结构:
App → Scene → Camera → Controller↑Object3D↑(Mesh, Light, Helper...)
关键类说明:
- THING.App:应用入口,管理应用生命周期
- THING.Scene:场景容器,管理所有3D对象
- THING.Camera:视图控制器,决定观察视角
- THING.Object3D:所有3D对象的基类
2.2 场景创建与管理
基础场景创建:
const app = new THING.App({background: '#000000', // 背景色skyBox: 'SkyBox1', // 天空盒env: 'env1' // 环境光
});// 创建地面
const ground = app.create({type: 'Ground',name: 'myGround',position: [0, 0, 0],style: {texture: 'gradient',size: [100, 100]}
});// 加载园区场景
app.load('/scenes/building').then((scene) => {console.log('场景加载完成');
});
场景生命周期:
app.on('load', function(ev) {// 场景加载完成
});app.on('update', function(ev) {// 每帧更新
});app.on('destroy', function(ev) {// 场景销毁
});
2.3 对象操作基础
创建与操作3D对象:
// 创建立方体
const box = app.create({type: 'Box',name: 'myBox',position: [0, 5, 0],size: [2, 2, 2],style: {color: '#FF0000',opacity: 0.8}
});// 对象变换
box.position = [10, 0, 5]; // 设置位置
box.scale = [1.5, 1.5, 1.5]; // 缩放
box.rotation = [0, 45, 0]; // 旋转(欧拉角)// 动画移动
box.moveTo([15, 5, 10], {time: 2000, // 毫秒easing: 'Quadratic.InOut'
});
对象查询:
// 通过名称查询
const obj = app.query('myBox')[0];// 通过类型查询
const lights = app.query(/Light/);// 通过条件查询
const bigObjects = app.query({type: 'Mesh',condition: 'object.scale.x > 1.5'
});
第三章 基础开发实战
3.1 第一个ThingJS应用
完整示例:智慧园区监控:
// 初始化应用
const app = new THING.App({background: '#F0F0F0',skyBox: 'SkyBox1'
});// 加载园区场景
app.load('/scenes/smart-park').then((scene) => {// 创建监控摄像头const camera = app.create({type: 'Camera',name: 'surveillance-cam',position: [50, 20, 0],target: [0, 0, 0]});// 添加设备标签camera.addComponent({type: 'Tag',text: '监控点#01',style: {color: '#FFFFFF',backgroundColor: '#3366FF'}});// 点击事件camera.on('click', (ev) => {app.camera.flyTo({target: camera,time: 1000,complete: function() {showCameraFeed(camera);}});});
});function showCameraFeed(camera) {// 显示监控画面逻辑const panel = new THING.widget.Panel({title: '实时监控',width: '300px',height: '200px'});panel.addString('摄像头ID', camera.name).captionStyle({color: '#333'});// 模拟视频流const video = document.createElement('video');video.src = '/assets/videos/sample.mp4';video.autoplay = true;panel.addDOM(video);
}
3.2 事件系统详解
事件类型:
- 鼠标事件:click, dblclick, mouseenter, mouseleave
- 触摸事件:touchstart, touchmove, touchend
- 对象生命周期:create, destroy, show, hide
- 自定义事件:可任意定义和触发
事件绑定与解绑:
// 绑定事件
obj.on('click', function(ev) {console.log('对象被点击', ev.object);
});// 一次性事件
obj.once('click', function(ev) {console.log('只会触发一次');
});// 事件解绑
const handler = function(ev) { /*...*/ };
obj.on('click', handler);
obj.off('click', handler);// 触发自定义事件
obj.trigger('alarm', {level: 'high',message: '温度过高!'
});
事件冒泡与拦截:
// 事件冒泡示例
parent.on('click', function(ev) {console.log('父对象收到事件', ev.target);
});child.on('click', function(ev) {console.log('子对象事件');ev.stopPropagation(); // 阻止冒泡
});// 事件拦截
app.on('click', function(ev) {if (shouldIgnore(ev)) {ev.preventDefault(); // 阻止默认行为}
});
3.3 基础动画实现
变换动画:
// 移动动画
obj.moveTo([x, y, z], {time: 1000, // 持续时间(ms)easing: 'Linear', // 缓动函数complete: function() {console.log('移动完成');}
});// 旋转动画
obj.rotateTo([x, y, z], {time: 2000,easing: 'Elastic.Out'
});// 缩放动画
obj.scaleTo([x, y, z], {time: 500
});
关键帧动画:
// 创建动画剪辑
const clip = new THING.AnimationClip({name: 'moveAndRotate',duration: 3000,tracks: [{type: 'position',keys: [{ time: 0, value: [0, 0, 0] },{ time: 1000, value: [10, 0, 0] },{ time: 3000, value: [10, 5, 10] }]},{type: 'rotation',keys: [{ time: 0, value: [0, 0, 0] },{ time: 3000, value: [0, 360, 0] }]}]
});// 播放动画
const mixer = new THING.AnimationMixer(obj);
const action = mixer.clipAction(clip);
action.play();
第二部分:ThingJS中级开发
第四章 场景设计与优化
4.1 复杂场景构建
分层加载策略:
// 分步加载大型场景
async function loadLargeScene() {// 1. 先加载基础结构await app.load('/scenes/base-structure');// 2. 加载建筑外观await app.load('/scenes/buildings-exterior');// 3. 加载室内场景(按需)app.on('click', '.building', (ev) => {ev.object.load('/scenes/interior/' + ev.object.name);});// 4. 最后加载动态元素loadDynamicElements();
}
场景组织技巧:
// 使用空对象作为容器
const floor1 = app.create({type: 'Object3D',name: 'floor1-container'
});// 将相关对象添加到容器
const desk1 = createDesk();
const chair1 = createChair();
floor1.add(desk1);
floor1.add(chair1);// 整体操作
floor1.position = [0, 3, 0]; // 移动整个楼层
4.2 性能优化策略
渲染性能优化:
- LOD(层级细节):
app.create({type: 'LOD',levels: [{ distance: 0, object: highDetailModel },{ distance: 50, object: mediumDetailModel },{ distance: 100, object: lowDetailModel }]
});
- 视锥裁剪:
// 在thingjs.config.js中配置
module.exports = {renderer: {frustumCulling: true, // 启用视锥裁剪maxRenderDistance: 500 // 最大渲染距离}
};
内存优化:
// 对象池管理
const objectPool = {desks: [],init(count) {for (let i = 0; i < count; i++) {this.desks.push(createDesk());this.desks[i].visible = false;}},getDesk() {const desk = this.desks.find(d => !d.visible);if (desk) {desk.visible = true;return desk;}return createDesk();}
};
第五章 高级交互实现
5.1 复杂事件处理
手势识别:
let touchStartTime;
let startPosition;obj.on('touchstart', (ev) => {touchStartTime = Date.now();startPosition = obj.position.clone();
});obj.on('touchmove', (ev) => {// 计算移动距离const delta = ev.deltaPosition;obj.position = [startPosition[0] + delta[0],startPosition[1],startPosition[2] + delta[1]];
});obj.on('touchend', (ev) => {// 判断快速滑动if (Date.now() - touchStartTime < 300) {const speed = ev.speed;// 添加惯性移动效果addInertiaMovement(speed);}
});
射线检测:
app.on('click', (ev) => {const rayCaster = new THING.Raycaster();const ray = rayCaster.setFromCamera(ev.screenPosition, app.camera);const intersects = rayCaster.intersectObjects(scene.children);if (intersects.length > 0) {console.log('击中的对象:', intersects[0].object);}
});
5.2 UI系统集成
原生UI组件:
// 创建控制面板
const panel = new THING.widget.Panel({title: '设备控制',width: '300px',height: 'auto',position: [20, 20]
});// 添加控件
panel.addBoolean('开启照明', false).onChange((value) => {toggleLights(value);
});panel.addSlider('温度调节', 22, 16, 30, 1).onChange((value) => {setTemperature(value);
});// 自定义HTML内容
panel.addHTML('<div class="alert">警告区域</div>');
与外部UI框架集成:
// Vue集成示例
const vueApp = new Vue({el: '#vue-ui-container',data: {deviceStatus: {}},methods: {handleControl(command) {// 调用ThingJS接口app.query(command.target).forEach(obj => {obj[command.method](...command.args);});}}
});// ThingJS事件触发Vue更新
app.on('deviceUpdate', (ev) => {vueApp.deviceStatus = ev.data;
});
第六章 数据可视化
6.1 数据驱动场景
数据绑定示例:
// 模拟设备数据
const devices = [{ id: 'device1', type: 'sensor', position: [10, 2, 5], value: 25.6 },{ id: 'device2', type: 'camera', position: [15, 3, -8], status: 'online' }
];// 数据绑定到3D对象
function bindDataToObjects() {devices.forEach(device => {const obj = app.create({type: device.type === 'sensor' ? 'Sphere' : 'Camera',name: device.id,position: device.position,size: [1, 1, 1]});// 存储原始数据obj.userData = device;// 根据数据更新状态updateObjectByData(obj);});
}// 数据更新处理
function onDataUpdate(newData) {const obj = app.query(newData.id)[0];if (obj) {Object.assign(obj.userData, newData);updateObjectByData(obj);}
}function updateObjectByData(obj) {const data = obj.userData;if (data.type === 'sensor') {// 根据值改变颜色const color = data.value > 30 ? '#FF0000' : '#00FF00';obj.style.color = color;// 更新标签obj.getComponent('Tag').text = `${data.value}°C`;}
}
6.2 高级可视化技术
热力图实现:
function createHeatmap(points, options = {}) {const { radius = 10, max = 100 } = options;const geometry = new THING.HeatmapGeometry({points: points.map(p => ({position: p.position,intensity: p.value / max})),radius});const material = new THING.HeatmapMaterial({gradient: {0.0: '#0000FF',0.5: '#00FF00',1.0: '#FF0000'}});return new THING.Mesh(geometry, material);
}// 使用示例
const sensorData = [{ position: [0, 0, 0], value: 30 },{ position: [5, 0, 3], value: 45 },// 更多数据点...
];const heatmap = createHeatmap(sensorData, { radius: 15 });
app.scene.add(heatmap);
动态路径可视化:
class DynamicPath {constructor(points, options = {}) {this.options = {width: 0.5,color: '#00FFFF',dash: [1, 0.5],speed: 1,...options};this.line = createLine(points);this.animateFlow();}createLine(points) {const geometry = new THING.BufferGeometry().setFromPoints(points);const material = new THING.LineDashedMaterial({color: this.options.color,linewidth: this.options.width,dashSize: this.options.dash[0],gapSize: this.options.dash[1]});return new THING.Line(geometry, material);}animateFlow() {let offset = 0;app.on('update', () => {offset += 0.01 * this.options.speed;this.line.material.dashOffset = -offset;});}
}
第三部分:ThingJS高级精通
第七章 自定义扩展开发
7.1 自定义组件开发
组件开发规范:
// 温度传感器组件
THING.Component.register('TemperatureSensor', {// 组件属性properties: {warningThreshold: 30,criticalThreshold: 40,unit: '°C'},// 生命周期onAttach: function() {// 组件附加到对象时调用this.object.style.color = '#00FF00';this.label = this.object.addComponent('Tag', {text: this.getDisplayText()});// 定时更新this.timer = setInterval(() => this.updateReading(), 5000);},onDetach: function() {// 组件移除时清理clearInterval(this.timer);this.object.removeComponent(this.label);},// 自定义方法updateReading: function() {// 模拟数据更新const newValue = 25 + Math.random() * 20;this.object.userData.temperature = newValue;// 更新显示this.label.text = this.getDisplayText();// 触发事件if (newValue > this.warningThreshold) {this.object.trigger('temperatureWarning', {value: newValue,status: newValue > this.criticalThreshold ? 'critical' : 'warning'});}},getDisplayText: function() {return `${this.object.userData.temperature.toFixed(1)}${this.unit}`;}
});// 使用组件
const sensor = app.create({ type: 'Sphere' });
sensor.addComponent('TemperatureSensor', {warningThreshold: 28,criticalThreshold: 35
});
7.2 着色器开发
自定义材质示例:
// 创建自定义着色器材质
const customShader = {uniforms: {time: { value: 0 },mainColor: { value: new THING.Color(0x00ff00) },waveSpeed: { value: 1.0 }},vertexShader: `varying vec2 vUv;void main() {vUv = uv;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);}`,fragmentShader: `uniform float time;uniform vec3 mainColor;uniform float waveSpeed;varying vec2 vUv;void main() {float wave = sin(vUv.x * 10.0 + time * waveSpeed) * 0.5 + 0.5;vec3 color = mix(mainColor, vec3(1.0), wave * 0.3);gl_FragColor = vec4(color, 1.0);}`
};// 使用自定义材质
const material = new THING.ShaderMaterial(customShader);
const mesh = new THING.Mesh(new THING.BoxGeometry(), material);// 更新uniforms
app.on('update', () => {material.uniforms.time.value += 0.01;
});
第八章 项目架构与工程化
8.1 大型项目组织
模块化架构:
src/
├── core/ # 核心模块
│ ├── app.js # 应用初始化
│ ├── scene-manager.js # 场景管理
│ └── event-bus.js # 全局事件总线
├── modules/ # 功能模块
│ ├── equipment/ # 设备管理
│ ├── monitoring/ # 监控系统
│ └── analytics/ # 分析模块
├── assets/ # 资源管理
│ ├── models/ # 3D模型
│ ├── textures/ # 纹理贴图
│ └── configs/ # 配置文件
└── utils/ # 工具函数
状态管理实现:
// 基于事件总线的状态管理
class StateManager {constructor() {this.state = {devices: {},alarms: [],viewMode: 'default'};this.eventBus = new THING.EventEmitter();}setState(path, value) {const parts = path.split('.');let current = this.state;for (let i = 0; i < parts.length - 1; i++) {current = current[parts[i]];}current[parts[parts.length - 1]] = value;this.eventBus.emit('stateChange', { path, value });}subscribe(path, callback) {this.eventBus.on('stateChange', ({ path: changedPath, value }) => {if (changedPath.startsWith(path)) {callback(this.getState(path));}});}getState(path) {return path.split('.').reduce((obj, key) => obj[key], this.state);}
}// 使用示例
const state = new StateManager();
state.setState('viewMode', 'expert');
state.subscribe('devices', (devices) => {updateDeviceVisualization(devices);
});
8.2 性能分析与调优
性能分析工具:
class PerformanceMonitor {constructor() {this.stats = {fps: 0,renderTime: 0,objectCount: 0};this.frames = 0;this.lastTime = performance.now();app.on('update', this.update.bind(this));}update() {this.frames++;const now = performance.now();// 每秒计算一次FPSif (now >= this.lastTime + 1000) {this.stats.fps = Math.round((this.frames * 1000) / (now - this.lastTime));this.frames = 0;this.lastTime = now;// 收集其他指标this.stats.objectCount = app.scene.children.length;this.stats.renderTime = app.renderer.info.render.time;console.table(this.stats);}}startProfiling(name) {console.time(name);}endProfiling(name) {console.timeEnd(name);}
}// 使用示例
const monitor = new PerformanceMonitor();
monitor.startProfiling('SceneLoad');
app.load('/scenes/large-scene').then(() => {monitor.endProfiling('SceneLoad');
});
第九章 实战项目:智慧园区综合管理系统
9.1 项目需求分析
核心功能需求:
- 三维场景展示:完整呈现园区建筑、设施和设备的3D模型
- 设备监控:实时显示IoT设备状态和数据(温湿度、能耗等)
- 告警管理:可视化呈现设备告警及定位
- 人员管理:展示人员位置和移动轨迹
- 数据分析:多维度的数据统计和可视化
技术指标:
- 支持同时展示1000+设备对象
- 数据更新延迟<1秒
- 主流浏览器60FPS流畅运行
- 场景加载时间<5秒(首次)
9.2 系统实现
架构设计:
[前端]├── ThingJS 3D引擎├── Vue.js 管理后台└── ECharts 数据可视化[后端]├── Node.js API网关├── Kafka 消息队列└── 时序数据库
核心实现代码:
// 主应用入口
class SmartCampusApp {constructor() {this.app = new THING.App({background: '#F5F5F5',skyBox: 'SkyBox2'});this.initModules();this.setupEventHandlers();}initModules() {this.sceneManager = new SceneManager(this.app);this.deviceManager = new DeviceManager(this.app);this.alarmSystem = new AlarmSystem(this.app);this.dataAnalytics = new DataAnalytics(this.app);}setupEventHandlers() {// 设备选择事件this.app.on('click', '.device', (ev) => {this.deviceManager.showDevicePanel(ev.object);});// 告警处理this.alarmSystem.on('newAlarm', (alarm) => {this.sceneManager.highlightObject(alarm.deviceId);this.showAlarmNotification(alarm);});}
}// 设备管理模块
class DeviceManager {constructor(app) {this.app = app;this.devices = new Map();// 从API加载设备数据this.loadDevices();}async loadDevices() {const response = await fetch('/api/devices');const devices = await response.json();devices.forEach(device => {const obj = this.createDeviceObject(device);this.devices.set(device.id, obj);});}createDeviceObject(device) {const obj = this.app.create({type: this.getDeviceType(device),name: device.id,position: device.position,userData: device});// 添加状态指示器obj.addComponent('StatusIndicator', {getStatus: () => device.status});return obj;}
}
第四部分:扩展与未来
第十章 ThingJS高级主题
10.1 跨平台开发
移动端适配策略:
// 响应式设计
function setupResponsive() {// 根据屏幕尺寸调整UIconst updateUI = () => {const isMobile = window.innerWidth < 768;// 调整相机位置app.camera.position = isMobile ? [0, 50, 100] : [0, 30, 70];// 调整控制方式app.camera.controller.type = isMobile? 'Orbit': 'FirstPerson';// 调整UI尺寸panel.style.fontSize = isMobile ? '14px' : '16px';};window.addEventListener('resize', updateUI);updateUI();
}// 触摸优化
function optimizeForTouch() {// 增大点击区域app.query('.device').forEach(obj => {obj.userData.clickableArea = 1.5;});// 简化交互app.camera.controller.touchZoomSensitivity = 0.5;
}
10.2 与GIS系统集成
地理坐标转换:
class GISConverter {constructor(origin, scale = 1) {this.origin = origin; // 地理坐标系原点this.scale = scale; // 单位换算比例}// WGS84转场景坐标project(lng, lat) {// 简化的墨卡托投影const x = (lng - this.origin.lng) * this.scale;const y = (lat - this.origin.lat) * this.scale;return [x, 0, -y]; // Z轴取反}// 场景坐标转WGS84unproject(x, z) {const lng = x / this.scale + this.origin.lng;const lat = -z / this.scale + this.origin.lat;return { lng, lat };}
}// 使用示例
const converter = new GISConverter({ lng: 116.404, lat: 39.915 }, // 天安门坐标1000 // 1度=1000单位
);const scenePos = converter.project(116.408, 39.916);
const obj = app.create({type: 'Flag',position: scenePos
});
第十一章 最佳实践与常见问题
11.1 性能优化清单
关键优化策略:
-
资源优化:
- 使用压缩纹理(.ktx2格式)
- 模型面数控制在5万面以内
- 使用Draco压缩的GLB模型
-
渲染优化:
// thingjs.config.js module.exports = {renderer: {antialias: true,shadowMap: {enabled: true,type: 'PCFSoft' // 柔和阴影},precision: 'mediump' // 移动端使用} };
-
内存管理:
// 释放不再使用的资源 function cleanup() {// 销毁对象obj.destroy();// 释放纹理texture.dispose();// 清理几何体geometry.dispose(); }
11.2 常见问题解决方案
典型问题与解决:
-
场景加载慢:
- 使用
THING.LoadingManager
显示进度 - 实现分块加载
- 预加载关键资源
- 使用
-
内存泄漏:
// 错误示例(会导致内存泄漏) app.on('update', function() {// 频繁创建对象const temp = new THING.Object3D(); });// 正确做法 const reusableObjects = []; function getTempObject() {return reusableObjects.pop() || new THING.Object3D(); }
-
点击事件不触发:
- 检查对象
visible
和pickable
属性 - 确认没有其他对象遮挡
- 检查事件冒泡是否被阻止
- 检查对象