Three.js补间问题:起始值始终保持不变

Three.js Tweening issue: start value always remains the same

我的 camera.position 补间有问题。我用最少的代码创建了一个代码笔,只是为了重现我的问题,并注释了我的所有代码。我还放了很多 console.log() 用于调试目的。

Codepen

起点是我的camera.postion

camera.position.z = 30;

和我的 tween001

    var tween001 = gsap.to(camera.position,{ delay:2,duration:5,z:60,onUpdate:function(){
    camera.updateProjectionMatrix();
    console.log("play");
  },onComplete:function(){console.log("complete");},ease:"elastic"});

所以补间即将把我的相机从 Z = 30 移动到 Z = 60

它的工作完美但是......当用户移动相机时用户move/over/click在3d上它的火和事件监听器暂停“tween001.pause()”我想要tween001使用“实际”camera.postion 而不是当补间 001 着火时使用 camera.postion。

因为当再次播放 tween001 或从暂停恢复时,使用的起点是默认起点 x=0 y=0 z=30 .

空闲函数再次播放 tween001

window.setInterval(checkTime, 1000);// every 1 second launch checktime()

  function checkTime() { //idleCounter get 1 every second and at 5 second coz timeout is 5 checktime relaunch the tween001
    if (idlecounter < timeout) {
      idlecounter++;

      //console.log("++ ");
    } else if (idlecounter == timeout) {
      tween001.play();
      console.log('timeout');
    }
  }

所以你必须明白 GSAP 假定它是唯一控制 camera.position 的东西。因此,当您声明 gsap.to(camera.position, {z: 60}) 时,它将在内部存储起始位置 (30) 和结束位置 (60) 以构建其时间线。它不知道您已经用鼠标滚轮更改了 z-position,所以当您调用 .play() 时,它仍然会假定您想要从 30 转到 60。

你需要做的是每次re-initialize一个新的补间,所以当你想重播它时它必须查找起始位置:

var tween001;
function doTween() {
    tween001 = gsap.to(camera.position, { delay:2,duration:5, z:60, ease:"elastic", onComplete:function(){
      // camera.updateProjectionMatrix();
      console.log("complete");
    }});
}
  • 请注意,我在函数外部声明了 var tween001,在全局范围内,因此您仍然可以在需要时调用 tween001.pause()
  • 改变位置时无需更新投影矩阵。

现在,当您准备好再次开始动画时,您可以调用 doTween() 而不是使用 tween001.play(),它将构建一个新的时间轴,re-reads 相机的当前 z-position 开始动画:

// ...
else if (idlecounter == timeout) {
    doTween();
    idlecounter = 0;
}

see here for the updated codepen