diff --git a/lib/ui/geometry.dart b/lib/ui/geometry.dart index cc53d4415274a..e4bb57ec5096c 100644 --- a/lib/ui/geometry.dart +++ b/lib/ui/geometry.dart @@ -263,7 +263,20 @@ class Offset extends OffsetBase { /// Linearly interpolate between two offsets. /// /// If either offset is null, this function interpolates from [Offset.zero]. + /// + /// The `t` argument represents position on the timeline, with 0.0 meaning + /// that the interpolation has not started, returning `a` (or something + /// equivalent to `a`), 1.0 meaning that the interpolation has finished, + /// returning `b` (or something equivalent to `b`), and values in between + /// meaning that the interpolation is at the relevant point on the timeline + /// between `a` and `b`. The interpolation can be extrapolated beyond 0.0 and + /// 1.0, so negative values and values greater than 1.0 are valid (and can + /// easily be generated by curves such as [Curves.elasticInOut]). + /// + /// Values for `t` are usually obtained from an [Animation], such as + /// an [AnimationController]. static Offset lerp(Offset a, Offset b, double t) { + assert(t != null); if (a == null && b == null) return null; if (a == null) @@ -490,7 +503,20 @@ class Size extends OffsetBase { /// Linearly interpolate between two sizes /// /// If either size is null, this function interpolates from [Size.zero]. + /// + /// The `t` argument represents position on the timeline, with 0.0 meaning + /// that the interpolation has not started, returning `a` (or something + /// equivalent to `a`), 1.0 meaning that the interpolation has finished, + /// returning `b` (or something equivalent to `b`), and values in between + /// meaning that the interpolation is at the relevant point on the timeline + /// between `a` and `b`. The interpolation can be extrapolated beyond 0.0 and + /// 1.0, so negative values and values greater than 1.0 are valid (and can + /// easily be generated by curves such as [Curves.elasticInOut]). + /// + /// Values for `t` are usually obtained from an [Animation], such as + /// an [AnimationController]. static Size lerp(Size a, Size b, double t) { + assert(t != null); if (a == null && b == null) return null; if (a == null) @@ -739,7 +765,20 @@ class Rect { /// Linearly interpolate between two rectangles. /// /// If either rect is null, [Rect.zero] is used as a substitute. + /// + /// The `t` argument represents position on the timeline, with 0.0 meaning + /// that the interpolation has not started, returning `a` (or something + /// equivalent to `a`), 1.0 meaning that the interpolation has finished, + /// returning `b` (or something equivalent to `b`), and values in between + /// meaning that the interpolation is at the relevant point on the timeline + /// between `a` and `b`. The interpolation can be extrapolated beyond 0.0 and + /// 1.0, so negative values and values greater than 1.0 are valid (and can + /// easily be generated by curves such as [Curves.elasticInOut]). + /// + /// Values for `t` are usually obtained from an [Animation], such as + /// an [AnimationController]. static Rect lerp(Rect a, Rect b, double t) { + assert(t != null); if (a == null && b == null) return null; if (a == null) @@ -752,7 +791,7 @@ class Rect { lerpDouble(a.left, b.left, t), lerpDouble(a.top, b.top, t), lerpDouble(a.right, b.right, t), - lerpDouble(a.bottom, b.bottom, t) + lerpDouble(a.bottom, b.bottom, t), ); } @@ -851,7 +890,20 @@ class Radius { /// Linearly interpolate between two radii. /// /// If either is null, this function substitutes [Radius.zero] instead. + /// + /// The `t` argument represents position on the timeline, with 0.0 meaning + /// that the interpolation has not started, returning `a` (or something + /// equivalent to `a`), 1.0 meaning that the interpolation has finished, + /// returning `b` (or something equivalent to `b`), and values in between + /// meaning that the interpolation is at the relevant point on the timeline + /// between `a` and `b`. The interpolation can be extrapolated beyond 0.0 and + /// 1.0, so negative values and values greater than 1.0 are valid (and can + /// easily be generated by curves such as [Curves.elasticInOut]). + /// + /// Values for `t` are usually obtained from an [Animation], such as + /// an [AnimationController]. static Radius lerp(Radius a, Radius b, double t) { + assert(t != null); if (a == null && b == null) return null; if (a == null) @@ -862,7 +914,7 @@ class Radius { } return new Radius.elliptical( lerpDouble(a.x, b.x, t), - lerpDouble(a.y, b.y, t) + lerpDouble(a.y, b.y, t), ); } @@ -1355,7 +1407,20 @@ class RRect { /// Linearly interpolate between two rounded rectangles. /// /// If either is null, this function substitutes [RRect.zero] instead. + /// + /// The `t` argument represents position on the timeline, with 0.0 meaning + /// that the interpolation has not started, returning `a` (or something + /// equivalent to `a`), 1.0 meaning that the interpolation has finished, + /// returning `b` (or something equivalent to `b`), and values in between + /// meaning that the interpolation is at the relevant point on the timeline + /// between `a` and `b`. The interpolation can be extrapolated beyond 0.0 and + /// 1.0, so negative values and values greater than 1.0 are valid (and can + /// easily be generated by curves such as [Curves.elasticInOut]). + /// + /// Values for `t` are usually obtained from an [Animation], such as + /// an [AnimationController]. static RRect lerp(RRect a, RRect b, double t) { + assert(t != null); if (a == null && b == null) return null; if (a == null) { @@ -1371,7 +1436,7 @@ class RRect { b.brRadiusX * t, b.brRadiusY * t, b.blRadiusX * t, - b.blRadiusY * t + b.blRadiusY * t, ]); } if (b == null) { @@ -1388,7 +1453,7 @@ class RRect { a.brRadiusX * k, a.brRadiusY * k, a.blRadiusX * k, - a.blRadiusY * k + a.blRadiusY * k, ]); } return new RRect._fromList([ @@ -1403,7 +1468,7 @@ class RRect { lerpDouble(a.brRadiusX, b.brRadiusX, t), lerpDouble(a.brRadiusY, b.brRadiusY, t), lerpDouble(a.blRadiusX, b.blRadiusX, t), - lerpDouble(a.blRadiusY, b.blRadiusY, t) + lerpDouble(a.blRadiusY, b.blRadiusY, t), ]); } diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index 366afb120d8fb..70e5570f37690 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -223,15 +223,28 @@ class Color { /// Linearly interpolate between two colors. /// - /// If either color is null, this function linearly interpolates from a - /// transparent instance of the other color. - /// - /// Values of `t` less that 0.0 or greater than 1.0 are supported. Each - /// channel will be clamped to the range 0 to 255. - /// /// This is intended to be fast but as a result may be ugly. Consider /// [HSVColor] or writing custom logic for interpolating colors. + /// + /// If either color is null, this function linearly interpolates from a + /// transparent instance of the other color. This is usually preferable to + /// interpolating from [Colors.transparent] (`const Color(0x00000000)`), which + /// is specifically transparent _black_. + /// + /// The `t` argument represents position on the timeline, with 0.0 meaning + /// that the interpolation has not started, returning `a` (or something + /// equivalent to `a`), 1.0 meaning that the interpolation has finished, + /// returning `b` (or something equivalent to `b`), and values in between + /// meaning that the interpolation is at the relevant point on the timeline + /// between `a` and `b`. The interpolation can be extrapolated beyond 0.0 and + /// 1.0, so negative values and values greater than 1.0 are valid (and can + /// easily be generated by curves such as [Curves.elasticInOut]). Each channel + /// will be clamped to the range 0 to 255. + /// + /// Values for `t` are usually obtained from an [Animation], such as + /// an [AnimationController]. static Color lerp(Color a, Color b, double t) { + assert(t != null); if (a == null && b == null) return null; if (a == null) diff --git a/lib/ui/text.dart b/lib/ui/text.dart index 8cd6a447ec604..2194c51bdd72b 100644 --- a/lib/ui/text.dart +++ b/lib/ui/text.dart @@ -62,8 +62,25 @@ class FontWeight { /// /// Rather than using fractional weights, the interpolation rounds to the /// nearest weight. - static FontWeight lerp(FontWeight begin, FontWeight end, double t) { - return values[lerpDouble(begin?.index ?? normal.index, end?.index ?? normal.index, t.clamp(0.0, 1.0)).round()]; + /// + /// Any null values for `a` or `b` are interpreted as equivalent to [normal] + /// (also known as [w400]). + /// + /// The `t` argument represents position on the timeline, with 0.0 meaning + /// that the interpolation has not started, returning `a` (or something + /// equivalent to `a`), 1.0 meaning that the interpolation has finished, + /// returning `b` (or something equivalent to `b`), and values in between + /// meaning that the interpolation is at the relevant point on the timeline + /// between `a` and `b`. The interpolation can be extrapolated beyond 0.0 and + /// 1.0, so negative values and values greater than 1.0 are valid (and can + /// easily be generated by curves such as [Curves.elasticInOut]). The result + /// is clamped to the range [w100]–[w900]. + /// + /// Values for `t` are usually obtained from an [Animation], such as + /// an [AnimationController]. + static FontWeight lerp(FontWeight a, FontWeight b, double t) { + assert(t != null); + return values[lerpDouble(a?.index ?? normal.index, b?.index ?? normal.index, t).round().clamp(0, 8)]; } String toString() {