Three.js: setAnimationLoop(null) does not call animation.stop()

Created on 18 Jun 2020  路  4Comments  路  Source: mrdoob/three.js

My use of threejs makes little use of animations, and thus I don't need to hammer the CPU/GPU for 60fps if I know that nothing is animating. I wrote a little helper function to do animations in short bursts, only when I know I am playing a clip action:

function shortAnimation(duration) {
    renderer.setAnimationLoop(myRenderFunc);
    setTimeout(function(){ renderer.setAnimationLoop(null); }, duration);   
}

The issue is that this only works once, as setAnimationLoop(null) does not call animation.stop(), which means that a subsequent call to setAnimationLoop(myRenderFunc) calls WebGLAnimation().start(), which immediately returns since isAnimating is still true.

Since the animation var in WebGLRenderer isn't accessible, I am just setting a flag to have myRenderFunc immediately return if I don't need to animate, but I'd prefer to not have the requestAnimationFrame (async) continuing to needlessly fire...

Regression

All 4 comments

So you are assuming that setAnimationLoop(null) stops the animation loop, right? Well, this is not the intended usage of the API since setAnimationLoop() is normally only called once. And null is currently no valid argument.

However, I understand your use case and have to admit that an enhancement would make the API more flexible. It would be possible to check for null and then stop the animation. Something like:

this.setAnimationLoop = function ( callback ) {

    onAnimationFrameCallback = callback;
    xr.setAnimationLoop( callback );

    ( callback === null ) ? animation.stop() :  animation.start();

};

Besides, to really stop the animation loop, it would be necessary to make use of cancelAnimationFrame in WebGLAnimation.stop().

Would this enhancement solve your issue?

The documentation at https://threejs.org/docs/#api/en/renderers/WebGLRenderer.setAnimationLoop specifically says: _"If null is passed it will stop any already ongoing animation."_ ... so, I'm not sure I understand what you mean by "and null is currently no valid argument"?

Your change looks exactly like what I would expect the code to do if null is passed in.

The behavior to stop an animation if null is passed in is implemented in WebGLAnimation and looking back through the history of WebGLRenderer it looks like it used to work this way:

https://github.com/mrdoob/three.js/blob/3fe6cfbde81f97f9eec9ff1040b43189d55421c3/src/renderers/webgl/WebGLAnimation.js#L23-L32

But it looks like in #14126 it was inadvertently removed by wrapping the animation loop function WebGLRenderer.

@shaunco The docs are definitely outdated, sorry. Let me try to make a PR with my proposed change.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

filharvey picture filharvey  路  3Comments

jlaquinte picture jlaquinte  路  3Comments

jack-jun picture jack-jun  路  3Comments

danieljack picture danieljack  路  3Comments

fuzihaofzh picture fuzihaofzh  路  3Comments