three.js官方案例(animation / keyframes)webgl_animation_keyframes.html学习
warning:
这篇文章距离上次修改已过248天,其中的内容可能已经有所变动。
// 引入相关库
import * as THREE from 'three';
import Stats from 'three/examples/jsm/libs/stats.module.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
// 场景、摄像机、渲染器等初始化代码略...
// 加载模型
const loader = new GLTFLoader();
loader.load( 'models/animals/horse.gltf', function ( gltf ) {
// 获取模型中的角色
const horse = gltf.scene.children[ 0 ];
horse.scale.set( 0.01, 0.01, 0.01 ); // 缩小模型
scene.add( horse );
// 设置动画和关键帧
const mixer = new THREE.AnimationMixer( horse );
const action = mixer.clipAction( gltf.animations[ 0 ] );
// 播放动画
action.play();
// 更新动画
mixer.timeScale = 0.8; // 放慢动画
// 创建关键帧
const keyframes = [];
keyframes.push({ time: 0, position: horse.position.clone() }); // 记录当前位置
// 设置动画更新时的回调函数
const clock = new THREE.Clock();
const update = function ( deltaTime ) {
const time = clock.getElapsedTime();
// 每隔一定时间记录关键帧
if ( time > keyframes[ keyframes.length - 1 ].time + 2 ) {
keyframes.push({
time: time,
position: horse.position.clone()
});
}
// 插值计算关键帧之间的位置
const keys = keyframes.length;
if ( keys > 1 ) {
const prevKey = keyframes[ keys - 2 ];
const nextKey = keyframes[ keys - 1 ];
const p = ( time - prevKey.time ) / ( nextKey.time - prevKey.time );
horse.position.lerpVectors( prevKey.position, nextKey.position, p );
}
// 更新动画
mixer.update( deltaTime );
// 渲染场景
renderer.render( scene, camera );
};
// 监听浏览器窗口大小变化
window.addEventListener( 'resize', onWindowResize );
// 渲染循环
function animate() {
requestAnimationFrame( animate );
update();
}
animate();
}, undefined, function ( error ) {
console.error( error );
} );
// 其他函数和监听器略...
这段代码示例展示了如何在Three.js中加载一个glTF模型,并设置其动画和关键帧记录。它演示了如何使用THREE.AnimationMixer
来播放和控制模型的动画,并使用关键帧数组来记录和插值计算模型的位置。最后,它提供了一个update
函数,该函数在每一帧调用,用于更新动画状态和渲染场景。
评论已关闭