vue 中使用threejs

时间:2022-07-22
本文章向大家介绍vue 中使用threejs ,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1、安装threejs  :npm install three --save

2、页面引入 :import * as THREE from "three";

如果使用到 OrbitControls 和 CSS3DRenderer import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; import { CSS3DRenderer,CSS3DObject } from "three/examples/jsm/renderers/CSS3DRenderer.js"; // 注意一定要引入CSS3DObjec

3、图片放在哪儿? 

在public下新建一个文件夹static 里面放入图片(如果图片放到src->assets图片文件夹中渲染时不显示图片)

4、在vue环境中渲染页面时明显比直接引入three.js方式卡

scene和camera等不要放在data里面,要在mounted时初始化,beforeDestroy时定时器清空

完整代码

<template>
  <div class="wrap">
    <div ref="container" id="container"></div>
  </div>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { CSS3DRenderer,CSS3DObject } from "three/examples/jsm/renderers/CSS3DRenderer.js";
export default {
  name: "ThreeTest",
  data() {
    return {
    
    };
  },
  mounted() {
    this.timer=null
    this.myReq=null
    this.container
    this.scene
    this.camera
    this.renderer
    this.labelRenderer
    this.controls
    //this.cube
    //this.scene
    //this.controls
    this.initRender();
    //this.initCamera();
    this.initScene();
    this.initModel();
    //this.initControls();
    this.animate();
    //this.getData()
    // window.onresize = this.onWindowResize;
  },
  methods: {
    getData(){
        // 循环获取数据
        setInterval(()=>{
         this.enterPressure = 70
         console.log(this.enterPressure)
       },1000)
    },
    initRender: function() {
      this.container = document.getElementById("container");
      this.camera = new THREE.PerspectiveCamera(
        70,
        this.container.clientWidth / this.container.clientHeight,
        1,
        1000
      );
      this.camera.position.z = 1;
      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);
      this.container.appendChild(this.renderer.domElement);

      this.labelRenderer = new CSS3DRenderer();
      this.labelRenderer.setSize(this.container.clientWidth, this.container.clientHeight);
      this.labelRenderer.domElement.style.position = "absolute";
      this.labelRenderer.domElement.style.top = 0;
      this.container.appendChild(this.labelRenderer.domElement);
      console.log(this.labelRenderer);
       //创建控件对象
      this.controls = new OrbitControls(this.camera, this.labelRenderer.domElement);
    },
    initScene() {
      this.scene = new THREE.Scene();  
    },
    initCamera() {
      this.camera = new THREE.PerspectiveCamera(
        70,
        this.container.clientWidth / this.container.clientHeight,
        1,
        1000
      );
      console.log(this.camera)
      this.camera.position.z = 1;
      // this.camera = new THREE.PerspectiveCamera(
      //   75,
      //   window.innerWidth / window.innerHeight,
      //   1,
      //   1000
      // );
      // console.log(this.camera);
      // this.camera.position.z = 1; //z设置小写会使图像变形小
      
    },

    initLight() {
      scene.add(new THREE.AmbientLight(0xffffff));
      this.light = new THREE.DirectionalLight(0xffffff);
      //light.position.set(1,1,1);
      this.light.position.set(0, 0, 50);
      scene.add(this.light);
    },
    initModel() {
      var texture1 = new THREE.TextureLoader().load("/static/posxx.jpg");
       console.log(texture1)
      var texture2 = new THREE.TextureLoader().load("/static/negxx.jpg");
      var texture3 = new THREE.TextureLoader().load("/static/posyy.jpg");
      var texture4 = new THREE.TextureLoader().load("/static/negyy.jpg");
      var texture5 = new THREE.TextureLoader().load("/static/tiaoyaxiang.jpg"); //前面与后面的图片反着放
      var texture6 = new THREE.TextureLoader().load("/static/negzz.jpg");

      var materialArr = [
        //纹理对象赋值给6个材质对象
        new THREE.MeshBasicMaterial({ map: texture1 }),
        new THREE.MeshBasicMaterial({ map: texture2 }),
        new THREE.MeshBasicMaterial({ map: texture3 }),
        new THREE.MeshBasicMaterial({ map: texture4 }),
        new THREE.MeshBasicMaterial({ map: texture5 }),
        new THREE.MeshBasicMaterial({ map: texture6 })
      ];
      var boxGeometry = new THREE.BoxGeometry(200, 200, 200, 100, 100, 100);
      boxGeometry.scale(1, 1, -1);
      let cube = new THREE.Mesh(boxGeometry, materialArr);
      //console.log(this.cube);
      scene.add(cube);
 
      //获取随机数
       function getRandomNum(elementId,max,min){
          var element =document.getElementById(elementId);
         	element.innerHTML = Math.round(Math.random()*(max-min) + min);
       }
       // 文字:
       var enterPressure = 0;
       var enterPressureDiv = document.createElement("div");
       enterPressureDiv.className ="label";
       enterPressureDiv.innerHTML = "<div class='pressure'>进口压力:<span class='text_Num' id='enter_text_Num'>"+enterPressure+"</span> kpa</div>"
       let enterPressureLabel = new CSS3DObject(enterPressureDiv);
       enterPressureLabel.position.set(-150,-50,-380);
       scene.add(enterPressureLabel);


       // 获取数据
        this.timer = setTimeout(()=>{
         var element =document.getElementById("enter_text_Num");
         	element.innerHTML = Math.round(Math.random()*(70-60) + 60);
       },1000)

    },
    initControls() {
      //controls = new THREE.OrbitControls( camera, renderer.domElement );
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);

      // 如果使用animate方法时,将此函数删除

      //controls.addEventListener( 'change', render );

      // 使动画循环使用时阻尼或自转 意思是否有惯性

      this.controls.enableDamping = false;

      //动态阻尼系数 就是鼠标拖拽旋转灵敏度

      //controls.dampingFactor = 0.25;

      //是否可以缩放

      this.controls.enableZoom = false;

      //是否自动旋转

      this.controls.autoRotate = false;

      //设置相机距离原点的最远距离

      this.controls.minDistance = 1;

      //设置相机距离原点的最远距离

      this.controls.maxDistance = 10;

      //是否开启右键拖拽

      this.controls.enablePan = false;
    },
    render() {
      this.renderer.render(scene, this.camera);
      this.labelRenderer.render(scene, this.camera);
    },
    onWindowResize() {
      this.camera.aspect = window.innerWidth / window.innerHeight;

      this.camera.updateProjectionMatrix();

      this.render();

      this.renderer.setSize(window.innerWidth, window.innerHeight);
    },
    animate() {
      this.render();
      this.myReq = requestAnimationFrame(this.animate);
    }
  },
  beforeDestroy() {
    cancelAnimationFrame(this.myReq)
    clearInterval(this.timer);
    this.scene = null
    this.scene.dispose()
    this.camera = null
    this.renderer = null
    this.labelRenderer =null
    this.controls = null
    
  }
};
</script>
<style>
.wrap {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 100;
}

#container {
  height: 100%;
}
.label {
  margin-top: -20px;
  color: #fff;
  font-size: 12px;
  border: 1px solid #dbeca4;
  padding: 3px 5px;
  background: rgba(0, 0, 0, 0.6);
  min-width: 80px;
}
.pressure {
  width: 115px;
}
.text_Num {
  color: red;
  margin-right: 5px;
}
</style>