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>

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Vue使用Three.js可以给您的应用程序添加3D渲染和交互功能。下面是一个使用VueThree.js的简单示例: 首先,确保您已经引入VueThree.js库。 在Vue组件中,您可以创建一个Canvas元素来渲染Three.js场景,并在mounted钩子函数中初始化场景、相机和渲染器。 ```vue <template> <div> <canvas ref="canvas"></canvas> </div> </template> <script> import * as THREE from 'three'; export default { mounted() { this.init(); }, methods: { init() { // 创建场景 const scene = new THREE.Scene(); // 创建相机 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // 创建渲染器 const renderer = new THREE.WebGLRenderer({ canvas: this.$refs.canvas }); renderer.setSize(window.innerWidth, window.innerHeight); // 创建立方体 const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 动画循环 function animate() { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } animate(); }, } }; </script> <style> canvas { width: 100%; height: 100%; } </style> ``` 在这个示例中,我们创建了一个Canvas元素来渲染Three.js场景,并在mounted钩子函数中初始化了场景、相机和渲染器。然后,我们创建了一个立方体,并将其添加到场景中。在动画循环中,我们更新立方体的旋转,并使用渲染器在每一帧中渲染场景。 请注意,这只是一个简单的示例,您可以根据具体需求进行进一步的定制和开发。希望对您有所帮助!
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值