mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
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.
This commit is contained in:
parent
075ba6477f
commit
ecb708ee3a
@ -589,23 +589,39 @@ class _CupertinoBackGestureController {
|
||||
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(
|
||||
|
||||
@ -519,40 +519,53 @@ class ThemeData {
|
||||
/// 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,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -284,19 +284,36 @@ class TextTheme {
|
||||
}
|
||||
|
||||
/// 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),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -84,7 +84,20 @@ abstract class AlignmentGeometry {
|
||||
/// 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 @@ class Alignment extends AlignmentGeometry {
|
||||
/// 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 @@ class AlignmentDirectional extends AlignmentGeometry {
|
||||
/// 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)
|
||||
|
||||
@ -126,7 +126,20 @@ abstract class BorderRadiusGeometry {
|
||||
/// 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 @@ class BorderRadius extends BorderRadiusGeometry {
|
||||
/// 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 @@ class BorderRadiusDirectional extends BorderRadiusGeometry {
|
||||
/// 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)
|
||||
|
||||
@ -130,11 +130,22 @@ class BorderSide {
|
||||
);
|
||||
}
|
||||
|
||||
/// 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 @@ class BorderSide {
|
||||
/// 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 @@ abstract class ShapeBorder {
|
||||
/// 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 @@ abstract class ShapeBorder {
|
||||
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 @@ abstract class ShapeBorder {
|
||||
/// 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 @@ abstract class ShapeBorder {
|
||||
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 @@ abstract class ShapeBorder {
|
||||
/// 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 @@ abstract class ShapeBorder {
|
||||
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 @@ class _CompoundBorder extends ShapeBorder {
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
@ -34,6 +34,8 @@ enum BoxShape {
|
||||
///
|
||||
/// * [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 @@ abstract class BoxBorder extends ShapeBorder {
|
||||
///
|
||||
/// 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 @@ class Border extends BoxBorder {
|
||||
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 @@ class Border extends BoxBorder {
|
||||
);
|
||||
}
|
||||
|
||||
/// 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 @@ class Border extends BoxBorder {
|
||||
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 @@ class Border extends BoxBorder {
|
||||
///
|
||||
/// 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 @@ class Border extends BoxBorder {
|
||||
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 @@ class BorderDirectional extends BoxBorder {
|
||||
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 @@ class BorderDirectional extends BoxBorder {
|
||||
);
|
||||
}
|
||||
|
||||
/// 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 @@ class BorderDirectional extends BoxBorder {
|
||||
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 @@ class BorderDirectional extends BoxBorder {
|
||||
///
|
||||
/// 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 @@ class BorderDirectional extends BoxBorder {
|
||||
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),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -200,6 +200,18 @@ class BoxDecoration extends Decoration {
|
||||
/// 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 @@ class BoxDecoration extends Decoration {
|
||||
/// 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)
|
||||
|
||||
@ -70,7 +70,20 @@ class BoxShadow {
|
||||
/// 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 @@ class BoxShadow {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -136,9 +136,30 @@ class HSVColor {
|
||||
|
||||
/// 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 @@ class HSVColor {
|
||||
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),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -61,7 +61,8 @@ abstract class Decoration extends Diagnosticable {
|
||||
/// 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 @@ abstract class Decoration extends Diagnosticable {
|
||||
/// 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 @@ abstract class Decoration extends Diagnosticable {
|
||||
/// 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,
|
||||
|
||||
@ -189,7 +189,20 @@ abstract class EdgeInsetsGeometry {
|
||||
/// 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 @@ abstract class EdgeInsetsGeometry {
|
||||
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 @@ class EdgeInsets extends EdgeInsetsGeometry {
|
||||
/// 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 @@ class EdgeInsetsDirectional extends EdgeInsetsGeometry {
|
||||
/// 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)
|
||||
|
||||
@ -125,13 +125,25 @@ class FlutterLogoDecoration extends Decoration {
|
||||
///
|
||||
/// 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)
|
||||
|
||||
@ -177,7 +177,20 @@ class FractionalOffset extends Alignment {
|
||||
/// 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)
|
||||
|
||||
@ -67,7 +67,7 @@ abstract class Gradient {
|
||||
/// 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 @@ abstract class Gradient {
|
||||
/// 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 @@ abstract class Gradient {
|
||||
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 @@ abstract class Gradient {
|
||||
/// 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 @@ abstract class Gradient {
|
||||
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 @@ class LinearGradient extends Gradient {
|
||||
/// [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 @@ class RadialGradient extends Gradient {
|
||||
/// [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)
|
||||
|
||||
@ -55,6 +55,7 @@ class RoundedRectangleBorder extends ShapeBorder {
|
||||
|
||||
@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 @@ class RoundedRectangleBorder extends ShapeBorder {
|
||||
|
||||
@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 @@ class _RoundedRectangleToCircleBorder extends ShapeBorder {
|
||||
|
||||
@override
|
||||
ShapeBorder lerpFrom(ShapeBorder a, double t) {
|
||||
assert(t != null);
|
||||
if (a is RoundedRectangleBorder) {
|
||||
return new _RoundedRectangleToCircleBorder(
|
||||
side: BorderSide.lerp(a.side, side, t),
|
||||
|
||||
@ -186,13 +186,22 @@ class ShapeDecoration extends Decoration {
|
||||
/// 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 @@ class ShapeDecoration extends Decoration {
|
||||
/// 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) {
|
||||
|
||||
@ -41,6 +41,7 @@ class StadiumBorder extends ShapeBorder {
|
||||
|
||||
@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 @@ class StadiumBorder extends ShapeBorder {
|
||||
|
||||
@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 @@ class _StadiumToCircleBorder extends ShapeBorder {
|
||||
|
||||
@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 @@ class _StadiumToCircleBorder extends ShapeBorder {
|
||||
|
||||
@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 @@ class _StadiumToRoundedRectangleBorder extends ShapeBorder {
|
||||
|
||||
@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 @@ class _StadiumToRoundedRectangleBorder extends ShapeBorder {
|
||||
|
||||
@override
|
||||
ShapeBorder lerpTo(ShapeBorder b, double t) {
|
||||
assert(t != null);
|
||||
if (b is StadiumBorder) {
|
||||
return new _StadiumToRoundedRectangleBorder(
|
||||
side: BorderSide.lerp(side, b.side, t),
|
||||
|
||||
@ -338,7 +338,7 @@ class TextStyle extends Diagnosticable {
|
||||
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 @@ class TextStyle extends Diagnosticable {
|
||||
String modifiedDebugLabel;
|
||||
assert(() {
|
||||
if (debugLabel != null)
|
||||
modifiedDebugLabel = 'modified $debugLabel';
|
||||
modifiedDebugLabel = '($debugLabel).apply';
|
||||
return true;
|
||||
}());
|
||||
|
||||
@ -459,7 +459,7 @@ class TextStyle extends Diagnosticable {
|
||||
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 @@ class TextStyle extends Diagnosticable {
|
||||
/// 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,
|
||||
);
|
||||
}
|
||||
|
||||
@ -402,7 +402,20 @@ class BoxConstraints extends Constraints {
|
||||
///
|
||||
/// 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)
|
||||
|
||||
@ -124,7 +124,20 @@ class RelativeRect {
|
||||
/// 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 @@ class RelativeRect {
|
||||
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),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -116,15 +116,29 @@ class TableBorder {
|
||||
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 @@ class TableBorder {
|
||||
///
|
||||
/// 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 @@ class TableBorder {
|
||||
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),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -65,11 +65,24 @@ class IconThemeData {
|
||||
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),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -417,7 +417,7 @@ void main() {
|
||||
}
|
||||
}
|
||||
|
||||
expect(theme.textTheme.display4.debugLabel, 'blackMountainView display4 < englishLike display4');
|
||||
expect(theme.textTheme.display4.debugLabel, '(englishLike display4).merge(blackMountainView display4)');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -156,11 +156,11 @@ void main() {
|
||||
|
||||
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');
|
||||
});
|
||||
}
|
||||
|
||||
@ -57,8 +57,8 @@ void main() {
|
||||
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),
|
||||
));
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user