效果:
1.html部分(:id="`sign${v.uuid}`" 动态id名称)
<template>
<div class="container">
<div ref="canvasContainer" class="canvas-container"></div>
<div :id="`sign${v.uuid}`" style="position: absolute;" v-for="(v, idx) in labels" :key="idx">
<div class="sign" :uuid="v.uuid">
<div class="name">制冷循坏水系统</div>
<div class="data">数据: {{ v.uuid }}</div>
<div class="name">名称: {{ v.name }}</div>
</div>
</div>
</div>
</template>
2.css部分(div[id *="sign"]动态css)
<style lang="scss" scoped>
.canvas-container {
position: relative;
width: 100%;
height: 800px;
border: 1px solid #ccc;
}
div[id *="sign"] {
width: 250px;
height: 100px;
background: rgba(0, 0, 0, .65);
.sign {
div {
color: #fff;
text-align: left;
padding: 0 5px;
}
}
}
</style>
3.js部分
(1)在methods中定义生成方法
labelTag(camera, targePosition, targetId, innerHTML, webGLdom) {
const { width, height } = webGLdom.getBoundingClientRect();
let worldVector = new THREE.Vector3(targePosition.x, targePosition.y, targePosition.z);
let vector = worldVector.project(camera);
let halfWidth = width / 2,
halfHeight = height / 2;
let x = Math.round(vector.x * halfWidth + halfWidth);
let y = Math.round(-vector.y * halfHeight + halfHeight);
/**
* 更新立方体元素位置
*/
let div = document.getElementById(targetId);
if (div&&div.style) {
div.style.left = x + 'px';
div.style.top = y + 'px';
}
}
(2)在animate方法中查询到具体的要显示tip的对象后调用上面的labelTag方法 (在这里调用就是为了tip和元素的位置一起变化)
animate() {
// tag初始化创建
this.$nextTick(() => {
//this.model = gltf.scene 这里是模型加载时候的所保存的gltf.scene对象
this.container = document.querySelector('.canvas-container');
this.labels = [this.model.getObjectByName('Box056'),this.model.getObjectByName('Box057'),this.model.getObjectByName('Box058'),this.model.getObjectByName('Box007')]
this.labels.forEach((val, idx) => {
const { x, y, z } = val.position;
this.labelTag(this.camera, { x, y, z }, `sign${val.uuid}`, val, this.container)
})
})
},
可以根据某个标识去批量加载出对应的tip
// tag初始化创建
this.labels = this.model.children.filter(v => v.type == 'Mesh')
this.$nextTick(() => {
this.model.children.forEach((val, idx) => {
if (val.type == 'Mesh') {
const { x, y, z } = val.position;
this.labelTag(this.camera, { x, y, z }, `sign${val.uuid}`, val, this.container)
}
})
})