加载动画
let nameToClip = {};
let mixer = null;
const loader = new GLTFLoader();
loader.load('/threed/models/' + modelName, function (gltf) {
let model = gltf.scene;
let animations = gltf.animations;
mixer = new THREE.AnimationMixer(model);
for (let clip of animations) {
nameToClip[clip.name] = clip;
// console.log(clip.name);
}
});
1倍倍速播放一段
let clip = nameToClip[clipName];
let action = mixer.clipAction(clip);
action.setLoop(THREE.LoopOnce); // 此时 timeScale 大于零才有效
action.clampWhenFinished = true;
action.timeScale = 1; // N 倍速
action.time = 10; // 开始时间,小于结束时间
action._clip.duration = 50; // 结束时间
mixer.stopAllAction();
action.reset().play();
animate();
let clock = new THREE.Clock();
function animate() {
mixer.update(clock.getDelta());
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
暂停/停止
action.paused = true;
action.stop();
从一个位置,1倍倍速反向播放一段
let clip = nameToClip[clipName];
let action = mixer.clipAction(clip);
action.setLoop(THREE.LoopRepeat); // 必须是LoopRepeat
action.clampWhenFinished = true;
action.timeScale = -1; // N 倍速
action.time = 50; // 开始时间,大于结束时间
// action._clip.duration = 10; // 不能设置结束时间点,设置后播放不了
let endTime = 10; // 结束时间
mixer.stopAllAction();
action.reset().play();
animate();
let clock = new THREE.Clock();
function animate() {
mixer.update(clock.getDelta());
if (action._loopCount >= 0 || action.time <= endTime) {
action.stop();
}
requestAnimationFrame(animate);
renderer.render(scene, camera);
}