three.js 给模型中添加图片标签或文字标签

实现效果
在这里插入图片描述

1、创建 CSS3DRenderer 作为承载 标签的容器

//创建CSS3DRenderer
   labelRenderer = new CSS3DRenderer();
   labelRenderer.setSize(window.innerWidth, window.innerHeight); // 设置渲染器尺寸
  labelRenderer.domElement.style.position = 'absolute'; // 设置渲染器样式
  labelRenderer.domElement.style.pointerEvents = 'none';
  labelRenderer.domElement.style.top = '0'; // 设置渲染器样式
document.getElementById('web-container')?.appendChild(labelRenderer.domElement)

2、给指定模型上创建标签

  if (child.isGroup && child.name.indexOf('LLJ') !== -1) {
             const LLJName = child.name.split('-')[1]
              if (child.name.split('-')[1] === '24092297') {
                   child.name='LLJ-24092297-神东天隆2'
              }
             if (flowMeterRealData.value[LLJName]?.display === 1) {
               if (flowMeterRealData.value[LLJName]?.alarmSign === 0) {

               if (flowMeterRealData.value[LLJName]?.locationId === 7) {
               const tag = createTagIcon(child);   //创建标签函数
               scene.add(tag);//添加到指定的场景里
               }



//创建标签元素
  function createTagIcon(obj: any) {
    const worldPosition = obj.getWorldPosition(new THREE.Vector3());
          const div = document.createElement("div");
    div.className = "workshop-text";

    if (obj.name.split('-')[2] === '洒水车1'||obj.name.split('-')[2] === '井下污水入口'||obj.name.split('-')[2] === '备用'||obj.name.split('-')[2] === '神东天隆1'||obj.name.split('-')[2] === '洗煤厂后1'||obj.name.split('-')[2] === '井下生产'||obj.name.split('-')[2] === '总表二'||obj.name.split('-')[2] === '总表四') {
      div.innerHTML = `<div class='LLJ'><span class='text'>${obj.name.split('-')[2]}</span><div class='pic pic1'></div></div>`;
             const pic=div.querySelector('.LLJ')
        // 添加点击事件 鼠标悬浮展示详细信息
pic?.addEventListener('mouseenter', function(event) {
     updateRackInfo(obj,event) //打开popover
});
pic?.addEventListener('mouseleave', function(event) {
     closeInfo() //关闭popover
});
          // <span>${obj.name}</span>
          // 创建CSS3DSprite
    const tag = new CSS3DSprite(div);
    tag.position.copy(worldPosition);  // 调整标签位置

         tag.position.y += 30;
      tag.name = 'TextLabel-' + obj.name

    return tag;
    }

3、给添加的 标签添加样式

<style scoped lang="scss">
:deep(.workshop-text) {
  .text{
     font-size: 0.2rem;
    color: #fff;
  text-align: center;
    line-height: 3px;
       transform: translateY(80px);
  }

.LLJ {
     .pic{
    margin:0 auto;
    height: 2.8vh;
    width:  1vh;
   background: url('@/assets/images/LLJ.png');
   background-size: 100% 100%;
  background-repeat: no-repeat;

   }
   .pic1{
     background: url('@/assets/images/LLJ-hight.png');
      background-size: 100%;
  background-repeat: no-repeat;
  height: 4vh;
   }
   </style>

}在这里插入代码片

three.js中,要实现鼠标移动到模型上显示文字标签,通常需要使用场景中的对象拾取机制,配合渲染文字标签的UI元素。这里有一些基本的步骤: 1. **监听鼠标事件**:首先需要为场景添加鼠标事件监听器,如`mousemove`事件,当鼠标移动到场景上时,根据鼠标的屏幕坐标找到最接近的场景中的对象。 2. **对象拾取**:使用射线投射(Raycasting)技术来检测鼠标位置下最接近的物体。射线从摄像机发射,穿过鼠标所在的屏幕位置,然后与场景中的对象进行相交检测。 3. **显示文字标签**:一旦检测到对象,可以在该对象附近渲染一个HTML元素,用来显示文字标签。可以通过创建一个div元素,并使用CSS样式来定位它在3D空间的正确位置。 4. **更新和隐藏标签**:当鼠标移动到其他位置时,需要更新射线投射的检测结果,并相应地更新标签的位置者隐藏标签。 下面是一个简单的代码示例,展示了如何结合上述步骤: ```javascript // 初始化场景、相机、渲染器等... // 监听鼠标移动事件 document.addEventListener('mousemove', onDocumentMouseMove, false); var mouse = new THREE.Vector2(); // 用于存储鼠标位置 function onDocumentMouseMove(event) { // 将鼠标位置转换为归一化的设备坐标 mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = - (event.clientY / window.innerHeight) * 2 + 1; // 使用射线投射检测最接近的对象 raycaster.setFromCamera(mouse, camera); var intersects = raycaster.intersectObjects(scene.children); if (intersects.length > 0) { // 如果有对象被选中,显示标签 showLabel(intersects[0].object); } else { // 如果没有对象被选中,隐藏标签 hideLabel(); } } function showLabel(selectedObject) { // 创建标签 var label = document.createElement('div'); label.style.position = 'absolute'; label.style.background = 'white'; label.style.border = '1px solid black'; label.style.padding = '5px'; label.style.zIndex = 100; document.body.appendChild(label); // 设置标签位置和内容 var labelPosition = new THREE.Vector3(); var projector = new THREE.Projector(); projector.projectVector(selectedObject.position, camera); label.style.left = (projector.projectVector(selectedObject.position, camera).x * window.innerWidth / 2) + 'px'; label.style.top = (projector.projectVector(selectedObject.position, camera).y * window.innerHeight / -2) + 'px'; label.textContent = '这是标签内容'; // 可以根据需要显示不同的内容 } function hideLabel() { // 隐藏标签 var label = document.getElementById('label'); if (label) { label.remove(); } } // 渲染循环中调用渲染器... ``` 上述代码提供了一个基本的框架,你可能需要根据实际的应用需求对`showLabel`函数进行更多的定制,比如动态设置标签的样式、位置者绑定更复杂的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值