VUE使用three.js模型縮放卡頓問題

VUE使用three.js模型縮放卡頓問題

最近將之前開發的three.js程序集成到vue項目中,發現模型的旋轉可縮放變得比較卡頓,網上搜集資料發現是將scene與controls放在vue data中的緣故,解決方法是將其定義在vue之外,然後在method中修改,完整代碼如下。

<template>
  <div class="test" id='gltf'>

  </div>
</template>

<script>
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { Projector } from "three/examples/jsm/renderers/Projector";
//實現360度自由旋轉的控制球
import { TrackballControls } from "three/examples/jsm/controls/TrackballControls";
// 定義three全局變量
const scene = new THREE.Scene();
// three的控制器必須放在data外,否則會造成卡頓的問題
var controls;
export default {
  data () {
    return {
      camera: null,
      //   scene: null,
      renderer: null,
      mesh: null,
      loader: null,
      mixer: null,
      clock: new THREE.Clock(),
      //   controls: null,
      //   projector: new THREE.Projector(),
      SELECTED: null,
      objects: []
    }
  },
  components: {

  },
  mounted () {
    this.init();
    this.render();
    this.animate();
    //點擊事件
    // window.addEventListener('click', this.onMouseClick, false);
    window.onresize = () => {
      console.log("窗口變化")
      let container = document.getElementById('gltf')
      let _this = this
      _this.camera.aspect = container.clientWidth / container.clientHeight;
      _this.camera.updateProjectionMatrix();
      _this.renderer.setSize(container.clientWidth, container.clientHeight);

    };

  },
  methods: {
    // 模型初始化
    init () {
      let container = document.getElementById("gltf");
      // 設置相機
      this.camera = new THREE.PerspectiveCamera(
        45,
        container.clientWidth / container.clientHeight,
        0.1, 10000
      );
      this.camera.position.set(10, 50, 20);
      this.camera.lookAt(new THREE.Vector3(0, 0, 0));
      //   this.scene = new THREE.Scene();
      let self = this;
      // 加載模型
      //   ZHENGQITIAOZHIZHUANGZHI
      var loader = new GLTFLoader().setPath("/gltf/");
      loader.load("ZHENGQITIAOZHIZHUANGZHI.gltf", function (gltf) {
        // const scene = gltf.scene || gltf.scenes[0];
        var mesh = gltf.scene.children[0];
        // mesh.scale.set(0.1, 0.1, 0.1);
        scene.add(mesh); // 將模型引入three
        // self.scene.add(gltf.scene);
        // 調用動畫
      });
      /*
        添加光源
      */
      var spot1;
      var ambient = new THREE.AmbientLight(0x222222);
      scene.add(ambient);
      var directionalLight = new THREE.DirectionalLight(0x222222, 7);//第一個參數光顏色,第二個參數光強度
      directionalLight.position.set(0, 5, 10).normalize();
      scene.add(directionalLight);
      var directionalLight2 = new THREE.DirectionalLight(0x222222, 7);
      directionalLight2.position.set(0, 5, -30).normalize();
      scene.add(directionalLight2);
      var directionalLight3 = new THREE.DirectionalLight(0x222222, 7);
      directionalLight3.position.set(0, 20, 0).normalize();
      scene.add(directionalLight3);
      var directionalLight4 = new THREE.DirectionalLight(0x222222, 7);
      directionalLight4.position.set(0, -20, 0).normalize();
      scene.add(directionalLight4);
      var directionalLight5 = new THREE.DirectionalLight(0x222222, 7);
      directionalLight5.position.set(20, 0, 0).normalize();
      scene.add(directionalLight5);
      var directionalLight6 = new THREE.DirectionalLight(0x222222, 7);
      directionalLight6.position.set(-20, 0, 0).normalize();
      scene.add(directionalLight6);
      /**
       * 相機設置
       */
      var width = window.innerWidth; //窗口寬度
      var height = window.innerHeight; //窗口高度
      var k = width / height; //窗口寬高比
      var s = 150; //三維場景顯示範圍控制係數,係數越大,顯示的範圍越大

      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.renderer.setSize(container.clientWidth, container.clientHeight);
      this.renderer.setClearColor('#DEE1E6', 1.0);//設置場景顏色
      container.appendChild(this.renderer.domElement);
      controls = new TrackballControls(this.camera, this.renderer.domElement);
      this.controls.rotateSpeed = 4;
      this.controls.zoomSpeed = 2;
      this.controls.panSpeed = 2;
	  this.controls.dynamicDampingFactor = 0.3;

    },
    render () {
      requestAnimationFrame(this.render);
      this.renderer.render(scene, this.camera); //執行渲染操作
    },
    /* 數據更新 */
    update () {
      // stats.update();
      controls.update();
    },
    /* 循環渲染 */
    animate () {
      //if (selectObject != undefined && selectObject != null) {
      //    renderDiv(selectObject);
      //}
      requestAnimationFrame(this.animate);
      this.renderer.render(scene, this.camera);
      this.update();
    },

   
    
    
  },

}
</script>

<style  scoped>
.test {
    height: 84.9vh;
    width: 100%;
}
</style>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章