需要:页面初始的时候会根据数据渲染一个模型,之后需要点击模型时在点击位置生成一个标签,该标签可以随模型进行缩放及旋转.
import { CSS3DRenderer,CSS3DObject } from "three/examples/jsm/renderers/CSS3DRenderer";
// 创建一个空的 Object3D 用于包装标签,解决跟着父模型旋转的问题
let labelContainer = new THREE.Object3D();
export default{
init(){
......
//在初始化renderer时需要再初始化一个3D渲染器
css3Renderer = new CSS3DRenderer();
css3Renderer.setSize(element.clientWidth, element.clientHeight)
css3Renderer.domElement.id = "tagContainer"
css3Renderer.domElement.style.position = "absolute"
css3Renderer.domElement.style.top = "0px"
css3Renderer.domElement.style.pointerEvents = "none";
element.appendChild(css3Renderer.domElement);
},
render() {
controls.update()
css3Renderer.render(scene, camera);
renderer.render(scene, camera);
},
//设置标绘文本框位置
handleSetPosition(positionObj){
// 获取场景中的对象
const myLabel = scene.getObjectByName('labelTag');
// 从labelContainer中移除CSS3DObject
if (myLabel) {
labelContainer.remove(myLabel);
}
//创建标签
const div = document.createElement("div");
const diseaseType = this.getDisType(positionObj.color)
//设置标签内容
div.innerHTML = ``
div.style.backgroundColor = "rgba(0,0,0,0.6)"
div.style.padding = "10px"
div.id = "tag"
const label = this.initLabel(div, positionObj);
label.position.set(positionObj.x, positionObj.y, positionObj.z);//标签位置调整
},
// 初始化label
initLabel(dom,positionObj) {
if(labelContainer.children && !labelContainer.children.length){
// 添加 labelContainer 到场景中,而不是直接添加 label3DObject
scene.add(labelContainer);
}
const label3DObject = new CSS3DObject(dom);
dom.style.pointerEvents = "none";
label3DObject.name = 'labelTag';
// 缩放标签
labelContainer.scale.set(0.2, 0.2, 0.2);
labelContainer.add(label3DObject);
let position = {
x:positionObj.x,
y:positionObj.y,
z:positionObj.z,
}
// 将标签放在模型的位置
label3DObject.position.copy(position);
//计算标签朝向相机的方向
const lookAtVector = new THREE.Vector3();
lookAtVector
.subVectors(camera.position, position)
.normalize();
//设置标签元素的朝向
label3DObject.lookAt(lookAtVector);
return label3DObject;
},
}