• threejs CSS3DRenderer添加标签并设置朝向摄像机


    一.由于CSS3DRenderer 是附加组件,必须显式导入
    import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
    
    • 1
    二.CSS3DRenderer特点

    CSS3D不面向摄像机,会跟随场景缩放,不被模型遮挡,通过DOM事件点击
    但是由于项目要求label时刻面向摄像机,因此需要在每次刷新更新lookat朝向,可参考以下代码

    function updateLabel(nodeName){
    	// nodeName添加标签时记得赋予name属性
        const node = scene.getObjectByName(nodeName);// 返回一个匹配该名字的子对象
        const cameraPosition = camera.position.clone();
        node?.lookAt(cameraPosition);
    }
    // 循环渲染
    function animate() {
        requestAnimationFrame(animate);
        renderer_3d.render(scene, camera);
        updateLabel(nodeName) // label朝向camera
    }
    animate()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    三.完整代码

    从项目中抽出来的,可能有缺漏,欢迎大家补充

    import * as THREE from 'three';
    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
    import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
    
    // 创建场景
    const scene = new THREE.Scene();
    
    // 创建CSS3DRenderer渲染器, 相机, 控制器
    const renderer_3d = new CSS3DRenderer();
    renderer_3d.setSize(window.innerWidth, window.innerHeight);
    renderer_3d.domElement.style.position = 'absolute';
    renderer_3d.domElement.style.top = '0px';
    //DOM添加renderer : 我是使用umi写的containerRef.current是我的DOM容器(视个人项目情况而定)
    containerRef.current.appendChild(renderer_3d.domElement);  
    
    
    // 创建相机
    const camera = new new THREE.PerspectiveCamera(100, window.innerWidth / window.innerHeight, 0.1,1000);
    camera.lookAt(0, 0, 0)
    camera.updateProjectionMatrix(); 
    
    
    // 创建控制器
    const controls_3d = new OrbitControls(camera, renderer_3d.domElement);
    controls3.enableDamping = true; // 是否有惯性
    controls3.enableZoom = true; // 是否可以缩放
    
    
    //添加标签文字
    const tag = create3DTag({ name: '教学楼' });
    
    //创建CSS3DObject标签元素
    function create3DTag(obj) {
        const element = document.createElement('div');
        element.className = 'tag';
        element.innerText = obj.name;
        const object = new CSS3DObject(element);
        element.style.pointerEvents = 'none';//避免HTML标签遮挡三维场景的鼠标事件
        object.name='tag_3d'  // 注:name不可缺
        object.visible = true;
        object.scale.set(2,2,2);//缩放比例
        object.position.set(10, 20, 0);//指定摆放位置
        return object;
    }
    
    
    // 更新CSS3D朝向
    function updateLabel(nodeName){
        const node = scene.getObjectByName(nodeName);// 返回一个匹配该名字的子对象
        const cameraPosition = camera.position.clone();
        node?.lookAt(cameraPosition);
    }
    
    // 循环渲染
    function animate() {
        requestAnimationFrame(animate);
        renderer_3d.render(scene, camera);
        updateLabel(nodeName) // label朝向camera
    }
    animate()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
  • 相关阅读:
    深信服AC跨三层取mac,绑定ip/mac
    Ant vue中表单验证(动态校验、部分校验)
    MySQL 8.0.28 忘记密码,重置密码
    【蓝桥杯物联网赛项学习日志】Day4 关于USART/UART
    递归实现 输出全排列
    超级基础篇_疑惑实验
    108 使用Ajax请求获取PHP自制接口
    iOS_折叠展开 FoldTextView
    Docker 魔法解密:探索 UnionFS 与 OverlayFS
    帝国CMS后台登录显示空白解决方法汇总
  • 原文地址:https://blog.csdn.net/weixin_42674490/article/details/134244322