• three.js 添加html内容、文本


    需求:

    1、在场景内添加html元素并动态更新

    2、html内容需跟随场景变化

    方案:

    有几种方案

    一、直接将文本P成为图片 然后在场景内加载 2D模型将该图片当作模型贴图处理

    二、将html内容通过canvas 然后再以模型的方式加载进场景(不做详细解释)

    1、创建

        getTextCanvas(text){ 
          // 创建贴图文字
            var width=512, height=256; 
            var canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
            var ctx = canvas.getContext('2d');
            ctx.fillStyle = '#008080';
            ctx.fillRect(0, 0, width, height);
            ctx.font = 50+'px " bold';
            ctx.fillStyle = '#FFFFFF';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            ctx.fillText(text, width/2,height/2); 
            return canvas;
        },

    2、加载

            var geometry = new THREE.PlaneGeometry(e.w, e.h, 30 );
            var material = new THREE.MeshBasicMaterial(
              {
                // map:new THREE.CanvasTexture(this.getTextCanvas(e.content)),  // canvas 画图方式
                map:new THREE.TextureLoader().load(`${this.GLOBAL.service}img/043img/btn/${e.content}.png`), 
                } );
            var introduce = new THREE.Mesh( geometry, material );
            introduce.name= "model introduce"
            // plane.location=i.location
            introduce.modeltype= 3 //
            introduce.position.set(x,y,z);
            introduce.lookAt(0,y,0)
            skyBox.add(introduce);

    三、用CSS2DObject进行处理

    1、增加渲染器 CSS2DRenderer  

    2、使用 three.js 的 CSS2DObject 模块 进行html内容转换 并绑定模型 

    官网案例  

    官网示例代码 

    一般需要这个功能的肯定都不是新手了,所以内容就不做介绍了,这里只需要关注几点

    1、增加渲染器(原有的渲染器不动,新增一个CSS2DRenderer渲染器 ):

      addhtml() {
          // 场景渲染器
    
          this.renderer = new THREE.WebGLRenderer();
          this.renderer.shadowMapEnabled = true;
          this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
          // this.renderer.gammaOutput = true;
          this.renderer.gammaFactor = 2.2;
          // this.renderer.setClearColor(new THREE.Color(0xcce0ff));
    
          this.renderer.setSize(window.innerWidth*0.95, window.innerHeight*0.95);
          document
            .getElementById("container")
            .appendChild(this.renderer.domElement);
          // window.addEventListener("resize", () => this.onWindowResize());
          
          this.labelRenderer = new CSS2DRenderer();  // 新增的渲染器
          this.labelRenderer.setSize(window.innerWidth*0.95, window.innerHeight*0.95);
          // this.labelRenderer.domElement.style.position = 'absolute';
          // this.labelRenderer.domElement.style.top = 0;
          this.labelRenderer.domElement.style="pointer-events: auto;position: absolute;top: 0px;"  // 处理新的渲染器
          document.getElementById("container").appendChild(this.labelRenderer.domElement);
       },
        animate() {
          // 渲染
          this.renderer.render(this.scene, this.camera);
          this.labelRenderer.render(this.scene, this.camera);// 加载新渲染器
          window.requestAnimationFrame(() => this.animate());
          TWEEN.update();
        },

    注意:官网示例只适应于全屏的情况 不全屏的情况请自行调整

    2、增加内容容器:

    <template>
      <div class="project">
        <div id="text" style="    position: relative; 30%;
        height: 100px;
        color: #fff;">
          {{modelnumber}}
        </div>
        <div id="container">
     
      </div>
    </template>

    3、绑定模型(创建模型什么的这里就不解释了):

        // 2D 文本
        // let laberDiv = document.createElement('div');//创建div容器
        let laberDiv = document.getElementById('text');//获取div容器
            // laberDiv.innerHTML=`
            // <div class="leftTip" style="">
            //    ${this.modelnumber}
            // </div>
            // `;
            laberDiv.style.marginTop = '-1em';
        let pointLabel = new CSS2DObject(laberDiv);   
        pointLabel.position.set(0,100,0);  // 相对模型的位置
        console.log(pointLabel)   
        skyBox.add(pointLabel); //绑定到模型

    也看到了,你也可以选择直接新建一个容器、但是我尝试的时候内容无法动态变化、如果你不需要动态变化也可以直接新建 

    找资料的时候看到一个问题(没有尝试)、创建的这个容器切换场景不会消失、需要注意处理、这个创建出来的不在模型列表内、而是在dom里面、所以遇到这个情况、请尝试直接处理dom

    效果:

    注:

    前面两种方式是直接在场景内加载一个模型、第三种方式是将元素绑定在模型上

  • 相关阅读:
    《构建之法》阅读笔记--2
    学习进度条--第九周
    团队冲刺第十天
    团队冲刺第十一天
    团队冲刺第九天
    团队冲刺第八天(4/29)
    团队冲刺第七天(4/28)
    团队冲刺第六天( 2016/4/27)
    第九章动手动脑
    第八章多态动手动脑
  • 原文地址:https://www.cnblogs.com/yc-c/p/13901454.html
Copyright © 2020-2023  润新知