Search code examples
three.jstween.js

tween.js rotation starts from beginning each turn instead of rotating for additional degrees


I have chained 4 different tweens to create a loop, and one of the tweens that i want to happen is when loaded gltf model reaches certain y: position i want it to rotate for additional 90 degrees. But currently it just rotates from 0 to 90 degrees everytime it reaches that certain y: position.

...
  var currentRotation = 0;
  const tweenRotation = new TWEEN.Tween({ z: currentRotation })
    .to({ z: currentRotation + MathUtils.degToRad(90) }, 2000) // 2s linear tween for rotating 90dg
    .easing(TWEEN.Easing.Linear.None)
    .onUpdate((rotationFunc) => {
      model.rotation.z = rotationFunc.z;
      currentRotation += MathUtils.degToRad(90);
    })
    .onComplete(() => {
      currentRotation += MathUtils.degToRad(90);
    });
...

I also tried storing the initial rotation value as a

var currentRotation = model.rotation.z;

but it did not work, however when i console.info inside .onUpdate for current rotation it seems like its adding up value each time as expected but keeps teleporting the 0 degree to rotate for 90 degrees everytime. Any help would be appreciated!


Solution

  • I found the solution by delaying the start of chained 2nd tween after first tween gets finished. In that specific time window, rotation happens.

    I also changed the way I wrote for the rotation, now it is in a function. I can now change the degree parameter and just execute the function to add certain degrees each lap as i want.

    tween1.onComplete(() => {
        rotateModel(90);
      }); // after tween1 gets finished rotation happens immediately
    
      let currentRotation = model.rotation.z;
    
      function rotateModel(degrees) {
        var targetRotation = currentRotation + MathUtils.degToRad(degrees);
        var tweenRotation = new TWEEN.Tween({ z: currentRotation })
          .to({ z: targetRotation }, 2000)
          .easing(TWEEN.Easing.Linear.None)
          .onUpdate((rotationFunc) => {
            model.rotation.z = rotationFunc.z;
          })
          .onComplete(() => {
            currentRotation += degrees;
          });
    
        tweenRotation.start();
      }
    
      const tween12 = new TWEEN.Tween(model.position)
        .to({ y: 0 }, 1000)
        .easing(TWEEN.Easing.Circular.InOut)
        .onUpdate((coords) => {
          model.position.y = coords.y;
        });
      tween12.delay(2200); // delayed the start of 2nd tween so it'll rotate in the meantime