diff --git a/packages/flutter/lib/src/animation/animation_controller.dart b/packages/flutter/lib/src/animation/animation_controller.dart index 27919f2c1bb6..b3bcb3513b20 100644 --- a/packages/flutter/lib/src/animation/animation_controller.dart +++ b/packages/flutter/lib/src/animation/animation_controller.dart @@ -919,7 +919,7 @@ typedef _DirectionSetter = void Function(_AnimationDirection direction); class _RepeatingSimulation extends Simulation { _RepeatingSimulation(double initialValue, this.min, this.max, this.reverse, Duration period, this.directionSetter) : _periodInSeconds = period.inMicroseconds / Duration.microsecondsPerSecond, - _initialT = (max == min) ? 0.0 : (initialValue / (max - min)) * (period.inMicroseconds / Duration.microsecondsPerSecond) { + _initialT = (max == min) ? 0.0 : ((clampDouble(initialValue, min, max) - min) / (max - min)) * (period.inMicroseconds / Duration.microsecondsPerSecond) { assert(_periodInSeconds > 0.0); assert(_initialT >= 0.0); } diff --git a/packages/flutter/test/animation/animation_controller_test.dart b/packages/flutter/test/animation/animation_controller_test.dart index 725a44fb7aa2..c2112762946d 100644 --- a/packages/flutter/test/animation/animation_controller_test.dart +++ b/packages/flutter/test/animation/animation_controller_test.dart @@ -763,8 +763,8 @@ void main() { ); test( - 'calling repeat with specified min and max values makes the animation ' - 'alternate between min and max values on each repeat', + 'calling repeat with specified min and max values between 0 and 1 makes ' + 'the animation alternate between min and max values on each repeat', () { final AnimationController controller = AnimationController( duration: const Duration(milliseconds: 100), @@ -799,6 +799,47 @@ void main() { tick(Duration.zero); tick(const Duration(milliseconds: 125)); expect(controller.value, 1.0); + + controller.reset(); + controller.value = 0.2; + expect(controller.value, 0.2); + + controller.repeat(reverse: true, min: 0.2, max: 0.6); + tick(Duration.zero); + tick(const Duration(milliseconds: 50)); + expect(controller.value, 0.4); + controller.dispose(); + }, + ); + + test( + 'calling repeat with negative min value and positive max value makes the ' + 'animation alternate between min and max values on each repeat', + () { + final AnimationController controller = AnimationController( + duration: const Duration(milliseconds: 100), + value: 1.0, + lowerBound: -1, + upperBound: 3, + vsync: const TestVSync(), + ); + + expect(controller.value, 1.0); + + controller.repeat(min: 1, max: 3); + tick(Duration.zero); + expect(controller.value, 1); + tick(const Duration(milliseconds: 50)); + expect(controller.value, 2); + + controller.reset(); + controller.value = 0.0; + + controller.repeat(min: -1, max: 3); + tick(Duration.zero); + expect(controller.value, 0); + tick(const Duration(milliseconds: 25)); + expect(controller.value, 1); controller.dispose(); }, );