tweenjs / es6-tween

ES6 version of tween.js
MIT License
186 stars 34 forks source link

Strange output values when using Tween#update manually #80

Closed mildmojo closed 4 years ago

mildmojo commented 4 years ago

I'm using es6-tween in a NodeJS script. I'm trying to evaluate a tween at a custom time using Tween#update, but I'm getting really strange results that are way out of bounds. The same code in the browser outputs better-looking numbers, but they're still incorrect.

(I'd love a way to feed all these options to the library and get a simple tween function back which accepts a time value argument and returns the corresponding domain value, but I didn't see a way to get that in the documentation.)

To reproduce

let tweenVal = 0;

const tween = new TWEEN.Tween({x: 0})
  .to({x: 128}, 1000)
  .easing(TWEEN.Easing.Linear.None)
  .yoyo(true)
  .repeat(Infinity)
  .on('update', val => tweenVal = val.x)
  .start();

for (let t = -1000; t <= 3500; t += 500) {
  // Have to set preserve to `false` to keep tween from stopping,
  // and forceTime to `true` to get tween to run at all.
  tween.update(t, false, true);
  console.log(`at t=${t}: ${tweenVal}`);
}

https://jsfiddle.net/ds5h17fo/7/

Expected behavior

Given a linear tween from 0 to 128 over a duration of 1000 with .repeat(Infinity) and .yoyo(true), I expect that calling Tween#update will trigger update events with output values like the following, on every platform:

at t=-1000: 128
at t=-500: 64
at t=0: 0
at t=500: 64
at t=1000: 128
at t=1500: 64
at t=2000: 0
at t=2500: 64
at t=3000: 128
at t=3500: 64

Actual behavior

Firefox Developer Edition 72.0.1 (64-bit), Linux Mint 18.3.

NOTE: outputs for time values less than the duration (-1000 thru 1000 here) are not stable, and change every time (!?) you execute the script. I tried a few durations, and it's always the times under the duration that emit strange outputs. Even stable values past the duration time are incorrect, acting as if the time is offset by 500 here.

at t=-1000: -154.496
at t=-500: -90.496
at t=0: -26.496
at t=500: 37.504
at t=1000: 101.504
at t=1500: 128
at t=2000: 64
at t=2500: 0
at t=3000: 64
at t=3500: 128

NodeJS 10.19.0 and 12.15.0, same platform:

NOTE: output values increase with every execution.

at t=-1000: -25912755.214790147
at t=-500: -25912691.214790147
at t=0: -25912627.214790147
at t=500: -25912563.214790147
at t=1000: -25912499.214790147
at t=1500: -25912435.214790147
at t=2000: -25912371.214790147
at t=2500: -25912307.214790147
at t=3000: -25912243.214790147
at t=3500: -25912179.214790147
mikebolt commented 4 years ago

It might be a problem with the requestAnimationFrame loop code. Could you post that part?

On Sat, Feb 8, 2020 at 6:12 PM Tim notifications@github.com wrote:

I'm using es6-tween in a NodeJS script. I'm trying to evaluate a tween at a custom time using Tween#update, but I'm getting really strange results that are way out of bounds. The same code in the browser outputs better-looking numbers, but they're still incorrect.

(I'd love a way to feed all these options to the library and get a simple tween function back which accepts a time value argument and returns the corresponding domain value, but I didn't see a way to get that in the documentation.) To reproduce

let tweenVal = 0;

const tween = new TWEEN.Tween({x: 0}) .to({x: 128}, 1000) .easing(TWEEN.Easing.Linear.None) .yoyo(true) .repeat(Infinity) .on('update', val => tweenVal = val.x) .start();

