fix Curves.bounceInOut math (#22825)
* fix Curves.bounceInOut
* assert maximum slope
diff --git a/packages/flutter/lib/src/animation/curves.dart b/packages/flutter/lib/src/animation/curves.dart
index f1596c5..b9c17ca 100644
--- a/packages/flutter/lib/src/animation/curves.dart
+++ b/packages/flutter/lib/src/animation/curves.dart
@@ -369,7 +369,7 @@
double transform(double t) {
assert(t >= 0.0 && t <= 1.0);
if (t < 0.5)
- return (1.0 - _bounce(1.0 - t)) * 0.5;
+ return (1.0 - _bounce(1.0 - t * 2.0)) * 0.5;
else
return _bounce(t * 2.0 - 1.0) * 0.5 + 0.5;
}
diff --git a/packages/flutter/test/animation/curves_test.dart b/packages/flutter/test/animation/curves_test.dart
index b645c07..ea3da17 100644
--- a/packages/flutter/test/animation/curves_test.dart
+++ b/packages/flutter/test/animation/curves_test.dart
@@ -34,6 +34,29 @@
expect(step.transform(1.0), 1.0);
});
+ void assertMaximumSlope(Curve curve, double maximumSlope) {
+ const double delta = 0.005;
+ for (double x = 0.0; x < 1.0 - delta; x += delta) {
+ final double deltaY = curve.transform(x) - curve.transform(x + delta);
+ assert(deltaY.abs() < delta * maximumSlope, '${curve.toString()} discontinuous at $x');
+ }
+ }
+
+ test('Curve is continuous', () {
+ assertMaximumSlope(Curves.linear, 20.0);
+ assertMaximumSlope(Curves.decelerate, 20.0);
+ assertMaximumSlope(Curves.bounceIn, 20.0);
+ assertMaximumSlope(Curves.bounceOut, 20.0);
+ assertMaximumSlope(Curves.bounceInOut, 20.0);
+ assertMaximumSlope(Curves.elasticOut, 20.0);
+ assertMaximumSlope(Curves.elasticInOut, 20.0);
+ assertMaximumSlope(Curves.ease, 20.0);
+ assertMaximumSlope(Curves.easeIn, 20.0);
+ assertMaximumSlope(Curves.easeOut, 20.0);
+ assertMaximumSlope(Curves.easeInOut, 20.0);
+ assertMaximumSlope(Curves.fastOutSlowIn, 20.0);
+ });
+
void expectStaysInBounds(Curve curve) {
expect(curve.transform(0.0), inInclusiveRange(0.0, 1.0));
expect(curve.transform(0.1), inInclusiveRange(0.0, 1.0));