playdate.graphics.animator:valueAtTime(time) can cause the animator to end, breaking return values for subsequent calls

If the 'time' value passed to this function exceeds the duration of the animator, the animator will flag itself as ended, even if the requisite time hasn't passed. This feels like strange behavior, it seems to me that valueAtTime should purely be a getter function without any side-effects, and should ignore the animator's didend flag.

I assume the call to checkTime is to get a value for 'time' that takes repeats into consideration, but that same call will flag didend as true.

The effect this has specifically is that as soon as the animator is flagged as ended, all calls to valueAtTime will return the final value of the animator.

Consider the following code:

local animator = playdate.graphics.animator.new(5000, 0, 10)  -- animate from 0 to 10 over 5 seconds
local t10 = animator:valueAtTime(10000)  -- arbitrary check of value over duration. Expected output: 10
local t1 = animator:valueAtTime(1000)  -- arbitrary check of value under duration. Expected output: 2
print("TEST", t10, t1)  -- output: "TEST	10	10"

Similarly, after a single call of :ended() after the animator's intended duration has passed, valueAtTime with any value for the time argument will return the last value of the animator, which is also not expected.

Bonus bugreport, the 2.2.0 documentation for valueAtTime says that time argument should be in seconds, but it expects millliseconds.
Bonusbonus, in valueAtTime, the 'time' variable used is a global (though this has been reported elsewhere already)

2 Likes