Three.js中文网 Three.js中文网
首页
免费视频
系统课 (opens new window)
  • Three.js基础课程
  • Vue3+Threejs 3D可视化
  • Threejs进阶课程
  • 展厅3D预览漫游
  • Threejs Shader
  • Blender建模基础
  • Three.js基础课程(旧版本) (opens new window)
  • 文章
WebGPU教程
  • WebGL教程
  • WebGL教程(旧版本) (opens new window)
3D案例
  • 本站部署(打开快) (opens new window)
  • 原英文官网文档 (opens new window)
首页
免费视频
系统课 (opens new window)
  • Three.js基础课程
  • Vue3+Threejs 3D可视化
  • Threejs进阶课程
  • 展厅3D预览漫游
  • Threejs Shader
  • Blender建模基础
  • Three.js基础课程(旧版本) (opens new window)
  • 文章
WebGPU教程
  • WebGL教程
  • WebGL教程(旧版本) (opens new window)
3D案例
  • 本站部署(打开快) (opens new window)
  • 原英文官网文档 (opens new window)
Web3D系统课程视频
  • 0.学前说明

  • 1.Three.js快速入门

  • 2.几何体BufferGeometry

  • 3.模型对象、材质

  • 4.层级模型

  • 5.顶点UV坐标、纹理贴图

  • 6.加载外部三维模型(gltf)

  • 7.PBR材质与纹理贴图

  • 8.渲染器和前端UI界面

  • 9.生成曲线、几何体

  • 10.相机基础

  • 11.光源和阴影

  • 12.精灵模型Sprite

  • 13.后处理EffectComposer

  • 14.射线拾取模型

  • 15.场景标注标签信息

    • 1. CSS2DRenderer(HTML标签)
    • 2. HTML标签遮挡Canvas画布事件
    • 3. Canvas尺寸变化(HTML标签)
    • 4. 标签位置不同设置方式
    • 5. 标签位置(标注工厂设备)
    • 6. 标签指示线或箭头指向标注点
    • 7. 鼠标选中模型弹出标签(工厂)
      • 8. 单击按钮关闭HTML标签
      • 9. CSS3DRenderer渲染HTML标签
      • 10. CSS3批量标注多个标签
      • 11. 精灵模型Sprite作为标签
      • 12. Sprite标签(Canvas作为贴图)
    • 16.关键帧动画

    • 17.动画库tween.js

    • Three.js教程
    • 15.场景标注标签信息
    郭隆邦
    2023-03-13
    目录

    7. 鼠标选中模型弹出标签(工厂)

    # 鼠标选中模型弹出标签(工厂案例)

    射线、标签等知识点都学习过,你可以把本节课作为练习题,实现鼠标点击模型,弹出标签的功能。

    # 添加HTML元素标签,并隐藏

    引入标签的HTML、CSS代码,在射线拾取模型对象之前注意先隐藏display: none;。

    <div id="tag" style="display: none;">
    

    # HTML元素转化为CSS2模型对象

    // 引入CSS2模型对象CSS2DObject
    import {
        CSS2DObject
    } from 'three/addons/renderers/CSS2DRenderer.js';
    const div = document.getElementById('tag');
    div.style.top = '-161px'; //指示线端点和标注点重合
    // HTML元素转化为threejs的CSS2模型对象
    const tag = new CSS2DObject(div);
    export default tag;
    

    # 设置CSS2渲染器代码

    // 引入CSS2渲染器CSS2DRenderer
    import {CSS2DRenderer} from 'three/addons/renderers/CSS2DRenderer.js';
    
    // 创建一个CSS2渲染器CSS2DRenderer
    const css2Renderer = new CSS2DRenderer();
    css2Renderer.setSize(width, height);
    // HTML标签<div id="tag"></div>外面父元素叠加到canvas画布上且重合
    css2Renderer.domElement.style.position = 'absolute';
    css2Renderer.domElement.style.top = '0px';
    //设置.pointerEvents=none,解决HTML元素标签对threejs canvas画布鼠标事件的遮挡
    css2Renderer.domElement.style.pointerEvents = 'none';
    document.body.appendChild(css2Renderer.domElement);
    
    // 渲染循环
    function render() {
        css2Renderer.render(scene, camera);
        // ...
        requestAnimationFrame(render);
    }
    

    # 在射线代码基础上,添加标签代码

    当发生鼠标事件,如果射线拾取到模型对象,就把标签做为选中模型的子对象,或作为选中模型对应标注点空对象的子对象。

    前面说过,如果你想标注工厂中模型,CSS2模型对象有两种定位方式,下面两种定位模型位置方法任选其一即可。

    需要标注的模型,把局部坐标系坐标原点设置在需要标注的位置

    if (intersects.length > 0) {
        // 通过.ancestors属性判断那个模型对象被选中了
        outlinePass.selectedObjects = [intersects[0].object.ancestors];
        //tag会标注在intersects[0].object.ancestors模型的局部坐标系原点位置
        intersects[0].object.ancestors.add(tag);
    }
    

    工厂模型添加一个空对象,用来标记需要标注的位置。

    标注点对应空对象命名规则和代码规则息息相关,模型中两个设备的名字是设备A、设备B,对应的标注点空对象命名分别为设备A标注、设备B标注。

    if (intersects.length > 0) {
        // 通过.ancestors属性判断那个模型对象被选中了
        outlinePass.selectedObjects = [intersects[0].object.ancestors];
        // 获取模型对象对应的标注点
        // console.log('intersects[0].object.ancestors.name',intersects[0].object.ancestors.name);
        const obj = model.getObjectByName(intersects[0].object.ancestors.name+'标注');
        //tag会标注在空对象obj对应的位置
        obj.add(tag);
    }
    

    # 没有选中模型,不显示标签和发光描边

    在射线鼠标事件函数外面声明一个变量chooseObj来表示,此时是否有模型处于选中状态,如果没有,就把标签和发光描边取消。

    let chooseObj = null;
    addEventListener('click', function (event) {
        // ...射线拾取的代码
        // 射线交叉计算拾取模型
        const intersects = raycaster.intersectObjects(cunchu.children);
        if (intersects.length > 0) {
            // 通过.ancestors属性判断那个模型对象被选中了
            outlinePass.selectedObjects = [intersects[0].object.ancestors];
            //tag会标注在intersects[0].object.ancestors模型的局部坐标系原点位置
            intersects[0].object.ancestors.add(tag);
            chooseObj = intersects[0].object.ancestors;
        }else{
            if(chooseObj){//把原来选中模型对应的标签和发光描边隐藏
                outlinePass.selectedObjects = [];//无发光描边
                chooseObj.remove(tag);//从场景移除
            }
        }
    })
    

    # 修改标签内容

    可以根据选中的设备设置对应的标签内容数据,下面只是以设备名称为例进行演示,其它的标签数据,也可以类似修改。

    <span id="name">设备A</span>
    
    // 获取设备名称标签
    const span = document.getElementById('name');
    addEventListener('click', function (event) {
        // ...
        // ...
        // 射线交叉计算拾取模型
        const intersects = raycaster.intersectObjects(cunchu.children);
        if (intersects.length > 0) {
            span.innerHTML = intersects[0].object.ancestors.name;//修改标签数据
        }
    })
    
    6. 标签指示线或箭头指向标注点
    8. 单击按钮关闭HTML标签

    ← 6. 标签指示线或箭头指向标注点 8. 单击按钮关闭HTML标签→

    Theme by Vdoing | Copyright © 2016-2025 豫ICP备16004767号-2
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式