多个动画做在了一个模型上,animations的长度是1,项目需求是根据指令播放指定动画。
准备素材,加入场景,灯光、辅助线等
html
<template>
<div class="wapper">
<div id="ee"></div>
<!-- 模拟动画切换 -->
<div @click="play('a',1)">点击1</div>
<div @click="play('b',0.1)">点击2</div>
<div @click="play('c',0.5)">点击3</div>
</div>
</template>
引入three
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
enter() {
let that = this;
let container = document.getElementById("ee");
// 场景
that.scene = new THREE.Scene();
// 相机
/**
* fov — 摄像机视锥体垂直视野角度
* aspect — 摄像机视锥体长宽比
* near — 摄像机视锥体近端面
* far — 摄像机视锥体远端面
*/
that.camera = new THREE.PerspectiveCamera(50,
container.clientWidth / container.clientHeight,
0.1,
7000)
// that.camera.position.z = 4500;
// that.camera.position.y = 300;
// that.camera.position.x = 120;
that.camera.position.z = 300;
that.camera.position.y = 200;
// self.camera.position.set(90, 1000, 0);
that.camera.lookAt(that.scene.position);//相机定位在场景的中心
// 渲染器
that.renderer = new THREE.WebGLRenderer();
that.renderer.setAnimationLoop(that.animate())
// 插入页面
that.renderer.setClearAlpha(0.0);//设置背景透明度
that.renderer.setSize(container.clientWidth, container.clientHeight);
// that.$nextTick(() => {
container.appendChild(that.renderer.domElement)
// })
// 灯光
const light = new THREE.HemisphereLight('#ffffff', '#000000', 2);
that.scene.add(light);
// 加入辅助线
that.scene.add(new THREE.AxesHelper(10000))
that.controls = new OrbitControls(that.camera, that.renderer.domElement);
//禁用缩放
that.controls.enableZoom = false;
let fbxLoader = new FBXLoader();
this.clock = new THREE.Clock();
fbxLoader.load(that.modelPath, function (object) {
that.scene.add(object);
//console.log(object);
that.mixer = new THREE.AnimationMixer(object);
//根据需求裁剪,'A\b\c'片段名字,1-109 是第一帧到108帧动画
that.actionList.a = that.mixer.clipAction(THREE.AnimationUtils.subclip(object.animations[0], 'A', 1, 109));
that.actionList.b = that.mixer.clipAction(THREE.AnimationUtils.subclip(object.animations[0], 'b', 109, 475));
that.actionList.c = that.mixer.clipAction(THREE.AnimationUtils.subclip(object.animations[0], 'c', 474, 625));
});
},
animate() {
requestAnimationFrame(this.animate);
if (this.mixer) {
this.mixer.update(this.clock.getDelta())
}
this.renderer.render(this.scene, this.camera);
}
动画切换
play(times, tip) {
let that = this;
for (let key in that.actionList) {//停止其他动画,一次只播放一个
that.actionList[key].stop();
}
that.actionList[times].play();
that.actionList[times].timeScale = tip;//倍速,大于0是倍速,小于0是倒放
},