# How to sequentially play gltf animation on button click with previous animation endstate intact?

**URL:** <https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857>\
**Category:** Questions\
**Tags:** animation\
**Created:** [December 22, 2020, 12:16pm UTC](https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857 "2020-12-22T12:16:26Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Vaishali\_Valavade](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/vaishali_valavade/32/15283_2.png) [@Vaishali\_Valavade](https://discourse.threejs.org/u/Vaishali_Valavade)\
**Post date:** [December 22, 2020, 12:16pm UTC](https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857/1 "2020-12-22T12:16:26Z")

</div>

I have a gltf file with various related animations. I need to play these animations sequentially on button click.  
Am able to loop through the animations but the previous animation endstate is not being maintained. What am I missing?

My code so far:

loader.load( ‘xxx.gltf’, function ( gltf ) {

```
  var animcount = gltf.animations.length;
  mixer = new THREE.AnimationMixer( gltf.scene );
    
  nextButton.onclick = function NextAnimation() {   
        index++;
        if(index < animcount ) {
            action1 = mixer.clipAction( gltf.animations[index] );
            action1.clampWhenFinished = true;
            action1.timeScale = 1;
            action1.reset();
            action1.setLoop( THREE.LoopOnce )
            action1.setDuration(action1._clip.duration)
           
            if(prevAction)
                prevAction.fadeOut(0)
            
            action1.play();
            scene.add( gltf.scene );
            animate();

            mixer.addEventListener('finished', () => {
                prevAction = action1 // Save a reference to the previous action
            })
        }
    }

```

});

```
renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            renderer.gammaOutput = true;
            const controls = new OrbitControls( camera, renderer.domElement );
            document.body.appendChild(renderer.domElement);

```

}

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [December 22, 2020, 12:23pm UTC](https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857/2 "2020-12-22T12:23:44Z")

</div>

@Vaishali_Valavade

try with

```
action.clampWhenFinished = true;
```

---

<div class="post-metadata">

**Author:** ![Fyrestar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fyrestar/32/52793_2.png) [@Fyrestar](https://discourse.threejs.org/u/Fyrestar)\
**Post date:** [December 22, 2020, 12:24pm UTC](https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857/3 "2020-12-22T12:24:52Z")

</div>

You shouldn’t create the animation actions on the fly over and over again, i’m not sure how this animation should look but if you want the previous transition into the next their weights must cross fade rather than fade out A then fade in B. You can do this manually setting the weight or use the internal functions:

> **[three.js docs](https://threejs.org/docs/#api/en/animation/AnimationAction.crossFadeTo)**

---

<div class="post-metadata">

**Author:** ![Vaishali\_Valavade](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/vaishali_valavade/32/15283_2.png) [@Vaishali\_Valavade](https://discourse.threejs.org/u/Vaishali_Valavade)\
**Post date:** [December 22, 2020, 12:26pm UTC](https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857/4 "2020-12-22T12:26:26Z")

</div>

Thanks for the reply. I have already used it in my code above.

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [December 22, 2020, 12:29pm UTC](https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857/5 "2020-12-22T12:29:46Z")

</div>

@Vaishali_Valavade

appologies, overlooked that.

---

<div class="post-metadata">

**Author:** ![Vaishali\_Valavade](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/vaishali_valavade/32/15283_2.png) [@Vaishali\_Valavade](https://discourse.threejs.org/u/Vaishali_Valavade)\
**Post date:** [December 22, 2020, 12:29pm UTC](https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857/6 "2020-12-22T12:29:59Z")

</div>

Sorry for my ignorance. Then would you help me as to how i should go about playing the animations interactively ( on lets say “next” button click)

---

<div class="post-metadata">

**Author:** ![Fyrestar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fyrestar/32/52793_2.png) [@Fyrestar](https://discourse.threejs.org/u/Fyrestar)\
**Post date:** [December 22, 2020, 12:38pm UTC](https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857/7 "2020-12-22T12:38:57Z")

</div>

Just create the actions once and store them in an array, you can use your index variable to grab it then.

> ```
> scene.add( gltf.scene );
> animate();
> 
> ```

You don’t need to add the object every time again either, it won’t dublicate but just add it once outside that button click event, but especially don’t call animate there if that is your requestAnimationFrame loop.

I didn’t used the internal ones before but at here

> [@Vaishali\_Valavade](#):
>
> ```javascript
> if(prevAction)
> prevAction.fadeOut(0)
> 
> ```

you could try `action1.crossFadeFrom( prevAction, .5)` instead `prevAction.fadeOut(0)`, last parameter is duration in seconds how long it will take to fade from A to B.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [December 22, 2020, 12:40pm UTC](https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857/8 "2020-12-22T12:40:35Z")

</div>

> [@Vaishali\_Valavade](#):
>
> but the previous animation endstate is not being maintained.

Try it with:

> [@GLTF Animations Automatic](https://discourse.threejs.org/t/gltf-animations-automatic/9735/2):
>
> One approach to solve this is to register an event listener to the animation mixer’s finished event. mixer.addEventListener( 'finished', ( event ) =\> { console.log( 'Finished animation action: ', event.action ); // start next animation }); In this way, you automatically know when an animation action has finished its playback and then start the next one.

---

<div class="post-metadata">

**Author:** ![Vaishali\_Valavade](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/vaishali_valavade/32/15283_2.png) [@Vaishali\_Valavade](https://discourse.threejs.org/u/Vaishali_Valavade)\
**Post date:** [December 22, 2020, 1:00pm UTC](https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857/9 "2020-12-22T13:00:40Z")

</div>

Okay will give it a try.

---

<div class="post-metadata">

**Author:** ![Vaishali\_Valavade](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/vaishali_valavade/32/15283_2.png) [@Vaishali\_Valavade](https://discourse.threejs.org/u/Vaishali_Valavade)\
**Post date:** [December 24, 2020, 7:10am UTC](https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857/10 "2020-12-24T07:10:00Z")

</div>

The solutions specified are not working for me.  
I am now trying a different approach. I have the gltf file with a single animation.  
So now is there any way that I can play this animation from “x” seconds to “y” seconds of the entire clip duration?

I can set the starttime by action.time = {startTime}. but how can i play the animation till endTime only?

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [December 24, 2020, 10:38am UTC](https://discourse.threejs.org/t/how-to-sequentially-play-gltf-animation-on-button-click-with-previous-animation-endstate-intact/21857/11 "2020-12-24T10:38:02Z")

</div>

@Vaishali_Valavade

You can create subclips from the animation that run from too set frames using animationUtils

```
 https://threejs.org/docs/#api/en/animation/AnimationUtils
```
