threejs之显示Label-CSS2DRenderer

2019-05-31 14:15:19 浏览数 (1)

一、如果我们在场景图上标识一些文字,有2种常用的方法

1、采用threeJs的精灵(Sprite),具体用法查看我另一篇博客https://cloud.tencent.com/developer/article/1418129

2、使用CSS2DRenderer

二、2种方法主要特征

精灵:文字是在canvas中画的,精灵的材质就是加载的带有文字的canvas。

CSS2DRenderer:渲染器是生成一个DIV容器,它的作用是能把HTML元素绑定到三维物体上,在DIV容器中各自的DOM元素分别封装到CSS2DObject的实例中,并在scene中增加。

相对于精灵CSS2DRenderer有更好的灵活性,可以更好的通过css控制样式,并且也更方便的进行页面的跳转(通过a元素)

三、CSS2DRenderer方法:

(1)getSize():返回包含宽度和长度的对象

(2)render ( scene : Scene, camera : Camera ) : null    // 用相机渲染场景

(3)setSize (width : Number, height : Number) : null   //设置渲染器的宽度和高度

四、实例

查看实例效果

完整代码

代码语言:javascript复制
<div class="canvasWrap" id="canvasWrap" style="margin-bottom:15px;"></div>
代码语言:javascript复制
    <script>
    var camera, scene, scene2, renderer, labelRenderer;
    var controls;
    var clock = new THREE.Clock();
    var textureLoader = new THREE.TextureLoader();
    var width, height;
    var earth, moon;

    init();
    animate();

    function init() {
        var EARTH_RADIUS = 1;
        var MOON_RADIUS = 0.27;
        var container = document.getElementById('canvasWrap')
        width = document.getElementById('canvasWrap').clientWidth;
        height = document.getElementById('canvasWrap').clientHeight;
        camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
        camera.position.set(10, 9, 8);
        console.log(camera)
        controls = new THREE.OrbitControls(camera);
        scene = new THREE.Scene();
        scene2 = new THREE.Scene();
        var dirLight = new THREE.DirectionalLight(0xffffff);
        dirLight.position.set(0, 0, 1);
        scene.add(dirLight);

        var axesHelper = new THREE.AxesHelper(5);
        scene.add(axesHelper);

        var earthGeometry = new THREE.SphereBufferGeometry(EARTH_RADIUS, 16, 16);
        var earthMaterial = new THREE.MeshPhongMaterial({
            specular: 0x333333, //材质的高光颜色。默认值是0x111111
            shininess: 5, //高亮的程度,越高的值越闪亮。默认值为30
            //颜色贴图,默认null.纹理贴图颜色由漫反射颜色.color调节
            map: textureLoader.load('../dist/textures/planets/earth_atmos_2048.jpg'),
            //镜面反射贴图值会影响镜面高光以及环境贴图对表面的影响程度。默认null
            specularMap: textureLoader.load('../dist/textures/planets/earth_specular_2048.jpg'),
            //用于创建法线贴图的纹理。RGB值会影响每个像素片段的曲面法线,并更改颜色照亮的方式。法线贴图不会改变曲面的实际形状,只会改变光照。
            normalMap: textureLoader.load('../dist/textures/planets/earth_normal_2048.jpg'),
            //法线贴图对材质的影响程度。典型范围是0-1 ,默认值是Vector2 设置(1,1)
            normalScale: new THREE.Vector2(0.85, 0.85)
        });
        earth = new THREE.Mesh(earthGeometry, earthMaterial)
        scene.add(earth);

        var moonGeometry = new THREE.SphereBufferGeometry(MOON_RADIUS, 16, 16);
        var moonMaterial = new THREE.MeshPhongMaterial({
            shininess: 5,
            map: textureLoader.load("../dist/textures/planets/moon_1024.jpg")
        });
        moon = new THREE.Mesh(moonGeometry, moonMaterial);
        console.log(moon)
        scene.add(moon);

        //var earthDiv = '<div><a href="aboutMe.html">earth</a></div>' 用字符串写元素不行
        //earthDiv.style.marginTop = "-1em";
        earthDiv = document.getElementById("label1");
        earthDiv.style.display = "block"
        console.log(earthDiv)
        earthLabel = new THREE.CSS2DObject(earthDiv);
        earthLabel.position.set(0, EARTH_RADIUS, 0);
        earth.add(earthLabel);

        var moonDiv = document.createElement("div");
        moonDiv.className = "label";
        moonDiv.textContent = "Moon";
        //moonDiv.style.marginTop = "-1em";
        var moonLabel = new THREE.CSS2DObject(moonDiv);
        moonLabel.position.set(0, MOON_RADIUS, 0);
        moon.add(moonLabel);

        renderer = new THREE.WebGLRenderer();
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(width, height);
        container.appendChild(renderer.domElement);

        labelRenderer = new THREE.CSS2DRenderer();
        labelRenderer.setSize(width, height);
        labelRenderer.domElement.style.position = "absolute";
        labelRenderer.domElement.style.top = 0;
        container.appendChild(labelRenderer.domElement);

    }

    function animate() {
        requestAnimationFrame(animate);
        //获取自时钟启动后的秒数
        var elapsed = clock.getElapsedTime() / 3;
        moon.position.set(Math.sin(elapsed) * 5, 0, Math.cos(elapsed) * 5);
        renderer.render(scene, camera);
        labelRenderer.render(scene, camera)
    }
    </script>
代码语言:javascript复制
    .canvasWrap {
        position: relative;
        width: 100%;
        height: 500px;
        background: gray;
    }

    .label {
        margin-top: -20px;
        color: #fff;
        border: 1px solid #fff;
        padding: 3px 5px;
        background: rgba(0, 0, 0, 0.6)
    }

注意:标签中显示的HTML元素可以在页面中先写好并隐藏起来,运行js 的时候再获取此元素并显示,不能在js中直接用字符串的形式创建元素,否则会报错。

代码语言:txt复制
 (adsbygoogle = window.adsbygoogle || []).push({});

0 人点赞