在Vue中使用Three.js入门

1,579 阅读1分钟

201882116483515433.png

第一次接触Three,新手勿喷。简单做个搬砖日记记录一下。

准备工作

我这里使用的的Vue2,首先创建好一个项目,接下来就是下载安装Three.js包

安装Three.js

npm install three

安装轨道控制器

npm install three-orbit-controls

安装安装加载.obj和.mtl文件插件

npm i --save three-obj-mtl-loader

安装渲染器

npm install three-css2drender

到这里所需要的插件已经安装完成,接下来就是搬砖时刻了,奥力给!

代码实现

在Vue项目中的main.js中全局注册

// 引入three
import * as Three from 'three';
// 引入three轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

//挂载到原型
Vue.prototype.$Three = Three;
Vue.prototype.$OrbitControls = OrbitControls;

继续在Vue单页面中搬砖

1.HTML部分

<template>
  <div>
    正方体
    <div id="container"></div>
  </div>
</template>

1.js部分

<script>
export default {
  data() {
    return {
      scene: null,  //场景对象
      camera: null,  //相机对象
      renderer: null,  //渲染器对象
      mesh: null,  //网格模型对象
      controls:null ,//创建轨道控制器对象
      angle : 0
    }
  },
  mounted() {
    this.init()
    this.animate()
  },
  methods: {
    init() {
      let container = document.getElementById('container');

      //创建场景对象
      this.scene = new this.$Three.Scene() 
      
      // PerspectiveCamera(透视相机-有好多种,暂且先试用这个)
      // 第一个参数是视野角度:显示器上看到的场景的范围,
      // 第二个参数是长宽比(aspect ratio):物体的宽/高
      // 三四参数是视锥体的近截面(near)和远截面(far)(这个慢慢查资料吧,哈哈哈) 
      // 创建相机对象
      this.camera = new this.$Three.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 1, 3000) 
      // 相机位置
      this.camera.position.set(200,200,200)
      
      // 创建渲染器对象
      this.renderer = new this.$Three.WebGLRenderer() 
      // 渲染区域的宽高
      this.renderer.setSize( window.innerWidth/2 , window.innerHeight/2);
      // 给dom添加渲染器
      container.appendChild(this.renderer.domElement);
    
      // 创建正方体(BoxGeometry-几何正方体)大小100
      const geometry = new this.$Three.BoxGeometry(100, 100, 100)
      
      // 创建材质来让它有颜色(MeshBasicMaterial-材质,十六进制的颜色格式,transparent是否透明,透明度)
      // 材质:MeshBasicMaterial:以平面或线框方式来绘制几何体的材质(不受光照影响)
      // 材质:MeshLambertMaterial:漫反射材质(受光照影响) 
      // 这里使用MeshLambertMaterial是为了测试光照,任选其一都可以
      const material = new this.$Three.MeshLambertMaterial({ color: 0xff0000 ,transparent: true,opacity:0.5 });

      // 需要一个网格模型对象(Mesh)
      // 网格包含一个几何体以及作用在此几何体上的材质
      // 接收参数(创建的实例,显示的材质)这样实例就已经显示到网格上了
      this.mesh = new this.$Three.Mesh(geometry, material);
      // 设置网格位置
      this.mesh.position.set(0,0,0)
      // 把网格添加到场景中
      this.scene.add(this.mesh);
 
      // 环境光:AmbientLight
      // 点光源:PointLight
      // 可接受两个参数-表示光源颜色和光照强度
      // const light = new this.$Three.PointLight( 0xffffff,400);
      const light = new this.$Three.AmbientLight( 0xffffff,40);
      // 光照位置
      light.position.set(200,200,100)
      this.scene.add( light );

      // 创建轨道控制器
      this.controls = new this.$OrbitControls( this.camera, this.renderer.domElement );
      // 监听轨道控制器变化重新渲染
      this.controls.addEventListener('change',this.changRender)
    },
    
    
    // 渲染循环”(render loop)或者“动画循环 (animate loop)
    animate() {
      // requestAnimationFrame:相比较定时器,当用户切换到其它的标签页时,它会暂停,因此不会浪费用户宝贵的处理器资源
      requestAnimationFrame(this.animate);
      
      // 改变网格位置,获得旋转动画
      // this.mesh.rotation.x += 0.01;
      // this.mesh.rotation.y += 0.01;

      // 改变相机的位置.position,三维场景在canvas画布上呈现不同的效果,如果连续改变相机的位置.position,就可以获得一个动画效果。
      // this.camera.position.z += 0.9;

      // 在渲染循环中,改变相机位置,在XOZ平面上绕着y轴圆周运动
      this.angle += 0.01;
      this.camera.position.x = 100 * Math.cos(this.angle);
      this.camera.position.z = 100 * Math.sin(this.angle);
      //  保持相机镜头始终指向坐标原点或其它位置,实现圆周运动
      this.camera.lookAt(0,0,0);
      this.changRender()
    },

    // 执行渲染操作
    changRender() {
     this.renderer.render(this.scene, this.camera);
 }
  }
}
</script>

到这里页面效果就完成了,会呈现一个绕原点执行原周运动的一个正方体 效果

1.gif