Three.js (learning)

The process of using Three.js in a vue project

1. First use npm to install Q three.js, the specific operation code is as follows
   npm install three
2. Next use npm to install the orbit control plug-in:
  npm install three-orbit-controls

3. Next, install the plugin for loading .obj and .mtl files:
  npm i --save three-obj-mtl-loader


4. Install the renderer plugin:
 npm i --save three-css2drender

After installation, import and use three.is in the page, the code introduced in the called page is:
1 import * as Three from 'three

Remember to import three.js

  1. Create the scene first       
  2. create camera
  3. set camera position
  4. Add Objects Create Geometry
  5. Create objects from geometry and materials
  6. Add geometry to the scene
  7. Initialize the renderer
  8. Set the renderer size
  9. Add the canvas content rendered by webgl to the body
  10. Use the renderer to render the scene through the camera

 Go directly to the code:

      //创建场景
      const scene = new THREE.Scene();
      //创建相机
      const camera = new THREE.PerspectiveCamera(75,homebox.clientWidth/homebox.clientHeight,0.1,1000);
      //改变相机的初始位置
      camera.position.set(0,0,10);
      //在相机添加到场景
      scene.add(camera);
      //添加物体 创建几何体
      const cubeGeomtry = new THREE.BoxGeometry(1,1,1);//添加几何体
      const cubeMaterial = new THREE.MeshBasicMaterial({color:0xffbb00})//添加材质
      //根据几何体和材质创建物体 
      const cube = new THREE.Mesh(cubeGeomtry,cubeMaterial);
      //将几何体添加到场景
      scene.add(cube);
      //初始化渲染器
      const renderer = new THREE.WebGLRenderer();
      //设置渲染器的尺寸
      renderer.setSize(window.innerWidth,window.innerHeight);
      //将webgl渲染的canvas内容添加到页面容器中
      homebox.appendChild(renderer.domElement);
      //使用渲染器,通过相机将场景渲染进来
      renderer.render(scene,camera);

 The above code simply renders a cube ( still ) in the browser. If you want it to be draggable with the mouse , you need to do the following:

//导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; 

//创建轨道控制器
     var controls=new OrbitControls(camera,renderer.domElement);

    // 添加一个动画函数
      function Aboutanimate() {
        requestAnimationFrame(Aboutanimate);//请求动画帧  每帧执行一次动画函数
        renderer.render(scene,camera);//渲染
      }

In order to facilitate us to observe the location of the object , the following operations are required:

      //添加坐标轴辅助器
      const axesHelper = new THREE.AxesHelper(5)//参数代表坐标轴长度
      scene.add(axesHelper)//把坐标轴辅助器添加到场景中

Now we can see a cube, if only this is far from meeting our needs, so we want to make the cube move, the following code can be achieved:

import gsap from 'gsap';//导入动画库   要记得npm安装一下  npm install gsap
//gsap是补间动画库
//设置补间动画
      let animation= gsap.to(cube.position,{x:5,duration:5,ease:"powerl.inOut",
      repeat:5,  //设置重复次数  无限次重复设置为-1
      yoyo:true, //设置往返运动
      delay:2,   // delay 设置2秒延迟
      onComplete:()=>{
        console.log('动画完成');
      },
      onStart:()=>{
        console.log('动画开始');
      }
    })
      gsap.to(cube.rotation,{x:2*Math.PI,duration:5,ease:"powerl.inOut",repeat:5,yoyo:true})

Now we can see that the cube is moving. In order to facilitate our development and debugging, we need a panel that can be controlled in real time, which can be implemented with the following code:

 //导入dat.gui
import * as dat from 'dat.gui'  
//移动X轴坐标 
      const gui = new dat.GUI();
      gui.add(cube.position,"x").min(0).max(5).step(0.01).name('移动X轴坐标').onChange((value)=>{
        console.log('值被修改:',value);
      }).onFinishChange((valur)=>{
        console.log("完全停下来");
      });

       //移动Y轴坐标  
      gui.add(cube.position,"y").min(0).max(5).step(0.01).name('移动Y轴坐标').onChange((value)=>{
        console.log('值被修改:',value);
      }).onFinishChange((valur)=>{
        console.log("完全停下来");
      });
      