for (let t = -1000; t <= 3500; t += 500) { // Have to set preserve to false to keep tween from stopping, // and forceTime to true to get tween to run at all. tween.update(t, false, true); console.log(at t=${t}: ${tweenVal}); }

https://jsfiddle.net/ds5h17fo/7/ Expected behavior

Given a linear tween from 0 to 128 over a duration of 1000 with .repeat(Infinity) and .yoyo(true), I expect that calling Tween#update will trigger update events with output values like the following, on every platform:

at t=-1000: 128 at t=-500: 64 at t=0: 0 at t=500: 64 at t=1000: 128 at t=1500: 64 at t=2000: 0 at t=2500: 64 at t=3000: 128 at t=3500: 64

Actual behavior

Firefox Developer Edition 72.0.1 (64-bit), Linux Mint 18.3.

NOTE: outputs for time values less than the duration (-1000 thru 1000 here) are not stable, and change every time (!?) you execute the script. I tried a few durations, and it's always the times under the duration that emit strange outputs. Even stable values past the duration time are incorrect, acting as if the time is offset by 500 here.

at t=-1000: -154.496 at t=-500: -90.496 at t=0: -26.496 at t=500: 37.504 at t=1000: 101.504 at t=1500: 128 at t=2000: 64 at t=2500: 0 at t=3000: 64 at t=3500: 128

NodeJS 10.19.0 and 12.15.0, same platform:

NOTE: output values increase with every execution.

at t=-1000: -25912755.214790147 at t=-500: -25912691.214790147 at t=0: -25912627.214790147 at t=500: -25912563.214790147 at t=1000: -25912499.214790147 at t=1500: -25912435.214790147 at t=2000: -25912371.214790147 at t=2500: -25912307.214790147 at t=3000: -25912243.214790147 at t=3500: -25912179.214790147

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/tweenjs/es6-tween/issues/80?email_source=notifications&email_token=AAQJVP2WQRCKZYDQK7PED73RB5RBBA5CNFSM4KR6QH52YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4IMBDGGQ, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQJVP6ZPT3X3Z45IF4NA6LRB5RBBANCNFSM4KR6QH5Q .

mildmojo commented 4 years ago

Oh, this is the complete reproduction code; I'm not using requestAnimationFrame. I'm trying to evaluate the tween at arbitrary time values. In my actual code, I have a custom time accumulator that I'm providing as t.

I just found a workaround that works in limited testing, but I don't know why it works. If I store a timestamp when the script starts and offset my t by that value, it looks like I get stable and correct output in Node and Firefox:

now = Date.now();
for (let t = -1000; t <= 3500; t += 500) {
  tween.update(t + now, false, true);
  console.log(`at t=${t}: ${tweenVal}`);
}
mikebolt commented 4 years ago

Make sure to pass a starting time to start() when you're using custom timestamps. So, change start() to start(0).

There is no "on" function. You need to use onUpdate(callback).

I recommend reading this: https://mikebolt.me/article/understanding-tweenjs.html

mildmojo commented 4 years ago

Thanks for the link! I was going by your API documentation and your wiki, which shows on but not onUpdate.

Trying it out, .start(0) seems to work great; I didn't realize the argument was sort of like scheduling a tween to start.

My tween objects don't seem to have an .onUpdate, only on and once like the API docs show. You can test it by modifying the fiddle I linked above. That's fine, though, .on('update', callback) seems to work. I'm using es6-tween v5.5.10 from npm, which also looks like the latest release on this repo's releases page.

mikebolt commented 4 years ago

Hi. Sorry for the confusion. I thought this issue was posted in https://github.com/tweenjs/tween.js. It's a different library.

dalisoft commented 4 years ago

@mikebolt Thanks for help, even confused, you helped user fix their bug

dalisoft commented 4 years ago

@mildmojo Is the issue was solved or still issue for you?

mildmojo commented 4 years ago

@dalisoft @mikebolt I think the issue's solved enough for my workflow. I don't get the right output when I provide negative time values, but I can limit my usage to positive-only. Thanks for your help, and for being so fast to respond!

Here's the updated NodeJS test and results:

const TWEEN = require('es6-tween');

let tweenVal = 0;

const tween = new TWEEN.Tween({x: 0})
  .to({x: 128}, 1000)
  .easing(TWEEN.Easing.Linear.None)
  .yoyo(true)
  .repeat(Infinity)
  .on('update', val => tweenVal = val.x)
  .start(0);

for (let t = -2000; t <= 3500; t += 500) {
  tween.update(t, false, true);
  console.log(`at t=${t}: ${tweenVal}`);
}
at t=-2000: -256
at t=-1500: -192
at t=-1000: -128
at t=-500: -64
at t=0: 0
at t=500: 64
at t=1000: 128
at t=1500: 64
at t=2000: 0
at t=2500: 64
at t=3000: 128
at t=3500: 64