Clean up lerp() methods and their documentation. (#13684)
This cleans up lerp, lerpFrom, lerpTo, and scale methods, and their
documentation.
Fixes https://github.com/flutter/flutter/issues/12377.
diff --git a/packages/flutter/lib/src/cupertino/route.dart b/packages/flutter/lib/src/cupertino/route.dart
index d651a80..2233493 100644
--- a/packages/flutter/lib/src/cupertino/route.dart
+++ b/packages/flutter/lib/src/cupertino/route.dart
@@ -589,23 +589,39 @@
class _CupertinoEdgeShadowDecoration extends Decoration {
const _CupertinoEdgeShadowDecoration({ this.edgeGradient });
- /// A Decoration with no decorating properties.
+ // An edge shadow decoration where the shadow is null. This is used
+ // for interpolating from no shadow.
static const _CupertinoEdgeShadowDecoration none =
const _CupertinoEdgeShadowDecoration();
- /// A gradient to draw to the left of the box being decorated.
- /// Alignments are relative to the original box translated one box
- /// width to the left.
+ // A gradient to draw to the left of the box being decorated.
+ // Alignments are relative to the original box translated one box
+ // width to the left.
final LinearGradient edgeGradient;
- /// Linearly interpolate between two edge shadow decorations decorations.
- ///
- /// See also [Decoration.lerp].
+ // Linearly interpolate between two edge shadow decorations decorations.
+ //
+ // 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<double>], such as
+ // an [AnimationController].
+ //
+ // See also:
+ //
+ // * [Decoration.lerp].
static _CupertinoEdgeShadowDecoration lerp(
_CupertinoEdgeShadowDecoration a,
_CupertinoEdgeShadowDecoration b,
- double t
+ double t,
) {
+ assert(t != null);
if (a == null && b == null)
return null;
return new _CupertinoEdgeShadowDecoration(
diff --git a/packages/flutter/lib/src/material/theme_data.dart b/packages/flutter/lib/src/material/theme_data.dart
index bbc9056..3821623 100644
--- a/packages/flutter/lib/src/material/theme_data.dart
+++ b/packages/flutter/lib/src/material/theme_data.dart
@@ -519,40 +519,53 @@
/// Linearly interpolate between two themes.
///
/// The arguments must not be null.
- static ThemeData lerp(ThemeData begin, ThemeData end, double t) {
- assert(begin != null);
- assert(end != null);
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
+ static ThemeData lerp(ThemeData a, ThemeData b, double t) {
+ assert(a != null);
+ assert(b != null);
+ assert(t != null);
return new ThemeData.raw(
- brightness: t < 0.5 ? begin.brightness : end.brightness,
- primaryColor: Color.lerp(begin.primaryColor, end.primaryColor, t),
- primaryColorBrightness: t < 0.5 ? begin.primaryColorBrightness : end.primaryColorBrightness,
- canvasColor: Color.lerp(begin.canvasColor, end.canvasColor, t),
- scaffoldBackgroundColor: Color.lerp(begin.scaffoldBackgroundColor, end.scaffoldBackgroundColor, t),
- cardColor: Color.lerp(begin.cardColor, end.cardColor, t),
- dividerColor: Color.lerp(begin.dividerColor, end.dividerColor, t),
- highlightColor: Color.lerp(begin.highlightColor, end.highlightColor, t),
- splashColor: Color.lerp(begin.splashColor, end.splashColor, t),
- selectedRowColor: Color.lerp(begin.selectedRowColor, end.selectedRowColor, t),
- unselectedWidgetColor: Color.lerp(begin.unselectedWidgetColor, end.unselectedWidgetColor, t),
- disabledColor: Color.lerp(begin.disabledColor, end.disabledColor, t),
- buttonColor: Color.lerp(begin.buttonColor, end.buttonColor, t),
- secondaryHeaderColor: Color.lerp(begin.secondaryHeaderColor, end.secondaryHeaderColor, t),
- textSelectionColor: Color.lerp(begin.textSelectionColor, end.textSelectionColor, t),
- textSelectionHandleColor: Color.lerp(begin.textSelectionHandleColor, end.textSelectionHandleColor, t),
- backgroundColor: Color.lerp(begin.backgroundColor, end.backgroundColor, t),
- dialogBackgroundColor: Color.lerp(begin.dialogBackgroundColor, end.dialogBackgroundColor, t),
- accentColor: Color.lerp(begin.accentColor, end.accentColor, t),
- accentColorBrightness: t < 0.5 ? begin.accentColorBrightness : end.accentColorBrightness,
- indicatorColor: Color.lerp(begin.indicatorColor, end.indicatorColor, t),
- hintColor: Color.lerp(begin.hintColor, end.hintColor, t),
- errorColor: Color.lerp(begin.errorColor, end.errorColor, t),
- textTheme: TextTheme.lerp(begin.textTheme, end.textTheme, t),
- primaryTextTheme: TextTheme.lerp(begin.primaryTextTheme, end.primaryTextTheme, t),
- accentTextTheme: TextTheme.lerp(begin.accentTextTheme, end.accentTextTheme, t),
- iconTheme: IconThemeData.lerp(begin.iconTheme, end.iconTheme, t),
- primaryIconTheme: IconThemeData.lerp(begin.primaryIconTheme, end.primaryIconTheme, t),
- accentIconTheme: IconThemeData.lerp(begin.accentIconTheme, end.accentIconTheme, t),
- platform: t < 0.5 ? begin.platform : end.platform
+ brightness: t < 0.5 ? a.brightness : b.brightness,
+ primaryColor: Color.lerp(a.primaryColor, b.primaryColor, t),
+ primaryColorBrightness: t < 0.5 ? a.primaryColorBrightness : b.primaryColorBrightness,
+ canvasColor: Color.lerp(a.canvasColor, b.canvasColor, t),
+ scaffoldBackgroundColor: Color.lerp(a.scaffoldBackgroundColor, b.scaffoldBackgroundColor, t),
+ cardColor: Color.lerp(a.cardColor, b.cardColor, t),
+ dividerColor: Color.lerp(a.dividerColor, b.dividerColor, t),
+ highlightColor: Color.lerp(a.highlightColor, b.highlightColor, t),
+ splashColor: Color.lerp(a.splashColor, b.splashColor, t),
+ selectedRowColor: Color.lerp(a.selectedRowColor, b.selectedRowColor, t),
+ unselectedWidgetColor: Color.lerp(a.unselectedWidgetColor, b.unselectedWidgetColor, t),
+ disabledColor: Color.lerp(a.disabledColor, b.disabledColor, t),
+ buttonColor: Color.lerp(a.buttonColor, b.buttonColor, t),
+ secondaryHeaderColor: Color.lerp(a.secondaryHeaderColor, b.secondaryHeaderColor, t),
+ textSelectionColor: Color.lerp(a.textSelectionColor, b.textSelectionColor, t),
+ textSelectionHandleColor: Color.lerp(a.textSelectionHandleColor, b.textSelectionHandleColor, t),
+ backgroundColor: Color.lerp(a.backgroundColor, b.backgroundColor, t),
+ dialogBackgroundColor: Color.lerp(a.dialogBackgroundColor, b.dialogBackgroundColor, t),
+ accentColor: Color.lerp(a.accentColor, b.accentColor, t),
+ accentColorBrightness: t < 0.5 ? a.accentColorBrightness : b.accentColorBrightness,
+ indicatorColor: Color.lerp(a.indicatorColor, b.indicatorColor, t),
+ hintColor: Color.lerp(a.hintColor, b.hintColor, t),
+ errorColor: Color.lerp(a.errorColor, b.errorColor, t),
+ textTheme: TextTheme.lerp(a.textTheme, b.textTheme, t),
+ primaryTextTheme: TextTheme.lerp(a.primaryTextTheme, b.primaryTextTheme, t),
+ accentTextTheme: TextTheme.lerp(a.accentTextTheme, b.accentTextTheme, t),
+ iconTheme: IconThemeData.lerp(a.iconTheme, b.iconTheme, t),
+ primaryIconTheme: IconThemeData.lerp(a.primaryIconTheme, b.primaryIconTheme, t),
+ accentIconTheme: IconThemeData.lerp(a.accentIconTheme, b.accentIconTheme, t),
+ platform: t < 0.5 ? a.platform : b.platform,
);
}
diff --git a/packages/flutter/lib/src/material/typography.dart b/packages/flutter/lib/src/material/typography.dart
index 0acc9b4..2e131af 100644
--- a/packages/flutter/lib/src/material/typography.dart
+++ b/packages/flutter/lib/src/material/typography.dart
@@ -284,19 +284,36 @@
}
/// Linearly interpolate between two text themes.
- static TextTheme lerp(TextTheme begin, TextTheme end, double t) {
+ ///
+ /// The arguments must not be null.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
+ static TextTheme lerp(TextTheme a, TextTheme b, double t) {
+ assert(a != null);
+ assert(b != null);
+ assert(t != null);
return new TextTheme(
- display4: TextStyle.lerp(begin.display4, end.display4, t),
- display3: TextStyle.lerp(begin.display3, end.display3, t),
- display2: TextStyle.lerp(begin.display2, end.display2, t),
- display1: TextStyle.lerp(begin.display1, end.display1, t),
- headline: TextStyle.lerp(begin.headline, end.headline, t),
- title: TextStyle.lerp(begin.title, end.title, t),
- subhead: TextStyle.lerp(begin.subhead, end.subhead, t),
- body2: TextStyle.lerp(begin.body2, end.body2, t),
- body1: TextStyle.lerp(begin.body1, end.body1, t),
- caption: TextStyle.lerp(begin.caption, end.caption, t),
- button: TextStyle.lerp(begin.button, end.button, t),
+ display4: TextStyle.lerp(a.display4, b.display4, t),
+ display3: TextStyle.lerp(a.display3, b.display3, t),
+ display2: TextStyle.lerp(a.display2, b.display2, t),
+ display1: TextStyle.lerp(a.display1, b.display1, t),
+ headline: TextStyle.lerp(a.headline, b.headline, t),
+ title: TextStyle.lerp(a.title, b.title, t),
+ subhead: TextStyle.lerp(a.subhead, b.subhead, t),
+ body2: TextStyle.lerp(a.body2, b.body2, t),
+ body1: TextStyle.lerp(a.body1, b.body1, t),
+ caption: TextStyle.lerp(a.caption, b.caption, t),
+ button: TextStyle.lerp(a.button, b.button, t),
);
}
diff --git a/packages/flutter/lib/src/painting/alignment.dart b/packages/flutter/lib/src/painting/alignment.dart
index d21fa5d..d153182 100644
--- a/packages/flutter/lib/src/painting/alignment.dart
+++ b/packages/flutter/lib/src/painting/alignment.dart
@@ -84,7 +84,20 @@
/// this is not reflected in the type system). Otherwise, an object
/// representing a combination of both is returned. That object can be turned
/// into a concrete [Alignment] using [resolve].
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static AlignmentGeometry lerp(AlignmentGeometry a, AlignmentGeometry b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
@@ -320,7 +333,20 @@
/// Linearly interpolate between two [Alignment]s.
///
/// If either is null, this function interpolates from [Alignment.center].
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static Alignment lerp(Alignment a, Alignment b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
@@ -498,7 +524,20 @@
/// Linearly interpolate between two [AlignmentDirectional]s.
///
/// If either is null, this function interpolates from [AlignmentDirectional.center].
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static AlignmentDirectional lerp(AlignmentDirectional a, AlignmentDirectional b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
diff --git a/packages/flutter/lib/src/painting/border_radius.dart b/packages/flutter/lib/src/painting/border_radius.dart
index 6439a5a..3656108 100644
--- a/packages/flutter/lib/src/painting/border_radius.dart
+++ b/packages/flutter/lib/src/painting/border_radius.dart
@@ -126,7 +126,20 @@
/// this is not reflected in the type system). Otherwise, an object
/// representing a combination of both is returned. That object can be turned
/// into a concrete [BorderRadius] using [resolve].
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static BorderRadiusGeometry lerp(BorderRadiusGeometry a, BorderRadiusGeometry b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
a ??= BorderRadius.zero;
@@ -467,7 +480,20 @@
/// Linearly interpolate between two [BorderRadius] objects.
///
/// If either is null, this function interpolates from [BorderRadius.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<double>], such as
+ /// an [AnimationController].
static BorderRadius lerp(BorderRadius a, BorderRadius b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
@@ -681,7 +707,20 @@
/// Linearly interpolate between two [BorderRadiusDirectional] objects.
///
/// If either is null, this function interpolates from [BorderRadiusDirectional.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<double>], such as
+ /// an [AnimationController].
static BorderRadiusDirectional lerp(BorderRadiusDirectional a, BorderRadiusDirectional b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
diff --git a/packages/flutter/lib/src/painting/borders.dart b/packages/flutter/lib/src/painting/borders.dart
index d1741b1..0bc4338 100644
--- a/packages/flutter/lib/src/painting/borders.dart
+++ b/packages/flutter/lib/src/painting/borders.dart
@@ -130,11 +130,22 @@
);
}
- /// Creates a copy of this border but with the width scaled by the given factor.
+ /// Creates a copy of this border side description but with the width scaled
+ /// by the factor `t`.
///
- /// Since a zero width is painted as a hairline width rather than no border at
- /// all, the zero factor is special-cased to instead change the style no
- /// [BorderStyle.none].
+ /// The `t` argument represents the multiplicand, or the position on the
+ /// timeline for an interpolation from nothing to `this`, with 0.0 meaning
+ /// that the the object returned should be the nil variant of this object, 1.0
+ /// meaning that no change should be applied, returning `this` (or something
+ /// equivalent to `this`), and other values meaning that the object should be
+ /// multiplied by `t`. Negative values are treated like zero.
+ ///
+ /// Since a zero width is normally painted as a hairline width rather than no
+ /// border at all, the zero factor is special-cased to instead change the
+ /// style no [BorderStyle.none].
+ ///
+ /// Values for `t` are usually obtained from an [Animation<double>], such as
+ /// an [AnimationController].
BorderSide scale(double t) {
assert(t != null);
return new BorderSide(
@@ -186,6 +197,18 @@
/// Linearly interpolate between two border sides.
///
/// The arguments must not be null.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static BorderSide lerp(BorderSide a, BorderSide b, double t) {
assert(a != null);
assert(b != null);
@@ -272,7 +295,7 @@
/// computing their [dimensions].
EdgeInsetsGeometry get dimensions;
- /// Attempts to create a new object that represents the amalgamation of [this]
+ /// Attempts to create a new object that represents the amalgamation of `this`
/// border and the `other` border.
///
/// If the type of the other border isn't known, or the given instance cannot
@@ -297,10 +320,32 @@
return add(other) ?? other.add(this, reversed: true) ?? new _CompoundBorder(<ShapeBorder>[other, this]);
}
- /// Creates a new border with the widths of this border multiplied by `t`.
+ /// Creates a copy of this border, scaled by the factor `t`.
+ ///
+ /// Typically this means scaling the width of the border's side, but it can
+ /// also include scaling other artifacts of the border, e.g. the border radius
+ /// of a [RoundedRectangleBorder].
+ ///
+ /// The `t` argument represents the multiplicand, or the position on the
+ /// timeline for an interpolation from nothing to `this`, with 0.0 meaning
+ /// that the the object returned should be the nil variant of this object, 1.0
+ /// meaning that no change should be applied, returning `this` (or something
+ /// equivalent to `this`), and other values meaning that the object should be
+ /// multiplied by `t`. Negative values are allowed but may be meaningless
+ /// (they correspond to extrapolating the interpolation from this object to
+ /// nothing, and going beyond nothing)
+ ///
+ /// Values for `t` are usually obtained from an [Animation<double>], such as
+ /// an [AnimationController].
+ ///
+ /// See also:
+ ///
+ /// * [BorderSide.scale], which most [ShapeBorder] subclasses defer to for
+ /// the actual computation.
ShapeBorder scale(double t);
- /// Linearly interpolates from `a` to [this].
+ /// Linearly interpolates from another [ShapeBorder] (possibly of another
+ /// class) to `this`.
///
/// When implementing this method in subclasses, return null if this class
/// cannot interpolate from `a`. In that case, [lerp] will try `a`'s [lerpTo]
@@ -309,6 +354,19 @@
/// The base class implementation handles the case of `a` being null by
/// deferring to [scale].
///
+ /// 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 `this` (or something equivalent to `this`), and values in
+ /// between meaning that the interpolation is at the relevant point on the
+ /// timeline between `a` and `this`. 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<double>], such as
+ /// an [AnimationController].
+ ///
/// Instead of calling this directly, use [ShapeBorder.lerp].
@protected
ShapeBorder lerpFrom(ShapeBorder a, double t) {
@@ -317,7 +375,8 @@
return null;
}
- /// Linearly interpolates from [this] to `b`.
+ /// Linearly interpolates from `this` to another [ShapeBorder] (possibly of
+ /// another class).
///
/// This is called if `b`'s [lerpTo] did not know how to handle this class.
///
@@ -328,6 +387,18 @@
/// The base class implementation handles the case of `b` being null by
/// deferring to [scale].
///
+ /// The `t` argument represents position on the timeline, with 0.0 meaning
+ /// that the interpolation has not started, returning `this` (or something
+ /// equivalent to `this`), 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 `this` 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<double>], such as
+ /// an [AnimationController].
+ ///
/// Instead of calling this directly, use [ShapeBorder.lerp].
@protected
ShapeBorder lerpTo(ShapeBorder b, double t) {
@@ -336,19 +407,32 @@
return null;
}
- /// Linearly interpolates from `begin` to `end`.
+ /// Linearly interpolates between two [ShapeBorder]s.
///
- /// This defers to `end`'s [lerpTo] function if `end` is not null. If `end` is
- /// null or if its [lerpTo] returns null, it uses `begin`'s [lerpFrom]
- /// function instead. If both return null, it returns `begin` before `t=0.5`
- /// and `end` after `t=0.5`.
- static ShapeBorder lerp(ShapeBorder begin, ShapeBorder end, double t) {
+ /// This defers to `b`'s [lerpTo] function if `b` is not null. If `b` is
+ /// null or if its [lerpTo] returns null, it uses `a`'s [lerpFrom]
+ /// function instead. If both return null, it returns `a` before `t=0.5`
+ /// and `b` after `t=0.5`.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
+ static ShapeBorder lerp(ShapeBorder a, ShapeBorder b, double t) {
+ assert(t != null);
ShapeBorder result;
- if (end != null)
- result = end.lerpFrom(begin, t);
- if (result == null && begin != null)
- result = begin.lerpTo(end, t);
- return result ?? (t < 0.5 ? begin : end);
+ if (b != null)
+ result = b.lerpFrom(a, t);
+ if (result == null && a != null)
+ result = a.lerpTo(b, t);
+ return result ?? (t < 0.5 ? a : b);
}
/// Create a [Path] that describes the outer edge of the border.
@@ -480,6 +564,7 @@
}
static _CompoundBorder lerp(ShapeBorder a, ShapeBorder b, double t) {
+ assert(t != null);
assert(a is _CompoundBorder || b is _CompoundBorder); // Not really necessary, but all call sites currently intend this.
final List<ShapeBorder> aList = a is _CompoundBorder ? a.borders : <ShapeBorder>[a];
final List<ShapeBorder> bList = b is _CompoundBorder ? b.borders : <ShapeBorder>[b];
diff --git a/packages/flutter/lib/src/painting/box_border.dart b/packages/flutter/lib/src/painting/box_border.dart
index 9f47030..54f4b7a 100644
--- a/packages/flutter/lib/src/painting/box_border.dart
+++ b/packages/flutter/lib/src/painting/box_border.dart
@@ -34,6 +34,8 @@
///
/// * [CircleBorder], the equivalent [ShapeBorder].
circle,
+
+ // Don't add more, instead create a new ShapeBorder.
}
/// Base class for box borders that can paint as rectangle, circles, or rounded
@@ -95,7 +97,20 @@
///
/// For a more flexible approach, consider [ShapeBorder.lerp], which would
/// instead [add] the two sets of sides and interpolate them simultaneously.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static BoxBorder lerp(BoxBorder a, BoxBorder b, double t) {
+ assert(t != null);
if ((a is Border || a == null) && (b is Border || b == null))
return Border.lerp(a, b, t);
if ((a is BorderDirectional || a == null) && (b is BorderDirectional || b == null))
@@ -387,7 +402,6 @@
return null;
}
- /// Creates a new border with the widths of this border multiplied by `t`.
@override
Border scale(double t) {
return new Border(
@@ -398,13 +412,6 @@
);
}
- /// Linearly interpolates from `a` to [this].
- ///
- /// If `a` is null, this defers to [scale].
- ///
- /// If `a` is also a [Border], this uses [Border.lerp].
- ///
- /// Otherwise, it defers to [ShapeBorder.lerpFrom].
@override
ShapeBorder lerpFrom(ShapeBorder a, double t) {
if (a is Border)
@@ -412,13 +419,6 @@
return super.lerpFrom(a, t);
}
- /// Linearly interpolates from [this] to `b`.
- ///
- /// If `b` is null, this defers to [scale].
- ///
- /// If `b` is also a [Border], this uses [Border.lerp].
- ///
- /// Otherwise, it defers to [ShapeBorder.lerpTo].
@override
ShapeBorder lerpTo(ShapeBorder b, double t) {
if (b is Border)
@@ -430,7 +430,20 @@
///
/// If a border is null, it is treated as having four [BorderSide.none]
/// borders.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static Border lerp(Border a, Border b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
@@ -441,7 +454,7 @@
top: BorderSide.lerp(a.top, b.top, t),
right: BorderSide.lerp(a.right, b.right, t),
bottom: BorderSide.lerp(a.bottom, b.bottom, t),
- left: BorderSide.lerp(a.left, b.left, t)
+ left: BorderSide.lerp(a.left, b.left, t),
);
}
@@ -689,7 +702,6 @@
return null;
}
- /// Creates a new border with the widths of this border multiplied by `t`.
@override
BorderDirectional scale(double t) {
return new BorderDirectional(
@@ -700,13 +712,6 @@
);
}
- /// Linearly interpolates from `a` to [this].
- ///
- /// If `a` is null, this defers to [scale].
- ///
- /// If `a` is also a [BorderDirectional], this uses [BorderDirectional.lerp].
- ///
- /// Otherwise, it defers to [ShapeBorder.lerpFrom].
@override
ShapeBorder lerpFrom(ShapeBorder a, double t) {
if (a is BorderDirectional)
@@ -714,13 +719,6 @@
return super.lerpFrom(a, t);
}
- /// Linearly interpolates from [this] to `b`.
- ///
- /// If `b` is null, this defers to [scale].
- ///
- /// If `b` is also a [BorderDirectional], this uses [BorderDirectional.lerp].
- ///
- /// Otherwise, it defers to [ShapeBorder.lerpTo].
@override
ShapeBorder lerpTo(ShapeBorder b, double t) {
if (b is BorderDirectional)
@@ -732,7 +730,20 @@
///
/// If a border is null, it is treated as having four [BorderSide.none]
/// borders.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static BorderDirectional lerp(BorderDirectional a, BorderDirectional b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
@@ -743,7 +754,7 @@
top: BorderSide.lerp(a.top, b.top, t),
end: BorderSide.lerp(a.end, b.end, t),
bottom: BorderSide.lerp(a.bottom, b.bottom, t),
- start: BorderSide.lerp(a.start, b.start, t)
+ start: BorderSide.lerp(a.start, b.start, t),
);
}
diff --git a/packages/flutter/lib/src/painting/box_decoration.dart b/packages/flutter/lib/src/painting/box_decoration.dart
index 43c8a69..8a4f9d2 100644
--- a/packages/flutter/lib/src/painting/box_decoration.dart
+++ b/packages/flutter/lib/src/painting/box_decoration.dart
@@ -200,6 +200,18 @@
/// unmodified. Otherwise, the values are computed by interpolating the
/// properties appropriately.
///
+ /// 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<double>], such as
+ /// an [AnimationController].
+ ///
/// See also:
///
/// * [Decoration.lerp], which can interpolate between any two types of
@@ -208,6 +220,7 @@
/// and which use [BoxDecoration.lerp] when interpolating two
/// [BoxDecoration]s or a [BoxDecoration] to or from null.
static BoxDecoration lerp(BoxDecoration a, BoxDecoration b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
diff --git a/packages/flutter/lib/src/painting/box_shadow.dart b/packages/flutter/lib/src/painting/box_shadow.dart
index 28b8baa..2ef2407 100644
--- a/packages/flutter/lib/src/painting/box_shadow.dart
+++ b/packages/flutter/lib/src/painting/box_shadow.dart
@@ -70,7 +70,20 @@
/// If either box shadow is null, this function linearly interpolates from a
/// a box shadow that matches the other box shadow in color but has a zero
/// offset and a zero blurRadius.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static BoxShadow lerp(BoxShadow a, BoxShadow b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
@@ -81,25 +94,38 @@
color: Color.lerp(a.color, b.color, t),
offset: Offset.lerp(a.offset, b.offset, t),
blurRadius: ui.lerpDouble(a.blurRadius, b.blurRadius, t),
- spreadRadius: ui.lerpDouble(a.spreadRadius, b.spreadRadius, t)
+ spreadRadius: ui.lerpDouble(a.spreadRadius, b.spreadRadius, t),
);
}
/// Linearly interpolate between two lists of box shadows.
///
/// If the lists differ in length, excess items are lerped with null.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static List<BoxShadow> lerpList(List<BoxShadow> a, List<BoxShadow> b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
a ??= <BoxShadow>[];
b ??= <BoxShadow>[];
final List<BoxShadow> result = <BoxShadow>[];
final int commonLength = math.min(a.length, b.length);
- for (int i = 0; i < commonLength; ++i)
+ for (int i = 0; i < commonLength; i += 1)
result.add(BoxShadow.lerp(a[i], b[i], t));
- for (int i = commonLength; i < a.length; ++i)
+ for (int i = commonLength; i < a.length; i += 1)
result.add(a[i].scale(1.0 - t));
- for (int i = commonLength; i < b.length; ++i)
+ for (int i = commonLength; i < b.length; i += 1)
result.add(b[i].scale(t));
return result;
}
diff --git a/packages/flutter/lib/src/painting/colors.dart b/packages/flutter/lib/src/painting/colors.dart
index f1e0d1f..e0a8269 100644
--- a/packages/flutter/lib/src/painting/colors.dart
+++ b/packages/flutter/lib/src/painting/colors.dart
@@ -136,9 +136,30 @@
/// Linearly interpolate between two HSVColors.
///
+ /// The colors are interpolated by interpolating the [alpha], [hue],
+ /// [saturation], and [value] channels separately, which usually leads to a
+ /// more pleasing effect than [Color.lerp] (which interpolates the red, green,
+ /// and blue channels separately).
+ ///
/// If either color is null, this function linearly interpolates from a
- /// transparent instance of the other color.
+ /// transparent instance of the other color. This is usually preferable to
+ /// interpolating from [Colors.transparent] (`const Color(0x00000000)`) since
+ /// that will interpolate from a transparent red and cycle through the hues to
+ /// match the target color, regardless of what that color's hue is.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static HSVColor lerp(HSVColor a, HSVColor b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
@@ -149,7 +170,7 @@
lerpDouble(a.alpha, b.alpha, t),
lerpDouble(a.hue, b.hue, t),
lerpDouble(a.saturation, b.saturation, t),
- lerpDouble(a.value, b.value, t)
+ lerpDouble(a.value, b.value, t),
);
}
diff --git a/packages/flutter/lib/src/painting/decoration.dart b/packages/flutter/lib/src/painting/decoration.dart
index c8b22ce..e27252d 100644
--- a/packages/flutter/lib/src/painting/decoration.dart
+++ b/packages/flutter/lib/src/painting/decoration.dart
@@ -61,7 +61,8 @@
/// Whether this decoration is complex enough to benefit from caching its painting.
bool get isComplex => false;
- /// Linearly interpolates from `a` to [this].
+ /// Linearly interpolates from another [Decoration] (which may be of a
+ /// different class) to `this`.
///
/// When implementing this method in subclasses, return null if this class
/// cannot interpolate from `a`. In that case, [lerp] will try `a`'s [lerpTo]
@@ -71,11 +72,25 @@
/// method uses this as a fallback when two classes can't interpolate between
/// each other.
///
+ /// 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 `this` (or something equivalent to `this`), and values in
+ /// between meaning that the interpolation is at the relevant point on the
+ /// timeline between `a` and `this`. 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<double>], such as
+ /// an [AnimationController].
+ ///
/// Instead of calling this directly, use [Decoration.lerp].
@protected
Decoration lerpFrom(Decoration a, double t) => null;
- /// Linearly interpolates from [this] to `b`.
+ /// Linearly interpolates from `this` to another [Decoration] (which may be of
+ /// a different class).
///
/// This is called if `b`'s [lerpTo] did not know how to handle this class.
///
@@ -87,32 +102,54 @@
/// method uses this as a fallback when two classes can't interpolate between
/// each other.
///
+ /// The `t` argument represents position on the timeline, with 0.0 meaning
+ /// that the interpolation has not started, returning `this` (or something
+ /// equivalent to `this`), 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 `this` 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<double>], such as
+ /// an [AnimationController].
+ ///
/// Instead of calling this directly, use [Decoration.lerp].
@protected
Decoration lerpTo(Decoration b, double t) => null;
- /// Linearly interpolates from `begin` to `end`.
+ /// Linearly interpolates between two [Decoration]s.
///
- /// This attempts to use [lerpFrom] and [lerpTo] on `end` and `begin`
+ /// This attempts to use [lerpFrom] and [lerpTo] on `b` and `a`
/// respectively to find a solution. If the two values can't directly be
/// interpolated, then the interpolation is done via null (at `t == 0.5`).
///
- /// If the values aren't null, then for `t == 0.0` and `t == 1.0` the values
- /// `begin` and `end` are return verbatim.
- static Decoration lerp(Decoration begin, Decoration end, double t) {
- if (begin == null && end == null)
+ /// 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<double>], such as
+ /// an [AnimationController].
+ static Decoration lerp(Decoration a, Decoration b, double t) {
+ assert(t != null);
+ if (a == null && b == null)
return null;
- if (begin == null)
- return end.lerpFrom(null, t) ?? end;
- if (end == null)
- return begin.lerpTo(null, t) ?? begin;
+ if (a == null)
+ return b.lerpFrom(null, t) ?? b;
+ if (b == null)
+ return a.lerpTo(null, t) ?? a;
if (t == 0.0)
- return begin;
+ return a;
if (t == 1.0)
- return end;
- return end.lerpFrom(begin, t)
- ?? begin.lerpTo(end, t)
- ?? (t < 0.5 ? begin.lerpTo(null, t * 2.0) : end.lerpFrom(null, (t - 0.5) * 2.0));
+ return b;
+ return b.lerpFrom(a, t)
+ ?? a.lerpTo(b, t)
+ ?? (t < 0.5 ? (a.lerpTo(null, t * 2.0) ?? a) : (b.lerpFrom(null, (t - 0.5) * 2.0) ?? b));
}
/// Tests whether the given point, on a rectangle of a given size,
diff --git a/packages/flutter/lib/src/painting/edge_insets.dart b/packages/flutter/lib/src/painting/edge_insets.dart
index 7da8363..652dc06 100644
--- a/packages/flutter/lib/src/painting/edge_insets.dart
+++ b/packages/flutter/lib/src/painting/edge_insets.dart
@@ -189,7 +189,20 @@
/// this is not reflected in the type system). Otherwise, an object
/// representing a combination of both is returned. That object can be turned
/// into a concrete [EdgeInsets] using [resolve].
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static EdgeInsetsGeometry lerp(EdgeInsetsGeometry a, EdgeInsetsGeometry b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
@@ -206,7 +219,7 @@
ui.lerpDouble(a._start, b._start, t),
ui.lerpDouble(a._end, b._end, t),
ui.lerpDouble(a._top, b._top, t),
- ui.lerpDouble(a._bottom, b._bottom, t)
+ ui.lerpDouble(a._bottom, b._bottom, t),
);
}
@@ -542,7 +555,20 @@
/// Linearly interpolate between two [EdgeInsets].
///
/// If either is null, this function interpolates from [EdgeInsets.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<double>], such as
+ /// an [AnimationController].
static EdgeInsets lerp(EdgeInsets a, EdgeInsets b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
@@ -763,7 +789,20 @@
/// To interpolate between two [EdgeInsetsGeometry] objects of arbitrary type
/// (either [EdgeInsets] or [EdgeInsetsDirectional]), consider the
/// [EdgeInsetsGeometry.lerp] static method.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static EdgeInsetsDirectional lerp(EdgeInsetsDirectional a, EdgeInsetsDirectional b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
diff --git a/packages/flutter/lib/src/painting/flutter_logo.dart b/packages/flutter/lib/src/painting/flutter_logo.dart
index 9675c41..29e0b55 100644
--- a/packages/flutter/lib/src/painting/flutter_logo.dart
+++ b/packages/flutter/lib/src/painting/flutter_logo.dart
@@ -125,13 +125,25 @@
///
/// If both values are null, this returns null. Otherwise, it returns a
/// non-null value. If one of the values is null, then the result is obtained
- /// by scaling the other value's opacity and [margin]. If neither value is
- /// null and `t == 0.0`, then `a` is returned unmodified; if `t == 1.0` then
- /// `b` is returned unmodified. Otherwise, the values are computed by
- /// interpolating the properties appropriately.
+ /// by scaling the other value's opacity and [margin].
///
- /// See also [Decoration.lerp].
+ /// 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<double>], such as
+ /// an [AnimationController].
+ ///
+ /// See also:
+ ///
+ /// * [Decoration.lerp], which interpolates between arbitrary decorations.
static FlutterLogoDecoration lerp(FlutterLogoDecoration a, FlutterLogoDecoration b, double t) {
+ assert(t != null);
assert(a == null || a.debugAssertIsValid());
assert(b == null || b.debugAssertIsValid());
if (a == null && b == null)
diff --git a/packages/flutter/lib/src/painting/fractional_offset.dart b/packages/flutter/lib/src/painting/fractional_offset.dart
index 3a97436..0c023fa 100644
--- a/packages/flutter/lib/src/painting/fractional_offset.dart
+++ b/packages/flutter/lib/src/painting/fractional_offset.dart
@@ -177,7 +177,20 @@
/// Linearly interpolate between two [FractionalOffset]s.
///
/// If either is null, this function interpolates from [FractionalOffset.center].
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static FractionalOffset lerp(FractionalOffset a, FractionalOffset b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
diff --git a/packages/flutter/lib/src/painting/gradient.dart b/packages/flutter/lib/src/painting/gradient.dart
index d10edd8..2699ca4 100644
--- a/packages/flutter/lib/src/painting/gradient.dart
+++ b/packages/flutter/lib/src/painting/gradient.dart
@@ -67,7 +67,7 @@
/// Typically this is the same as interpolating from null (with [lerp]).
Gradient scale(double factor);
- /// Linearly interpolates from `a` to [this].
+ /// Linearly interpolates from another [Gradient] to `this`.
///
/// When implementing this method in subclasses, return null if this class
/// cannot interpolate from `a`. In that case, [lerp] will try `a`'s [lerpTo]
@@ -76,6 +76,19 @@
/// If `a` is null, this must not return null. The base class implements this
/// by deferring to [scale].
///
+ /// 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 `this` (or something equivalent to `this`), and values in
+ /// between meaning that the interpolation is at the relevant point on the
+ /// timeline between `a` and `this`. 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<double>], such as
+ /// an [AnimationController].
+ ///
/// Instead of calling this directly, use [Gradient.lerp].
@protected
Gradient lerpFrom(Gradient a, double t) {
@@ -84,7 +97,7 @@
return null;
}
- /// Linearly interpolates from [this] to `b`.
+ /// Linearly interpolates from `this` to another [Gradient].
///
/// This is called if `b`'s [lerpTo] did not know how to handle this class.
///
@@ -95,6 +108,18 @@
/// If `b` is null, this must not return null. The base class implements this
/// by deferring to [scale].
///
+ /// The `t` argument represents position on the timeline, with 0.0 meaning
+ /// that the interpolation has not started, returning `this` (or something
+ /// equivalent to `this`), 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 `this` 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<double>], such as
+ /// an [AnimationController].
+ ///
/// Instead of calling this directly, use [Gradient.lerp].
@protected
Gradient lerpTo(Gradient b, double t) {
@@ -103,24 +128,37 @@
return null;
}
- /// Linearly interpolates from `begin` to `end`.
+ /// Linearly interpolates between two [Gradient]s.
///
- /// This defers to `end`'s [lerpTo] function if `end` is not null. If `end` is
- /// null or if its [lerpTo] returns null, it uses `begin`'s [lerpFrom]
- /// function instead. If both return null, it returns `begin` before `t=0.5`
- /// and `end` after `t=0.5`.
- static Gradient lerp(Gradient begin, Gradient end, double t) {
+ /// This defers to `b`'s [lerpTo] function if `b` is not null. If `b` is
+ /// null or if its [lerpTo] returns null, it uses `a`'s [lerpFrom]
+ /// function instead. If both return null, it returns `a` before `t == 0.5`
+ /// and `b` after `t == 0.5`.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
+ static Gradient lerp(Gradient a, Gradient b, double t) {
+ assert(t != null);
Gradient result;
- if (end != null)
- result = end.lerpFrom(begin, t); // if begin is null, this must return non-null
- if (result == null && begin != null)
- result = begin.lerpTo(end, t); // if end is null, this must return non-null
+ if (b != null)
+ result = b.lerpFrom(a, t); // if a is null, this must return non-null
+ if (result == null && a != null)
+ result = a.lerpTo(b, t); // if b is null, this must return non-null
if (result != null)
return result;
- if (begin == null && end == null)
+ if (a == null && b == null)
return null;
- assert(begin != null && end != null);
- return t < 0.5 ? begin.scale(1.0 - (t * 2.0)) : end.scale((t - 0.5) * 2.0);
+ assert(a != null && b != null);
+ return t < 0.5 ? a.scale(1.0 - (t * 2.0)) : b.scale((t - 0.5) * 2.0);
}
}
@@ -298,7 +336,20 @@
/// [tileMode] and with the same [colors] but transparent (using [scale]).
///
/// If neither gradient is null, they must have the same number of [colors].
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static LinearGradient lerp(LinearGradient a, LinearGradient b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
@@ -532,7 +583,20 @@
/// [tileMode] and with the same [colors] but transparent (using [scale]).
///
/// If neither gradient is null, they must have the same number of [colors].
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static RadialGradient lerp(RadialGradient a, RadialGradient b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
diff --git a/packages/flutter/lib/src/painting/rounded_rectangle_border.dart b/packages/flutter/lib/src/painting/rounded_rectangle_border.dart
index 0321307..a01ab02 100644
--- a/packages/flutter/lib/src/painting/rounded_rectangle_border.dart
+++ b/packages/flutter/lib/src/painting/rounded_rectangle_border.dart
@@ -55,6 +55,7 @@
@override
ShapeBorder lerpFrom(ShapeBorder a, double t) {
+ assert(t != null);
if (a is RoundedRectangleBorder) {
return new RoundedRectangleBorder(
side: BorderSide.lerp(a.side, side, t),
@@ -73,6 +74,7 @@
@override
ShapeBorder lerpTo(ShapeBorder b, double t) {
+ assert(t != null);
if (b is RoundedRectangleBorder) {
return new RoundedRectangleBorder(
side: BorderSide.lerp(side, b.side, t),
@@ -169,6 +171,7 @@
@override
ShapeBorder lerpFrom(ShapeBorder a, double t) {
+ assert(t != null);
if (a is RoundedRectangleBorder) {
return new _RoundedRectangleToCircleBorder(
side: BorderSide.lerp(a.side, side, t),
diff --git a/packages/flutter/lib/src/painting/shape_decoration.dart b/packages/flutter/lib/src/painting/shape_decoration.dart
index f48c4ea..7aaff49 100644
--- a/packages/flutter/lib/src/painting/shape_decoration.dart
+++ b/packages/flutter/lib/src/painting/shape_decoration.dart
@@ -186,13 +186,22 @@
/// Interpolates each parameter of the decoration separately.
///
/// If both values are null, this returns null. Otherwise, it returns a
- /// non-null value. If neither value is null and `t == 0.0`, then `a` is
- /// returned unmodified; if `t == 1.0` then `b` is returned unmodified.
- /// Otherwise, the values are computed by interpolating the properties
- /// appropriately, treating a null argument like a [ShapeDecoration] whose
+ /// non-null value, with null arguments treated like a [ShapeDecoration] whose
/// fields are all null (including the [shape], which cannot normally be
/// null).
///
+ /// 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<double>], such as
+ /// an [AnimationController].
+ ///
/// See also:
///
/// * [Decoration.lerp], which can interpolate between any two types of
@@ -201,6 +210,7 @@
/// and which use [ShapeDecoration.lerp] when interpolating two
/// [ShapeDecoration]s or a [ShapeDecoration] to or from null.
static ShapeDecoration lerp(ShapeDecoration a, ShapeDecoration b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a != null && b != null) {
diff --git a/packages/flutter/lib/src/painting/stadium_border.dart b/packages/flutter/lib/src/painting/stadium_border.dart
index 0223e1f..c4422a9 100644
--- a/packages/flutter/lib/src/painting/stadium_border.dart
+++ b/packages/flutter/lib/src/painting/stadium_border.dart
@@ -41,6 +41,7 @@
@override
ShapeBorder lerpFrom(ShapeBorder a, double t) {
+ assert(t != null);
if (a is StadiumBorder)
return new StadiumBorder(side: BorderSide.lerp(a.side, side, t));
if (a is CircleBorder) {
@@ -61,6 +62,7 @@
@override
ShapeBorder lerpTo(ShapeBorder b, double t) {
+ assert(t != null);
if (b is StadiumBorder)
return new StadiumBorder(side: BorderSide.lerp(side, b.side, t));
if (b is CircleBorder) {
@@ -151,6 +153,7 @@
@override
ShapeBorder lerpFrom(ShapeBorder a, double t) {
+ assert(t != null);
if (a is StadiumBorder) {
return new _StadiumToCircleBorder(
side: BorderSide.lerp(a.side, side, t),
@@ -174,6 +177,7 @@
@override
ShapeBorder lerpTo(ShapeBorder b, double t) {
+ assert(t != null);
if (b is StadiumBorder) {
return new _StadiumToCircleBorder(
side: BorderSide.lerp(side, b.side, t),
@@ -303,6 +307,7 @@
@override
ShapeBorder lerpFrom(ShapeBorder a, double t) {
+ assert(t != null);
if (a is StadiumBorder) {
return new _StadiumToRoundedRectangleBorder(
side: BorderSide.lerp(a.side, side, t),
@@ -329,6 +334,7 @@
@override
ShapeBorder lerpTo(ShapeBorder b, double t) {
+ assert(t != null);
if (b is StadiumBorder) {
return new _StadiumToRoundedRectangleBorder(
side: BorderSide.lerp(side, b.side, t),
diff --git a/packages/flutter/lib/src/painting/text_style.dart b/packages/flutter/lib/src/painting/text_style.dart
index c39ffd1..251ecd6 100644
--- a/packages/flutter/lib/src/painting/text_style.dart
+++ b/packages/flutter/lib/src/painting/text_style.dart
@@ -338,7 +338,7 @@
String newDebugLabel;
assert(() {
if (this.debugLabel != null)
- newDebugLabel = debugLabel ?? 'copy of ${this.debugLabel}';
+ newDebugLabel = debugLabel ?? '(${this.debugLabel}).copyWith';
return true;
}());
return new TextStyle(
@@ -414,7 +414,7 @@
String modifiedDebugLabel;
assert(() {
if (debugLabel != null)
- modifiedDebugLabel = 'modified $debugLabel';
+ modifiedDebugLabel = '($debugLabel).apply';
return true;
}());
@@ -459,7 +459,7 @@
String mergedDebugLabel;
assert(() {
if (other.debugLabel != null || debugLabel != null)
- mergedDebugLabel = '${other.debugLabel ?? _kDefaultDebugLabel} < ${debugLabel ?? _kDefaultDebugLabel}';
+ mergedDebugLabel = '(${debugLabel ?? _kDefaultDebugLabel}).merge(${other.debugLabel ?? _kDefaultDebugLabel})';
return true;
}());
@@ -483,29 +483,44 @@
/// Interpolate between two text styles.
///
/// This will not work well if the styles don't set the same fields.
- static TextStyle lerp(TextStyle begin, TextStyle end, double t) {
- assert(begin.inherit == end.inherit);
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
+ static TextStyle lerp(TextStyle a, TextStyle b, double t) {
+ assert(a != null);
+ assert(b != null);
+ assert(t != null);
+ assert(a.inherit == b.inherit);
String lerpDebugLabel;
assert(() {
- lerpDebugLabel = 'lerp(${begin.debugLabel ?? _kDefaultDebugLabel}, ${end.debugLabel ?? _kDefaultDebugLabel})';
+ lerpDebugLabel = 'lerp(${a.debugLabel ?? _kDefaultDebugLabel} ⎯${t.toStringAsFixed(1)}→ ${b.debugLabel ?? _kDefaultDebugLabel})';
return true;
}());
return new TextStyle(
- inherit: end.inherit,
- color: Color.lerp(begin.color, end.color, t),
- fontFamily: t < 0.5 ? begin.fontFamily : end.fontFamily,
- fontSize: ui.lerpDouble(begin.fontSize ?? end.fontSize, end.fontSize ?? begin.fontSize, t),
- fontWeight: FontWeight.lerp(begin.fontWeight, end.fontWeight, t),
- fontStyle: t < 0.5 ? begin.fontStyle : end.fontStyle,
- letterSpacing: ui.lerpDouble(begin.letterSpacing ?? end.letterSpacing, end.letterSpacing ?? begin.letterSpacing, t),
- wordSpacing: ui.lerpDouble(begin.wordSpacing ?? end.wordSpacing, end.wordSpacing ?? begin.wordSpacing, t),
- textBaseline: t < 0.5 ? begin.textBaseline : end.textBaseline,
- height: ui.lerpDouble(begin.height ?? end.height, end.height ?? begin.height, t),
- decoration: t < 0.5 ? begin.decoration : end.decoration,
- decorationColor: Color.lerp(begin.decorationColor, end.decorationColor, t),
- decorationStyle: t < 0.5 ? begin.decorationStyle : end.decorationStyle,
+ inherit: b.inherit,
+ color: Color.lerp(a.color, b.color, t),
+ fontFamily: t < 0.5 ? a.fontFamily : b.fontFamily,
+ fontSize: ui.lerpDouble(a.fontSize ?? b.fontSize, b.fontSize ?? a.fontSize, t),
+ fontWeight: FontWeight.lerp(a.fontWeight, b.fontWeight, t),
+ fontStyle: t < 0.5 ? a.fontStyle : b.fontStyle,
+ letterSpacing: ui.lerpDouble(a.letterSpacing ?? b.letterSpacing, b.letterSpacing ?? a.letterSpacing, t),
+ wordSpacing: ui.lerpDouble(a.wordSpacing ?? b.wordSpacing, b.wordSpacing ?? a.wordSpacing, t),
+ textBaseline: t < 0.5 ? a.textBaseline : b.textBaseline,
+ height: ui.lerpDouble(a.height ?? b.height, b.height ?? a.height, t),
+ decoration: t < 0.5 ? a.decoration : b.decoration,
+ decorationColor: Color.lerp(a.decorationColor, b.decorationColor, t),
+ decorationStyle: t < 0.5 ? a.decorationStyle : b.decorationStyle,
debugLabel: lerpDebugLabel,
);
}
diff --git a/packages/flutter/lib/src/rendering/box.dart b/packages/flutter/lib/src/rendering/box.dart
index b87cc89..211d8cd 100644
--- a/packages/flutter/lib/src/rendering/box.dart
+++ b/packages/flutter/lib/src/rendering/box.dart
@@ -402,7 +402,20 @@
///
/// If either is null, this function interpolates from a [BoxConstraints]
/// object whose fields are all set to 0.0.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static BoxConstraints lerp(BoxConstraints a, BoxConstraints b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
diff --git a/packages/flutter/lib/src/rendering/stack.dart b/packages/flutter/lib/src/rendering/stack.dart
index bcd6646..a7798b7 100644
--- a/packages/flutter/lib/src/rendering/stack.dart
+++ b/packages/flutter/lib/src/rendering/stack.dart
@@ -124,7 +124,20 @@
/// Linearly interpolate between two RelativeRects.
///
/// If either rect is null, this function interpolates from [RelativeRect.fill].
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static RelativeRect lerp(RelativeRect a, RelativeRect b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
@@ -137,7 +150,7 @@
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),
);
}
diff --git a/packages/flutter/lib/src/rendering/table_border.dart b/packages/flutter/lib/src/rendering/table_border.dart
index fdf13e1..8f9c008 100644
--- a/packages/flutter/lib/src/rendering/table_border.dart
+++ b/packages/flutter/lib/src/rendering/table_border.dart
@@ -116,15 +116,29 @@
return true;
}
- /// Creates a new border with the widths of this border multiplied by `t`.
+ /// Creates a copy of this border but with the widths scaled by the factor `t`.
+ ///
+ /// The `t` argument represents the multiplicand, or the position on the
+ /// timeline for an interpolation from nothing to `this`, with 0.0 meaning
+ /// that the the object returned should be the nil variant of this object, 1.0
+ /// meaning that no change should be applied, returning `this` (or something
+ /// equivalent to `this`), and other values meaning that the object should be
+ /// multiplied by `t`. Negative values are treated like zero.
+ ///
+ /// Values for `t` are usually obtained from an [Animation<double>], such as
+ /// an [AnimationController].
+ ///
+ /// See also:
+ ///
+ /// * [BorderSide.scale], which is used to implement this method.
TableBorder scale(double t) {
return new TableBorder(
- top: top.copyWith(width: t * top.width),
- right: right.copyWith(width: t * right.width),
- bottom: bottom.copyWith(width: t * bottom.width),
- left: left.copyWith(width: t * left.width),
- horizontalInside: horizontalInside.copyWith(width: t * horizontalInside.width),
- verticalInside: verticalInside.copyWith(width: t * verticalInside.width)
+ top: top.scale(t),
+ right: right.scale(t),
+ bottom: bottom.scale(t),
+ left: left.scale(t),
+ horizontalInside: horizontalInside.scale(t),
+ verticalInside: verticalInside.scale(t),
);
}
@@ -132,7 +146,20 @@
///
/// If a border is null, it is treated as having only [BorderSide.none]
/// borders.
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
static TableBorder lerp(TableBorder a, TableBorder b, double t) {
+ assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
@@ -145,7 +172,7 @@
bottom: BorderSide.lerp(a.bottom, b.bottom, t),
left: BorderSide.lerp(a.left, b.left, t),
horizontalInside: BorderSide.lerp(a.horizontalInside, b.horizontalInside, t),
- verticalInside: BorderSide.lerp(a.verticalInside, b.verticalInside, t)
+ verticalInside: BorderSide.lerp(a.verticalInside, b.verticalInside, t),
);
}
diff --git a/packages/flutter/lib/src/widgets/icon_theme_data.dart b/packages/flutter/lib/src/widgets/icon_theme_data.dart
index 06a9847..0dc5f41 100644
--- a/packages/flutter/lib/src/widgets/icon_theme_data.dart
+++ b/packages/flutter/lib/src/widgets/icon_theme_data.dart
@@ -65,11 +65,24 @@
final double size;
/// Linearly interpolate between two icon theme data objects.
- static IconThemeData lerp(IconThemeData begin, IconThemeData end, double t) {
+ ///
+ /// 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<double>], such as
+ /// an [AnimationController].
+ static IconThemeData lerp(IconThemeData a, IconThemeData b, double t) {
+ assert(t != null);
return new IconThemeData(
- color: Color.lerp(begin.color, end.color, t),
- opacity: ui.lerpDouble(begin.opacity, end.opacity, t),
- size: ui.lerpDouble(begin.size, end.size, t)
+ color: Color.lerp(a.color, b.color, t),
+ opacity: ui.lerpDouble(a.opacity, b.opacity, t),
+ size: ui.lerpDouble(a.size, b.size, t),
);
}
diff --git a/packages/flutter/test/material/theme_test.dart b/packages/flutter/test/material/theme_test.dart
index 926f901..fbfa0af 100644
--- a/packages/flutter/test/material/theme_test.dart
+++ b/packages/flutter/test/material/theme_test.dart
@@ -417,7 +417,7 @@
}
}
- expect(theme.textTheme.display4.debugLabel, 'blackMountainView display4 < englishLike display4');
+ expect(theme.textTheme.display4.debugLabel, '(englishLike display4).merge(blackMountainView display4)');
});
}
diff --git a/packages/flutter/test/painting/text_style_test.dart b/packages/flutter/test/painting/text_style_test.dart
index fd2f607..f6c1ff9 100644
--- a/packages/flutter/test/painting/text_style_test.dart
+++ b/packages/flutter/test/painting/text_style_test.dart
@@ -156,11 +156,11 @@
expect(foo.debugLabel, 'foo');
expect(foo.toString(), 'TextStyle(debugLabel: foo, inherit: true, size: 1.0)');
- expect(foo.merge(bar).debugLabel, 'bar < foo');
- expect(foo.merge(bar).merge(baz).debugLabel, 'baz < bar < foo');
- expect(foo.copyWith().debugLabel, 'copy of foo');
- expect(foo.apply().debugLabel, 'modified foo');
- expect(TextStyle.lerp(foo, bar, 0.5).debugLabel, 'lerp(foo, bar)');
- expect(TextStyle.lerp(foo.merge(bar), baz, 0.5).copyWith().debugLabel, 'copy of lerp(bar < foo, baz)');
+ expect(foo.merge(bar).debugLabel, '(foo).merge(bar)');
+ expect(foo.merge(bar).merge(baz).debugLabel, '((foo).merge(bar)).merge(baz)');
+ expect(foo.copyWith().debugLabel, '(foo).copyWith');
+ expect(foo.apply().debugLabel, '(foo).apply');
+ expect(TextStyle.lerp(foo, bar, 0.5).debugLabel, 'lerp(foo ⎯0.5→ bar)');
+ expect(TextStyle.lerp(foo.merge(bar), baz, 0.51).copyWith().debugLabel, '(lerp((foo).merge(bar) ⎯0.5→ baz)).copyWith');
});
}
diff --git a/packages/flutter/test/rendering/table_border_test.dart b/packages/flutter/test/rendering/table_border_test.dart
index 6e9d717..4357c12 100644
--- a/packages/flutter/test/rendering/table_border_test.dart
+++ b/packages/flutter/test/rendering/table_border_test.dart
@@ -57,8 +57,8 @@
expect(border3.dimensions, const EdgeInsets.symmetric(horizontal: 1.0, vertical: 1.0));
expect(border3.isUniform, isFalse);
expect(border3.scale(0.0), new TableBorder.symmetric(
- inside: const BorderSide(width: 0.0),
- outside: const BorderSide(width: 0.0, color: const Color(0xFFFF0000)),
+ inside: const BorderSide(width: 0.0, style: BorderStyle.none),
+ outside: const BorderSide(width: 0.0, color: const Color(0xFFFF0000), style: BorderStyle.none),
));
});