//移动Z轴坐标  
       gui.add(cube.position,"z").min(0).max(5).step(0.01).name('移动Z轴坐标').onChange((value)=>{
        console.log('值被修改:',value);
      }).onFinishChange((valur)=>{
        console.log("完全停下来");
      });
//控制旋转
      gui.add(cube.rotation,'x').min(0).max(2*Math.PI).step(0.01).name('转动X轴')
      gui.add(cube.rotation,'y').min(0).max(2*Math.PI).step(0.01).name('转动Y轴')
      gui.add(cube.rotation,'z').min(0).max(2*Math.PI).step(0.01).name('转动Z轴')
 
//改变物体颜色
      const params = {
        color:'#ffff00',
        fn:()=>{
          //让立方体运动起来
          gsap.to(cube.position,{x:5,duration:5,yoyo:true,repeat:-1})
        }
      }
      gui.addColor(params,"color").name('物体颜色').onChange((value)=>{
        console.log("值被改变:",value);
        cube.material.color.set(value)
      })
      //设置选项框
      gui.add(cube,'visible').name('是否显示')
    
      
//设置文件夹
      var folder= gui.addFolder('设置立方体')
      folder.add(cube.material,'wireframe')
      //设置按钮点击触发某个事件
      folder.add(params,'fn').name('点击立方体运动')

In order to achieve responsiveness, the following code is added here:

 //调用js接口
        //双击控制屏幕进入全屏,退出全屏
        const fullScreenElement = document.fullscreenElement;
        if (!fullScreenElement) {
          renderer.domElement.requestFullscreen()
        } else {
          document.exitFullscreen()
          
        }
        
      })
      //监听画面变化,更新渲染画面
      window.addEventListener('resize',()=>{
        console.log('画面变化了');
        camera.aspect = homebox.clientWidth/homebox.clientHeight;//更新摄像头
        camera.updateProjectionMatrix();//更新摄像机的投影矩阵
        renderer.setSize(window.innerWidth,window.innerHeight);//更新渲染器
        
        renderer.setPixelRatio(homebox.devicePixelRatio);//设置渲染器的像素比
      })

Here is the complete code:

<template>
  <div id='Home'></div>
</template>

