advance method
bool
advance(
- double elapsedSeconds, {
- KeyedCallbackReporter? callbackReporter,
})
Implementation
bool advance(double elapsedSeconds,
{KeyedCallbackReporter? callbackReporter}) {
var deltaSeconds = elapsedSeconds * animation.speed * _direction;
_spilledTime = 0;
if (deltaSeconds == 0) {
_didLoop = false;
return true;
}
_lastTotalTime = _totalTime;
_totalTime += deltaSeconds.abs();
// NOTE:
// do not track spilled time, if our one shot loop is already completed.
// stop gap before we move spilled tracking into state machine logic.
var killSpilledTime = !keepGoing;
var lastTime = _time;
_time += deltaSeconds;
if (callbackReporter != null) {
animation.reportKeyedCallbacks(
lastTime,
_time,
reporter: callbackReporter,
);
}
var fps = animation.fps;
double frames = _time * fps;
var start = animation.enableWorkArea ? animation.workStart : 0;
var end = animation.enableWorkArea ? animation.workEnd : animation.duration;
var range = end - start;
bool didLoop = false;
int direction = deltaSeconds < 0 ? -1 : 1;
switch (animation.loop) {
case Loop.oneShot:
if (direction == 1 && frames > end) {
_spilledTime = (frames - end) / fps;
frames = end.toDouble();
_time = frames / fps;
didLoop = true;
} else if (direction == -1 && frames < start) {
_spilledTime = (start - frames) / fps;
frames = start.toDouble();
_time = frames / fps;
didLoop = true;
}
break;
case Loop.loop:
if (direction == 1 && frames >= end) {
_spilledTime = (frames - end) / fps;
frames = _time * fps;
frames = start + (frames - start) % range;
lastTime = 0;
_time = frames / fps;
if (callbackReporter != null) {
animation.reportKeyedCallbacks(
lastTime,
_time,
reporter: callbackReporter,
);
}
didLoop = true;
} else if (direction == -1 && frames <= start) {
_spilledTime = (start - frames) / fps;
frames = _time * fps;
frames = end - (start - frames) % range;
lastTime = end / fps;
_time = frames / fps;
if (callbackReporter != null) {
animation.reportKeyedCallbacks(
lastTime,
_time,
reporter: callbackReporter,
);
}
didLoop = true;
}
break;
case Loop.pingPong:
// ignore: literal_only_boolean_expressions
while (true) {
if (direction == 1 && frames >= end) {
_spilledTime = (frames - end) / animation.fps;
lastTime = end / fps;
frames = end + (end - frames);
} else if (direction == -1 && frames < start) {
_spilledTime = (start - frames) / animation.fps;
lastTime = start / fps;
frames = start + (start - frames);
} else {
// we're within the range, we can stop fixing. We do this in a
// loop to fix conditions when time has advanced so far that we've
// ping-ponged back and forth a few times in a single frame. We
// want to accomodate for this in cases where animations are not
// advanced on regular intervals.
break;
}
_time = frames / animation.fps;
_direction *= -1;
direction *= -1;
didLoop = true;
if (callbackReporter != null) {
animation.reportKeyedCallbacks(
lastTime,
_time,
reporter: callbackReporter,
);
}
}
break;
}
if (killSpilledTime) {
_spilledTime = 0;
}
_didLoop = didLoop;
return keepGoing;
}