Skip to content
分类目录:

vue使用three.js

Post date:
Author:
标签:
Number of comments: no comments

在vue中使用three.js

1.安装依赖

cnpm install three --save
cnpm install three-orbitcontrols --save
three.js依赖
three.js依赖

编写代码

<template>
  <div class="components-container">
    <div id="three_container"></div>
  </div>
</template>

<script>
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader";
import { DDSLoader } from "three/examples/jsm/loaders/DDSLoader";
import { STLLoader } from "three/examples/jsm/loaders/STLLoader";
import OrbitControls from "three-orbitcontrols";
// import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import * as THREE from "three";
// 定义three全局变量
var scene = null;
// three的控制器必须放在data外,否则会造成卡顿的问题
var controls = null;
export default {
  name: "Three",
  props: {},
  components: {},
  computed: {},
  data() {
    return {
      camera: null,
      // controls: null,
      // scene: null,
      renderer: null,
      dummy: new THREE.Object3D(),
      dummys: {},
    };
  },
  watch: {},
  mounted() {
    this.init();
  },
  methods: {
    // 初始化
    init() {
      this.initScene();
      this.initCamera();
      this.initRender();
      this.initControls();
      this.initLight();
      this.initObject();

      // document.addEventListener("keydown", onkeyDown, false);
      // document.addEventListener("mousedown", clickEvent, false);
      // window.addEventListener("resize", onWindowResize, false);
      // document.addEventListener("mousemove", onMousemove, false);
    },
    // 场景
    initScene() {
      scene = new THREE.Scene();
    },
    // 镜头
    initCamera() {
      let container = document.getElementById("three_container");
      let VIEW_ANGLE = 75, // 摄像机视锥体垂直视野角度,最小值为0,最大值为180,默认值为50,实际项目中一般都定义45,因为45最接近人正常睁眼角度
        ASPECT = container.clientWidth / container.clientHeight, // 摄像机视锥体长宽比,默认长宽比为1,即表示看到的是正方形,实际项目中使用的是屏幕的宽高比
        NEAR = 1, // 摄像机视锥体近端面,这个值默认为0.1,实际项目中都会设置为1
        FAR = 20000; // 摄像机视锥体远端面,默认为2000,这个值可以是无限的,说的简单点就是我们视觉所能看到的最远距离
      this.camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
      this.camera.position.set(0, 500, 800); // position用来指定相机在三维坐标中的位置
      // this.camera.lookAt(scene.position);
      this.camera.up.set(0, 1, 0); // up用来指定相机拍摄时相机头顶的方向
      this.camera.lookAt(0, 0, 0); // lookAt表示相机拍摄时指向的中心点
      scene.add(this.camera);
    },
    // 渲染器
    initRender() {
      let container = document.getElementById("three_container");
      this.renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true,
      });
      this.renderer.setClearColor(0xeeeeee); //背景色
      this.renderer.setSize(container.clientWidth, container.clientHeight); //场景大小
      this.renderer.shadowMap.enabled = true; //启用阴影
      container.appendChild(this.renderer.domElement);
    },
    // 控制
    initControls() {
      controls = new OrbitControls(this.camera, this.$el);
      controls.type = "orbit";
      // //是否可以缩放
      controls.enableZoom = true;
      controls.enableRotate = true;
      // //是否开启右键拖拽
      controls.enablePan = true;
      console.log("controls-->>", controls);
      //监听鼠标事件,触发渲染函数,更新canvas画布渲染效果
      controls.addEventListener("change", this.update);
    },
    // 光源
    initLight() {
      var directionalLight = new THREE.DirectionalLight(0xffffff, 1); //模拟远处类似太阳的光源
      directionalLight.position.set(0, 100, 0).normalize();
      scene.add(directionalLight);

      let ambient = new THREE.AmbientLight(0xffffff, 1); //AmbientLight,影响整个场景的光源
      ambient.position.set(0, 0, 0);
      scene.add(ambient);
    },
    // 载入模型
    initObject() {
      this.createFloor(); // 地板
    },
    getObject(object) {
      return object;
    },
    // 更新场景
    update() {
      this.renderer.render(scene, this.camera);
      // controls.update();
    },
    // 创建地板
    createFloor() {
      let this_ = this;
      let loader = new THREE.TextureLoader();
      loader.load("/static/images/floor.jpg", function (texture) {
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
        texture.repeat.set(10, 10);
        let floorGeometry = new THREE.BoxGeometry(2000, 1000, 1);
        let floorMaterial = new THREE.MeshBasicMaterial({
          map: texture,
          side: THREE.DoubleSide,
        });
        let floor = new THREE.Mesh(floorGeometry, floorMaterial);
        floor.name = "floor";
        floor.position.y = -0.5;
        floor.rotation.x = Math.PI / 2;
        scene.add(floor);
        this_.update();
      });
    },
  },
  beforeDestroy() {
    this.renderer.dispose();
    if (controls) {
      controls.dispose();
    }
  },
};
</script>

<style lang="scss" scoped>
.components-container {
  margin-top: 15px;
  margin-bottom: 15px;
  height: 300px;
  width: 100%;
  background-color: #fff;
  #three_container {
    width: 100%;
    height: 100%;
  }
}
</style>
vue使用three.js
效果

载入stl模型

loadSTL(name, obj, x, y, z, r, s) {
      let loader = new STLLoader();
      loader.load("/static/obj/yzhou.stl", function (geometry) {
        var material = new THREE.MeshPhongMaterial({
          color: 0xff5533,
          specular: 0x111111,
          shininess: 200,
        });
        var mesh = new THREE.Mesh(geometry, material);
        mesh.position.set(0, -0.5, 0);
        mesh.rotation.set(0, -Math.PI / 2, 0);
        mesh.scale.set(0.1, 0.1, 0.1);
        mesh.castShadow = true;
        mesh.receiveShadow = true;
        scene.add(mesh);
      });
    },
载入stl模型
载入stl模型
地板素材
地板素材

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注