<script>
//引入three.js
import * as THREE from 'three'; 
//导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; 
//导入动画库
import gsap from 'gsap';
//导入dat.gui
import * as dat from 'dat.gui';  
export default {
  data() {
    return {
      
    }
  },
  mounted() {
   this.init()
   
    
    
  },
  methods: {
    init(){
      //获取dom元素
      let homebox = document.getElementById('Home');

      //创建场景
      const scene = new THREE.Scene();

      //创建相机
      const camera = new THREE.PerspectiveCamera(75,homebox.clientWidth/homebox.clientHeight,0.1,1000);

      //改变相机的初始位置
      camera.position.set(0,0,10);

      //在相机添加到场景
      scene.add(camera);

      //添加物体 创建几何体
      const cubeGeomtry = new THREE.BoxGeometry(1,1,1);//添加几何体
      const cubeMaterial = new THREE.MeshBasicMaterial({color:0xffbb00})//添加材质

      //根据几何体和材质创建物体 
      const cube = new THREE.Mesh(cubeGeomtry,cubeMaterial);

      //将几何体添加到场景
      scene.add(cube);

      //移动X轴坐标 
      const gui = new dat.GUI();
      gui.add(cube.position,"x").min(0).max(5).step(0.01).name('移动X轴坐标').onChange((value)=>{
        console.log('值被修改:',value);
      }).onFinishChange((valur)=>{
        console.log("完全停下来");
      });

       //移动Y轴坐标  
      gui.add(cube.position,"y").min(0).max(5).step(0.01).name('移动Y轴坐标').onChange((value)=>{
        console.log('值被修改:',value);
      }).onFinishChange((valur)=>{
        console.log("完全停下来");
      });
      

       //移动Z轴坐标  
       gui.add(cube.position,"z").min(0).max(5).step(0.01).name('移动Z轴坐标').onChange((value)=>{
        console.log('值被修改:',value);
      }).onFinishChange((valur)=>{
        console.log("完全停下来");
      });


      //控制旋转
      gui.add(cube.rotation,'x').min(0).max(2*Math.PI).step(0.01).name('转动X轴')
      gui.add(cube.rotation,'y').min(0).max(2*Math.PI).step(0.01).name('转动Y轴')
      gui.add(cube.rotation,'z').min(0).max(2*Math.PI).step(0.01).name('转动Z轴')
 

      //改变物体颜色
      const params = {
        color:'#ffff00',
        fn:()=>{
          //让立方体运动起来
          gsap.to(cube.position,{x:5,duration:5,yoyo:true,repeat:-1})
        }
      }
      gui.addColor(params,"color").name('物体颜色').onChange((value)=>{
        console.log("值被改变:",value);
        cube.material.color.set(value)
      })
      //设置选项框
      gui.add(cube,'visible').name('是否显示')

      
      //设置文件夹
      var folder= gui.addFolder('设置立方体')
      folder.add(cube.material,'wireframe')
      //设置按钮点击触发某个事件
      folder.add(params,'fn').name('点击立方体运动')

      //初始化渲染器
      const renderer = new THREE.WebGLRenderer();

      //设置渲染器的尺寸
      renderer.setSize(window.innerWidth,window.innerHeight);

      //将webgl渲染的canvas内容添加到页面容器中
      homebox.appendChild(renderer.domElement);

      //使用渲染器,通过相机将场景渲染进来
      // renderer.render(scene,camera);
      Aboutanimate()

      //创建轨道控制器
      var controls=new OrbitControls(camera,renderer.domElement);

      //添加坐标轴辅助器
       const axesHelper = new THREE.AxesHelper(5)//参数代表坐标轴长度
       scene.add(axesHelper)//把坐标轴辅助器添加到场景中

      
      //这里可以不要 
       //设置补间动画
    //  let animation= gsap.to(cube.position,{x:5,duration:5,ease:"powerl.inOut",
    //  repeat:5,  //设置重复次数  无限次重复设置为-1
    //  yoyo:true, //设置往返运动
    //  delay:2,   // delay 设置2秒延迟
    //  onComplete:()=>{
    //    console.log('动画完成');
    //  },
    //  onStart:()=>{
    //    console.log('动画开始');
    //  }
    //  })
    //    gsap.to(cube.rotation,{x:2*Math.PI,duration:5,ease:"powerl.inOut",repeat:5,yoyo:true})




     //双击触发事件  监听鼠标双击
     window.addEventListener("dblclick",()=>{
        // console.log(animation);
        // if (animation.isActive()) {
        //   //暂停动画
        //   animation.pause()
        // } else {
        //   //恢复动画
        //   animation.resume()
        // }

        //调用js接口
        //双击控制屏幕进入全屏,退出全屏
        const fullScreenElement = document.fullscreenElement;
        if (!fullScreenElement) {
          renderer.domElement.requestFullscreen()
        } else {
          document.exitFullscreen()
          
        }
        
      })
      //监听画面变化,更新渲染画面
      window.addEventListener('resize',()=>{
        console.log('画面变化了');
        camera.aspect = homebox.clientWidth/homebox.clientHeight;//更新摄像头
        camera.updateProjectionMatrix();//更新摄像机的投影矩阵
        renderer.setSize(window.innerWidth,window.innerHeight);//更新渲染器
        
        renderer.setPixelRatio(homebox.devicePixelRatio);//设置渲染器的像素比
      })
      
      // 动画函数
      function Aboutanimate() {
        requestAnimationFrame(Aboutanimate);//请求动画帧  每帧执行一次动画函数
        renderer.render(scene,camera);//渲染
      
       }

    }
  },
}
</script>

<style scoped lang='scss'>
#Home {
  width: 100vh;
  height: 100vh;
}
</style>

Guess you like

Origin blog.csdn.net/w418856/article/details/130399267