3

I am using tweenjs and Typescript to change the x and y coordinates of a three.js cube. I created the following tween to change the x position of an item of class "FallingItem".

this.movementArcData.horzTween = new TWEEN.Tween(this.movementArcData.pos.x)
                .to(this.movementArcData.newPos.x, this.movementArcData.movementTime * 1000)
                .onUpdate(this.updateXPos)
                .onComplete(this.horzTweenComplete);

where "this.movementArcData" is an object containing the following:

  • horzTween - the tween itself
  • pos.x - the original position of the item

  • movementTime - the time it takes to complete the movement, 2000 milliseconds

  • updateXPos - a member function of the a FallingItem object with the following code:

    updateXPos(){ this.mesh.position.x = this.movementArcData.pos.x; console.log("update x: " + this.movementArcData.pos.x); }

horzTweenComplete - a member funtion of the FallingItem object with the following code:

horzTweenComplete(){
    this.movementArcData.horzTweenComplete = true;
}

Neither the updateXPos or horzTweenComplete callback is getting fired.

I am calling TWEEN.update in my render loop like so:

TWEEN.update(dt);

Since the tween's onComplete event never fires, the TWEEN.update is called constantly. What am I missing that is causing the tween not to work properly?

reggie3
  • 1,018
  • 2
  • 15
  • 22

3 Answers3

6

I had a similar case when TWEEN was not calling my onUpdate function. Found out I had to call window.requestAnimationFrame() in order to tell the browser that I, i.e. TWEEN, "want to perform an animation and requests that the browser call a specified function to update an animation before the next repaint."

function animate(time) {
    window.requestAnimationFrame(animate);
    TWEEN.update(time);
}

new TWEEN
        .Tween({ y: 0 })
        .to({y: 1000}, 700)
        .easing(TWEEN.Easing.Exponential.InOut)
        .onUpdate(function () {
            window.scrollTo(0, this.y);
        })
        .start();

animate();

The above example was taken from https://github.com/tweenjs/tween.js/blob/master/examples/00_hello_world.html.

esengineer
  • 9,514
  • 7
  • 45
  • 69
  • 1
    Thanks for your answer... it helped remind me that I needed to add TWEEN.update() into my animation loop. Too much programming today methinks :) – Michael Paccione May 30 '19 at 15:53
4

Tween.js needs to be passed the elapsed time, not a delta time. Passing a running elapsed time fixed the problem.

Also, it's supposed to be passed an object containing the value you want interpolated. It looks like passing the value itself doesn't work. I had success with this:

let tweenElement = {
                x: this.tweenInfo.pos.x,
                y: this.tweenInfo.pos.y,
                item: this
            }

this.tweenInfo.tweenUp = new TWEEN.Tween(tweenElement)
                .to({y : this.tweenInfo.newPos.y}
                    , this.tweenInfo.movementTime * 0.5 * 1000)
                .easing( TWEEN.Easing.Cubic.InOut )
                .onUpdate(function(){
                    this.item.updateYPos(tweenElement, this)
                })
                .onComplete(function(){
                    this.item.tweenUpComplete();
                });
reggie3
  • 1,018
  • 2
  • 15
  • 22
  • This should be the correct answer. I'm using pixi and wanted to call TWEEN.update in app.ticker.add(...) and not in requestAnimationFrame(). – M'λ' Apr 04 '20 at 10:18
0

Another potential cause (I know probably not in this particular case) is that TWEEN.removeAll() is being called somewhere else in the code. One sign of this happening is that other tweens are working perfectly fine but some are not.

zzazzles
  • 117
  • 1
  • 9