信息提示框能够以较强的交互性、自由度为用户提供相应的提示信息。在三维场景中加入可交互的三维信息提示框对一个可视化项目来说尤为重要。一共有三个版本,推荐后两种实现方式,下面是对这方面的总结。
版本一(不推荐):
html:
<div class="floor-labels" ref="floor_18">
<div class="labels-line">
<img
src="../../assets/images/line.png"
style="width: 100%; height: 100%"
/>
</div>
<div class="labels-content">
<a
style="
display: table-cell;
text-align: center;
vertical-align: middle;
font-size: 0.2rem;
color: white;
"
@click="toNext(18)"
>18层</a // 可以给标签绑定一些监听事件
>
</div>
</div>
css:
//楼层标签样式
.floor-labels {
width: 120px;
height: 30px;
position: absolute;
z-index: 1;
display: flex;
.labels-line {
margin-top: 6px;
width: 32px;
height: 22px;
}
.labels-content {
width: 56px;
height: 27px;
border: 1px;
background: rgba(110, 114, 117, 0.6);
border-radius: 3px;
display: table;
cursor: pointer;
}
}
js:
this.controls.addEventListener("change", () => { // 当三维场景变化时触发
this.getFloorLabel();
});
this.getFloorLabel(); // 加载完模型的时候加载将dom标签渲染到三维场景中去
//楼层标签显示的位置
getFloorLabel() {
// WebGL相关
let worldVector = new THREE.Vector3(-26, 52, 0); //获取楼层位置的坐标
let standVector = worldVector.project(this.camera); // standVector是WebGL设备坐标
// WebGL标准设备坐标转屏幕坐标
const a = window.innerWidth / 2;
const b = window.innerHeight / 2;
this.x = Math.round(standVector.x * a + a);
this.y = Math.round(-standVector.y * b + b);
let div = this.$refs.floor_18; // 获取到div
div.style.left = this.x + "px";
div.style.top = this.y + "px";
// 还可以根据这个提示框的位置计算其它提示框
this.$refs.floor_xxx.style.left = this.x + "px";
this.$refs.floor_xxx.style.top = this.y + 60 + "px";
},
实现效果图如下:
版本二(CSS2DRenderer):
参考案例:three.js examples (threejs.org)
版本三(CSS3DRenderer):