持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情
写在前面
本文用vue+threejs写物体动画:物体旋转动画,物体绕着自己旋转90度的动画。
下面是演示gif:
代码说明
- 同样先创建一个
id容器,用来插入threejs渲染器节点
<template>
<div class="item">
<div id="THREE42"></div>
</div>
</template>
- 引入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";
mounted方法中调用initThreejs方法
mounted() {
this.initThreejs();
},
- 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);
}
},
写在最后
以上就是所有的代码和说明。