iotgateway/3d/3d.html

282 lines
6.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<title>3D</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="./css/main.css">
<style>
body {
background-color: #bfe3dd;
color: #000;
}
a {
color: #2983ff;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="../jquery.min.js"></script>
<script src="../mqtt.min.js"></script>
<script type="module">
import * as THREE from './lib/three.module.js';
import Stats from './lib/stats.module.js';
import { OrbitControls } from './lib/OrbitControls.js';
import { RoomEnvironment } from './lib/RoomEnvironment.js';
import { GLTFLoader } from './lib/GLTFLoader.js';
import { DRACOLoader } from './lib/DRACOLoader.js';
import { CSS3DObject, CSS3DRenderer } from './lib/CSS3DRenderer.js';
let W = window.innerWidth;
let H = window.innerHeight;
let mixer;
let labelArr = [];
//标签数据
let modelData = [{
id: 1,
cname: "Modbus设备",
ename: "modbus_01",
position: {
x: -0.5,
y: 0.6,
z: 1.55,
},
param: [{
name: "温度",
value: 123,
},
{
name: "湿度",
value: 123,
},
],
}
];
//定时更新数据
//setInterval(() => {
// modelData.forEach((item) => {
// if (item.id > 0) {
// item.param[0].value = parseInt(Math.random() * 30 + 150).toFixed(0);
// item.param[1].value = parseInt(Math.random() * 30 + 150).toFixed(0);
// }
// });
// updateData();
//}, 2000);
inimqttclient();
const clock = new THREE.Clock();
const container = document.getElementById('container');
const stats = new Stats();
container.appendChild(stats.dom);
const css3dRenderer = new CSS3DRenderer();
css3dRenderer.setSize(W, H);
css3dRenderer.domElement.style.position = 'absolute';
css3dRenderer.domElement.style.top = 0;
container.appendChild(css3dRenderer.domElement);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.outputEncoding = THREE.sRGBEncoding;
container.appendChild(renderer.domElement);
const pmremGenerator = new THREE.PMREMGenerator(renderer);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xbfe3dd);
scene.environment = pmremGenerator.fromScene(new RoomEnvironment(), 0.04).texture;
const camera = new THREE.PerspectiveCamera(40, W / H, .1, 10000);
camera.position.set(5, 2, 8);
const controls = new OrbitControls(camera, container);
controls.target.set(0, 0.5, 0);
controls.update();
controls.enablePan = false;
controls.enableDamping = true;
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('./lib/gltf/');
const loader = new GLTFLoader();
loader.setDRACOLoader(dracoLoader);
loader.load('./model/LittlestTokyo.glb', function (gltf) {
const model = gltf.scene;
model.position.set(1, 1, 0);
model.scale.set(0.01, 0.01, 0.01);
scene.add(model);
createLableArr();
mixer = new THREE.AnimationMixer(model);
mixer.clipAction(gltf.animations[0]).play();
animate();
}, undefined, function (e) {
console.error(e);
});
//创建标签
function createLableArr() {
let style = "color: #00CED1;cursor:pointer;font-size:30px;padding:5px 15px;"; //background:#43bafe;
modelData.forEach((item) => {
let label = createLabel(item.cname, style, item.param);
label.position.set(item.position.x, item.position.y, item.position.z);
let scale = 0.003;
label.scale.set(scale, scale, scale); //缩放比例
label.name = item.ename;
//label.visible = true;
scene.add(label);
labelArr.push(label);
const axesHelper = new THREE.AxesHelper(5);
label.add(axesHelper);
});
}
/**销毁模型*/
function destroyObject(object) {
if (!object) return;
object.traverse((item) => {
if (item.material) {
if (Array.isArray(item.material)) {
item.material.forEach(m => m.dispose());
} else {
item.material.dispose();
}
}
if (item.geometry) item.geometry.dispose();
item = null;
});
scene.remove(object);
object = null;
}
/**信息标注的生成*/
function createLabel(text, style, param) {
//创建CSS3D
let div_label = document.createElement("div");
div_label.className = "div-label";
let div_ul = document.createElement("ul");
let div_li = document.createElement("li");
style ? (div_li.style = style) : "";
div_li.textContent = `设备名称:${text}`;
div_ul.appendChild(div_li);
if (param.length) {
param.forEach((item) => {
let param_li = document.createElement("li");
style ? (param_li.style = style) : "";
param_li.textContent = `${item.name}:${item.value}`;
div_ul.appendChild(param_li);
});
}
div_label.appendChild(div_ul);
let label = new CSS3DObject(div_label);
return label;
}
//更新数据标签
function updateData() {
if (labelArr.length) {
labelArr.forEach(item => {
destroyObject(item);
});
createLableArr();
}
}
window.onresize = function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
};
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
mixer.update(delta);
controls.update();
//标签
// if (labelArr.length) {
// labelArr.forEach((item) => {
// if (item.visible) {
// item.quaternion.slerp(camera.quaternion, 1);
// }
// });
// }
stats.update();
renderer.render(scene, camera);
css3dRenderer.render(scene, camera);
}
function inimqttclient() {
var options = {
//mqtt客户端的id这里面应该还可以加上其他参数具体看官方文档
clientId: 'mqttjs3d_' + (Math.random() * 10000000).toString()
}
var client = mqtt.connect('ws://' + window.location.host + '/mqtt', options);
client.on('connect', function () {
client.subscribe('internal/v1/gateway/telemetry/+/+', function (err) {
if (!err) {
console.log("订阅成功!")
} else {
console.log(err)
}
})
})
client.on('message', function (topic, message) {
if (topic == 'internal/v1/gateway/telemetry/Modbus/temperature') {
var objmsg = $.parseJSON(message.toString());
modelData[0].param[0].value = objmsg.CookedValue;
updateData();
} else if (topic == 'internal/v1/gateway/telemetry/Modbus/humidity') {
var objmsg = $.parseJSON(message.toString());
modelData[0].param[1].value = objmsg.CookedValue;
updateData();
}
})
}
</script>
</body>
</html>