javascript - Tween.js anropar inte onUpdate-funktionen


Jag använder tweenjs och Typescript för att ändra x- och y-koordinaterna för en three.js-kub. Jag skapade följande tween för att ändra x-positionen för ett objekt av klassen "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);

där "this.movementArcData" är ett objekt som innehåller följande:

  • horzTween - själva tweenen
  • pos.x - artikelns ursprungliga position

  • movementTime - den tid det tar att fullfölja rörelsen, 2000 millisekunder

  • updateXPos - en medlemsfunktion av ett FallingItem-objekt med följande kod:

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

horzTweenComplete - en medlemsfunktion av FallingItem-objektet med följande kod:

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

Varken updateXPos eller horzTweenComplete callback triggas.

Jag anropar TWEEN.update i min renderingsloop på följande sätt:

TWEEN.update(dt);

Eftersom tweenens onComplete-händelse aldrig utlöses, kallas TWEEN.update konstant. Vad missar jag som gör att tweenen inte fungerar korrekt?

Svar #1

Jag hade ett liknande fall när TWEEN inte kallade min onUpdate-funktion. Jag upptäckte att jag var tvungen att kalla window.requestAnimationFrame() för att meddela webbläsaren att jag, alltså TWEEN, "vill utföra en animation och begär att webbläsaren ska kalla en specificerad funktion för att uppdatera en animation före nästa omladdning."

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();

Exemplet ovan togs från https://github.com/tweenjs/tween.js/blob/master/examples/00_hello_world.html.

Svar #2

Tween.js behöver få den förflutna tiden, inte en deltatid. Att skicka en löpande förfluten tid löste problemet.

Dessutom ska det ges ett objekt som innehåller värdet du vill interpolera. Det verkar som att det inte fungerar att skicka själva värdet. Jag hade framgång med detta:

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();
                });

Relaterade artiklar