继续创造,加快成长!这是我参加「日新计划 10 月更文应战」的第6天,点击检查活动概况


写在前面

本文用vue+threejs写物体动画:物体旋转动画,物体绕着自己旋转90度的动画。

下面是演示gif:

vue+threejs写物体动画:物体旋转动画

代码阐明

  1. 相同先创立一个id容器,用来插入threejs渲染器节点
<template>
  <div class="item">
    <div id="THREE42"></div>
  </div>
</template>
  1. 引进threejs及需要的模块

OrbitControls – 轨迹操控器

DRACOLoader – .drc文件加载器

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
  1. mounted办法中调用initThreejs办法
mounted() {
  this.initThreejs();
},
  1. initThreejs代码阐明
  • 创立场景:scene = new THREE.Scene();
  • 创立灯光:new THREE.DirectionalLight(0xffffff)创立一个平行光
  • 创立相机:camera = new THREE.PerspectiveCamera(35,(window.innerWidth - 201) / window.innerHeight,1,500);创立一个透视相机
  • 创立渲染器:new THREE.WebGLRenderer({ antialias: true }); 而且设置设备分辨率renderer.setPixelRatio(window.devicePixelRatio) 并将渲染器插入到dom节点中document.getElementById("THREE42").appendChild(renderer.domElement);
  • 创立轨迹操控器:new OrbitControls(camera, renderer.domElement); 传入的参数阐明:(操控的相机,空气的渲染器)
  • 创立地上:new THREE.Mesh即创立一个立方体网格模型。
  • 监听鼠标落下事情:document.addEventListener("pointerdown", animate);
  • 运用DRACOLoader加载模型,并给加载后的模型加上一个材质new THREE.MeshStandardMaterial({ color: 0xffffff });
  • 运用帧动画,每帧模型旋转/300:mesh.rotation.y += Math.PI / 300;
  • 最终进行渲染:renderer.render(scene, camera);
initThreejs() {
  let camera, scene, renderer;
  let mesh;
  const dracoLoader = new DRACOLoader();
  dracoLoader.setDecoderPath("js/libs/draco/");
  dracoLoader.setDecoderConfig({ type: "js" });
  init();
  function init() {
    scene = new THREE.Scene();
    scene.background = new THREE.Color(0x000000); // 设置场景背景颜色
    const light = new THREE.DirectionalLight(0xffffff); // 平行光
    light.position.set(0.5, 1.0, 0.5).normalize(); // 设置平行光的方向,从(0.5, 1.0, 0.5)->target一般(0, 0, 0)
    scene.add(light); // 将灯光添加到场景中
    camera = new THREE.PerspectiveCamera(
      35,
      (window.innerWidth - 201) / window.innerHeight,
      1,
      500
    ); // 透视相机
    camera.position.x = 0.5;
    camera.position.y = 0.5; // 设置相机的位置
    camera.position.z = 1.8;
    scene.add(camera); // 将相机添加到场景中
    // 创立渲染器
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.outputEncoding = THREE.sRGBEncoding;
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth - 201, window.innerHeight);
    document.getElementById("THREE42").appendChild(renderer.domElement);
    // 创立轨迹操控器
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.addEventListener("change", render);
    controls.update();
    // 创立地上
    const ground = new THREE.Mesh(
      new THREE.BoxGeometry(1, 0.0015, 1),
      new THREE.MeshPhongMaterial({
        color: 0x999999,
        depthWrite: false,
        transparent: true,
        opacity: 1,
      })
    );
    ground.receiveShadow = true; // 接纳暗影
    scene.add(ground);
    document.addEventListener("pointerdown", animate); // 监听鼠标、手指落下
    //  加载模型
    dracoLoader.load("/models/models/draco/bunny.drc", function (geometry) {
      geometry.computeVertexNormals();
      const material = new THREE.MeshStandardMaterial({ color: 0xffffff });
      mesh = new THREE.Mesh(geometry, material);
      mesh.castShadow = true;
      mesh.receiveShadow = true;
      scene.add(mesh);
      dracoLoader.dispose(); // 释放解码器资源并释放内存
      render();
    });
  }
  function animate() {
    requestAnimationFrame(animate);
    // 旋转Math.PI / 2后中止
    if (mesh.rotation.y < Math.PI / 2) {
      mesh.rotation.y += Math.PI / 300;
    }
    render();
  }
  function render() {
    renderer.render(scene, camera);
  }
},

写在最终

以上便是所有的代码和阐明。