advance method
Advances this controller's internal clock by dt seconds.
If the controller is still running, the return value will be 0. If it
already finished, then the return value will be the "leftover" part of
the dt. That is, the amount of time dt that remains after the
controller has finished. In all cases, the return value can be positive
only when completed == true.
Normally, this method will be called by the owner of the controller class. For example, if the controller is passed to an Effect class, then that class will take care of calling this method as necessary.
Implementation
@override
double advance(double dt) {
if (completed) {
return dt;
}
final t0 = t;
t += dt;
if (alternate && t > _duration / 2 && t0 <= _duration / 2) {
// Transition from forward to backward
final tInForward = _duration / 2 - t0;
final tInBackward = t - _duration / 2;
for (final effect in effects) {
effect.advance(tInForward);
if (tInBackward > 0) {
effect.recede(tInBackward);
}
}
} else if (!alternate || t <= _duration / 2) {
// Forward
for (final effect in effects) {
final effectDuration = effect.controller.duration ?? 0;
if (t0 < effectDuration) {
final t1 = min(t, effectDuration);
effect.advance(t1 - t0);
}
}
} else {
// Backward
for (final effect in effects) {
final effectDuration = effect.controller.duration ?? 0;
final timeInAlt = t0 - _duration / 2;
if (timeInAlt < effectDuration) {
final t1 = min(t - _duration / 2, effectDuration);
effect.recede(t1 - timeInAlt);
}
}
}
if (t >= _duration) {
final surplus = t - _duration;
t = _duration;
return surplus;
}
return 0;
}