之前用threejs实现的动画都是自然播放的,并没有干涉其播放过程,但是很多场景会需要手动干涉,比如做一个3D的SOP,用户通过3D动画的播放,360度查看设备的安装过程,并手动控制动画的继续和暂停来学习。这节介绍如何手动控制动画播放,包括暂停继续,以及控制速度。
首先我们需要创建一个场景,包括场景scene,相机camera,灯光light,渲染器Renderer,鼠标控制组件OrbitControl,以及最后的循环渲染InitAnimate
initScene(){
this.scene = new THREE.Scene();
},
initCamera(){
this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
this.camera.position.set(500,500,500);
},
initLight(){ //添加两个平行光
const directionalLight1 = new THREE.DirectionalLight(0xffffff, 5);
directionalLight1.position.set(-300,300,-600)
this.scene.add(directionalLight1);
const directionalLight2 = new THREE.DirectionalLight(0xffffff, 5);
directionalLight2.position.set(300,300,600)
this.scene.add(directionalLight2);
},
initRenderer(){
this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.container = document.getElementById("container")
this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);
this.renderer.setClearColor('#AAAAAA', 1.0);
this.container.appendChild(this.renderer.domElement);
},
initControl(){
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
this.controls.enableDamping = true;
this.controls.maxPolarAngle = Math.PI / 2.2; // // 最大角度
},
initAnimate() {
requestAnimationFrame(this.initAnimate);
this.renderer.render(this.scene, this.camera);
},
场景创建好后需要在场景中添加带动画的模型。这里以一个小零件为例,
加载到模型后就获取这个模型的动画,并创建动画混合器实现播放等,最后还需要在循环渲染中加入更新动画混合器的方法,让画面更新的时候也更新动画混合器。而其中的this.value就是播放动画的速度,值越大播放越快
initRound(){
const loader = new GLTFLoader()
loader.load("/static/models/mes/make3.glb", (gltf) => {
this.car = gltf.scene
this.car.scale.set(1,1,1)
this.car.position.set(0,0,0)
this.scene.add(this.car);//添加到场景中
const clip = gltf.animations[0]; //获取到模型动画
this.mixer = new THREE.AnimationMixer(gltf.scene); //创建动画混合器
this.action = this.mixer.clipAction(clip); //创建动画动作
this.action.setDuration(clip.duration).play(); //设置动画时长
})
},
initAnimate() {
if(this.mixer){
this.mixer.update(this.value);//这里给动画设置更新速度,因为默认是一秒钟渲染60次,所以这里设置为1/60的值,
}
requestAnimationFrame(this.initAnimate);
this.renderer.render(this.scene, this.camera);
},
然后就可以得到一个动画,但是此时动画是一直循环播放的,没办法暂停,因此我们需要加入两个按钮,这里引入element框架,让按钮更美观一点,为了控制速度再加入一个滑动条,等会可以通过滑动条来改变动画的播放速度,
<template>
<div>
<div id="container"></div>
<div style="position:absolute;width:360px; right:30px;top:60px;">
<el-button type="primary" @click="pauseAnimation">暂停</el-button>
<el-button type="primary" @click="continueAnimation">继续</el-button>
<div class="block">
<span class="demonstration">速度</span>
<el-slider
v-model="value"
:step=stepLength
:max=maxValue>
</el-slider>
</div>
</div>
</div>
</template>
在上面加载模型的时候,我们创建一个一个action来播放动画,其实控制动画播放也是通过此action的方法,设置action的paused属性为true就可以暂停动画,设置为false就可以继续播放动画了。滑动组件的值绑定到画面循环的this.value上就好了,
pauseAnimation(){
this.action.paused = true;
},
continueAnimation(){
this.action.paused = false;
this.action.play();
},
最终效果,这里不支持上传视频,我发个效果图代替,如果想看动态效果可以私我,我发给你视频
手动控制模型动画