Skip to content

Instantly share code, notes, and snippets.

@rtpHarry
Last active October 4, 2023 06:20
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rtpHarry/2d41811d04825935039dfc075116d0ad to your computer and use it in GitHub Desktop.
Save rtpHarry/2d41811d04825935039dfc075116d0ad to your computer and use it in GitHub Desktop.
Three.js - play an AnimationAction in reverse. There are a bunch of threads saying this isn't possible but I found a way so I wanted to post it online in a place that people will hopefully stumble upon it.
// The class itself is based on the animation helper class in
// https://github.com/paulmg/ThreeJS-Webpack-ES6-Boilerplate
// but I have changed almost everything except for the class name and the update function.
import * as THREE from 'three';
export default class Animation {
constructor(scene, animations) {
this.scene = scene;
this.animations = animations;
this.mixer = new THREE.AnimationMixer(this.scene);
}
playClipByIndex(index) {
// (mixer.clipAction() will also take a name string if that works better for your setup)
this.action = this.mixer.clipAction(this.animations[index]);
this.action.reset()
this.action.timeScale = 1;
this.action.setLoop(THREE.LoopOnce);
this.action.clampWhenFinished = true;
this.action.play();
}
// assumes that the mixer has already played
playClipReverseByIndex(index) {
// (mixer.clipAction() will also take a name string if that works better for your setup)
this.action = this.mixer.clipAction(this.animations[index]);
this.action.paused = false;
this.action.timeScale = -1;
this.action.setLoop(THREE.LoopOnce);
this.action.play();
}
// will force the mixer to play in reverse no matter what
playClipReverseByIndex_Forced(index) {
this.action = this.mixer.clipAction(this.animations[index]);
if(this.action.time === 0) {
this.action.time = this.action.getClip().duration;
}
this.action.paused = false;
this.action.setLoop(THREE.LoopOnce);
this.action.timeScale = -1;
this.action.play();
}
// Call update in loop
update(delta) {
if(this.mixer) {
this.mixer.update(delta);
}
}
}
@souporserious
Copy link

Just came across wanting to do the same @ametthey, it looks like you just need to call action.reset() before playing the animation on mouse down and it should work as expected.

@mudroljub
Copy link

playClipReverseByIndex_Forced works for me :) thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment