Commit 3012cce1 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Clean up Tween and friends. (#9858)

parent a6eb0a3e
......@@ -47,7 +47,7 @@ class NavigationIconView {
return new FadeTransition(
opacity: _animation,
child: new SlideTransition(
position: new Tween<FractionalOffset>(
position: new FractionalOffsetTween(
begin: const FractionalOffset(0.0, 0.02), // Small offset from the top.
end: FractionalOffset.topLeft,
).animate(_animation),
......
......@@ -38,7 +38,7 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
parent: new ReverseAnimation(_controller),
curve: Curves.fastOutSlowIn,
);
_drawerDetailsPosition = new Tween<FractionalOffset>(
_drawerDetailsPosition = new FractionalOffsetTween(
begin: const FractionalOffset(0.0, -1.0),
end: const FractionalOffset(0.0, 0.0),
).animate(new CurvedAnimation(
......
......@@ -24,9 +24,9 @@ enum AnimationStatus {
/// Signature for listeners attached using [Animation.addStatusListener].
typedef void AnimationStatusListener(AnimationStatus status);
/// An animation with a value of type T
/// An animation with a value of type `T`.
///
/// An animation consists of a value (of type T) together with a status. The
/// An animation consists of a value (of type `T`) together with a status. The
/// status indicates whether the animation is conceptually running from
/// beginning to end or from the end back to the beginning, although the actual
/// value of the animation might not change monotonically (e.g., if the
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show Color, Size, Rect;
import 'dart:ui' show Color, Size, Rect, hashValues;
import 'package:flutter/foundation.dart';
......@@ -10,7 +10,11 @@ import 'animation.dart';
import 'animations.dart';
import 'curves.dart';
/// An object that can produce a value of type T given an [Animation] as input.
/// An object that can produce a value of type `T` given an [Animation<double>]
/// as input.
///
/// Typically, the values of the input animation are nominally in the range 0.0
/// to 1.0. In principle, however, any value could be provided.
abstract class Animatable<T> {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
......@@ -77,14 +81,33 @@ class _ChainedEvaluation<T> extends Animatable<T> {
/// [Tween] is useful if you want to interpolate across a range.
///
/// To use a [Tween] object with an animation, call the [Tween] object's
/// `animate()` method and pass it the [Animation] object that you want to
/// [animate] method and pass it the [Animation] object that you want to
/// modify.
///
/// You can chain [Tween] objects together using the `chain()` method, so that a
/// You can chain [Tween] objects together using the [chain] method, so that a
/// single [Animation] object is configured by multiple [Tween] objects called
/// in succession. This is different than calling the `animate()` method twice,
/// in succession. This is different than calling the [animate] method twice,
/// which results in two [Animation] separate objects, each configured with a
/// single [Tween].
///
/// ## Sample usage
///
/// Suppose `_controller` is an [AnimationController], and we want to create an
/// [Animation<Offset>] that is controlled by that controller, and save it in
/// `_animation`:
///
/// ```dart
/// _animation = new Tween<Offset>(
/// begin: const Offset(100.0, 50.0),
/// end: const Offset(200.0, 300.0),
/// ).animation(_controller);
/// ```
///
/// That would provide an `_animation` that, over the lifetime of the
/// `_controller`'s animation, returns a value that depicts a point along the
/// line between the two offsets above. If we used a [MaterialPointArcTween]
/// instead of a [Tween<Offset>] in the code above, the points would follow a
/// pleasing curve instead of a straight line, with no other changes necessary.
class Tween<T extends dynamic> extends Animatable<T> {
/// Creates a tween.
///
......@@ -95,27 +118,38 @@ class Tween<T extends dynamic> extends Animatable<T> {
/// The value this variable has at the beginning of the animation.
///
/// Must be non-null before this [Tween] is evaluated.
/// See the constructor for details about whether this property may be null
/// (it varies from subclass to subclass).
T begin;
/// The value this variable has at the end of the animation.
///
/// Must be non-null before this [Tween] is evaluated.
/// See the constructor for details about whether this property may be null
/// (it varies from subclass to subclass).
T end;
/// Returns the value this variable has at the given animation clock value.
///
/// The [begin] and [end] properties must be non-null by the time this method
/// is called.
T lerp(double t) => begin + (end - begin) * t;
/// The default implementation of this method uses the [+], [-], and [*]
/// operators on `T`. The [begin] and [end] properties must therefore be
/// non-null by the time this method is called.
T lerp(double t) {
assert(begin != null);
assert(end != null);
return begin + (end - begin) * t;
}
/// Returns the interpolated value for the current value of the given animation.
///
/// This method returns `begin` and `end` when the animation values are 0.0 or
/// 1.0, respectively.
///
/// The [begin] and [end] properties must be non-null by the time this method
/// is called with an animation that is not at 0.0 or 1.0.
/// This function is implemented by deferring to [lerp]. Subclasses that want to
/// provide custom behavior should override [lerp], not [evaluate].
///
/// See the constructor for details about whether the [begin] and [end]
/// properties may be null when this is called. It varies from subclass to
/// subclass.
@override
T evaluate(Animation<double> animation) {
final double t = animation.value;
......@@ -126,67 +160,89 @@ class Tween<T extends dynamic> extends Animatable<T> {
return lerp(t);
}
@override
bool operator ==(dynamic other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
final Tween<T> typedOther = other;
return begin == typedOther.begin
&& end == typedOther.end;
}
@override
int get hashCode => hashValues(begin, end);
@override
String toString() => '$runtimeType($begin \u2192 $end)';
}
/// An interpolation between two colors.
///
/// This class specializes the interpolation of Tween<Color> to be
/// appropriate for colors.
/// This class specializes the interpolation of [Tween<Color>] to use
/// [Color.lerp].
///
/// See [Tween] for a discussion on how to use interpolation objects.
class ColorTween extends Tween<Color> {
/// Creates a color tween.
/// Creates a [Color] tween.
///
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
/// filled in later.
/// The [begin] and [end] properties may be null; the null value
/// is treated as transparent black.
ColorTween({ Color begin, Color end }) : super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
Color lerp(double t) => Color.lerp(begin, end, t);
}
/// An interpolation between two sizes.
///
/// This class specializes the interpolation of Tween<Size> to be
/// appropriate for rectangles.
/// This class specializes the interpolation of [Tween<Size>] to use
/// [Size.lerp].
///
/// See [Tween] for a discussion on how to use interpolation objects.
class SizeTween extends Tween<Size> {
/// Creates a size tween.
/// Creates a [Size] tween.
///
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
/// filled in later.
/// The [begin] and [end] properties may be null; the null value
/// is treated as an empty size.
SizeTween({ Size begin, Size end }) : super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
Size lerp(double t) => Size.lerp(begin, end, t);
}
/// An interpolation between two rectangles.
///
/// This class specializes the interpolation of Tween<Rect> to be
/// appropriate for rectangles.
/// This class specializes the interpolation of [Tween<Rect>] to use
/// [Rect.lerp].
///
/// See [Tween] for a discussion on how to use interpolation objects.
class RectTween extends Tween<Rect> {
/// Creates a rect tween.
/// Creates a [Rect] tween.
///
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
/// filled in later.
/// The [begin] and [end] properties may be null; the null value
/// is treated as an empty rect at the top left corner.
RectTween({ Rect begin, Rect end }) : super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
Rect lerp(double t) => Rect.lerp(begin, end, t);
}
/// An interpolation between two integers that rounds.
///
/// This class specializes the interpolation of Tween<int> to be
/// This class specializes the interpolation of [Tween<int>] to be
/// appropriate for integers by interpolating between the given begin
/// and end values and then rounding the result to the nearest
/// integer.
///
/// This is the closest approximation to a linear tween that is
/// possible with an integer. Compare to [StepTween].
/// This is the closest approximation to a linear tween that is possible with an
/// integer. Compare to [StepTween] and [Tween<double>].
///
/// See [Tween] for a discussion on how to use interpolation objects.
class IntTween extends Tween<int> {
/// Creates an int tween.
///
......@@ -203,15 +259,17 @@ class IntTween extends Tween<int> {
/// An interpolation between two integers that floors.
///
/// This class specializes the interpolation of Tween<int> to be
/// This class specializes the interpolation of [Tween<int>] to be
/// appropriate for integers by interpolating between the given begin
/// and end values and then using [int.floor()] to return the current
/// and end values and then using [int.floor] to return the current
/// integer component, dropping the fractional component.
///
/// This results in a value that is never greater than the equivalent
/// value from a linear double interpolation. Compare to [IntTween].
///
/// See [Tween] for a discussion on how to use interpolation objects.
class StepTween extends Tween<int> {
/// Creates a step tween.
/// Creates an [int] tween that floors.
///
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
......
......@@ -3,17 +3,20 @@
// found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' show hashValues, lerpDouble;
import 'dart:ui' show lerpDouble;
import 'package:flutter/animation.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
// How close the begin and end points must be to an axis to be considered
// vertical or horizontal.
const double _kOnAxisDelta = 2.0;
/// A [Tween] that animates an [Offset] along a circular arc.
/// A [Tween] that interpolates an [Offset] along a circular arc.
///
/// This class specializes the interpolation of [Tween<Offset>] so that instead
/// of a straight line, the intermediate points follow the arc of a circle in a
/// manner consistent with material design principles.
///
/// The arc's radius is related to the bounding box that contains the [begin]
/// and [end] points. If the bounding box is taller than it is wide, then the
......@@ -21,23 +24,27 @@ const double _kOnAxisDelta = 2.0;
/// Otherwise the center of the circle will be aligned with the begin point.
/// The arc's sweep is always less than or equal to 90 degrees.
///
/// Unlike those of most Tweens, the [begin] and [end] members of a
/// [MaterialPointArcTween] are immutable.
///
/// See also:
///
/// * [MaterialRectArcTween]
/// * [Tween], for a discussion on how to use interpolation objects.
/// * [MaterialRectArcTween], which extends this concept to interpolating [Rect]s.
class MaterialPointArcTween extends Tween<Offset> {
/// Creates a [Tween] for animating [Offset]s along a circular arc.
///
/// The [begin] and [end] points are required, cannot be null, and are
/// immutable.
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
/// filled in later.
MaterialPointArcTween({
@required Offset begin,
@required Offset end
}) : super(begin: begin, end: end) {
Offset begin,
Offset end,
}) : super(begin: begin, end: end);
bool _dirty = true;
void _initialize() {
assert(begin != null);
assert(end != null);
// An explanation with a diagram can be found at https://goo.gl/vMSdRg
final Offset delta = end - begin;
final double deltaX = delta.dx.abs();
......@@ -69,45 +76,85 @@ class MaterialPointArcTween extends Tween<Offset> {
_endAngle = _beginAngle + sweepAngle() * (begin.dx - end.dx).sign;
}
}
assert(_beginAngle != null);
assert(_endAngle != null);
} else {
_beginAngle = null;
_endAngle = null;
}
_dirty = false;
}
/// The center of the circular arc, null if [begin] and [end] are horizontally or
/// vertically aligned, or if either is null.
Offset get center {
if (begin == null || end == null)
return null;
if (_dirty)
_initialize();
return _center;
}
Offset _center;
double _radius;
double _beginAngle;
double _endAngle;
/// The center of the circular arc, null if [begin] and [end] are horiztonally or
/// vertically aligned.
Offset get center => _center;
/// The radius of the circular arc, null if begin and end are horiztonally or
/// vertically aligned.
double get radius => _radius;
/// The radius of the circular arc, null if [begin] and [end] are horizontally or
/// vertically aligned, or if either is null.
double get radius {
if (begin == null || end == null)
return null;
if (_dirty)
_initialize();
return _radius;
}
double _radius;
/// The beginning of the arc's sweep in radians, measured from the positive X axis.
/// Positive angles turn clockwise. Null if begin and end are horiztonally or
/// vertically aligned.
double get beginAngle => _beginAngle;
/// The beginning of the arc's sweep in radians, measured from the positive x
/// axis. Positive angles turn clockwise.
///
/// This will be null if [begin] and [end] are horizontally or vertically
/// aligned, or if either is null.
double get beginAngle {
if (begin == null || end == null)
return null;
if (_dirty)
_initialize();
return _beginAngle;
}
double _beginAngle;
/// The end of the arc's sweep in radians, measured from the positive X axis.
/// The end of the arc's sweep in radians, measured from the positive x axis.
/// Positive angles turn clockwise.
double get endAngle => _beginAngle;
///
/// This will be null if [begin] and [end] are horizontally or vertically
/// aligned, or if either is null.
double get endAngle {
if (begin == null || end == null)
return null;
if (_dirty)
_initialize();
return _beginAngle;
}
double _endAngle;
/// Setting the arc's [begin] parameter is not supported. Construct a new arc instead.
@override
set begin(Offset value) {
assert(false); // not supported
if (value != begin) {
super.begin = value;
_dirty = true;
}
}
/// Setting the arc's [end] parameter is not supported. Construct a new arc instead.
@override
set end(Offset value) {
assert(false); // not supported
if (value != end) {
super.end = value;
_dirty = true;
}
}
@override
Offset lerp(double t) {
if (_dirty)
_initialize();
if (t == 0.0)
return begin;
if (t == 1.0)
......@@ -120,23 +167,9 @@ class MaterialPointArcTween extends Tween<Offset> {
return _center + new Offset(x, y);
}
@override
bool operator ==(dynamic other) {
if (identical(this, other))
return true;
if (other is! MaterialPointArcTween)
return false;
final MaterialPointArcTween typedOther = other;
return begin == typedOther.begin
&& end == typedOther.end;
}
@override
int get hashCode => hashValues(begin, end);
@override
String toString() {
return '$runtimeType($begin \u2192 $end center=$center, radius=$radius, beginAngle=$beginAngle, endAngle=$endAngle)';
return '$runtimeType($begin \u2192 $end; center=$center, radius=$radius, beginAngle=$beginAngle, endAngle=$endAngle)';
}
}
......@@ -176,44 +209,55 @@ T _maxBy<T>(Iterable<T> input, _KeyFunc<T> keyFunc) {
return maxValue;
}
/// A [Tween] that animates a [Rect] from [begin] to [end].
/// A [Tween] that interpolates a [Rect] by having its opposite corners follow
/// circular arcs.
///
/// The rectangle corners whose diagonal is closest to the overall direction of
/// the animation follow arcs defined with [MaterialPointArcTween].
/// This class specializes the interpolation of [Tween<Rect>] so that instead of
/// growing or shrinking linearly, opposite corners of the rectangle follow arcs
/// in a manner consistent with material design principles.
///
/// Unlike those of most Tweens, the [begin] and [end] members of a
/// [MaterialPointArcTween] are immutable.
/// Specifically, the rectangle corners whose diagonals are closest to the overall
/// direction of the animation follow arcs defined with [MaterialPointArcTween].
///
/// See also:
///
/// * [MaterialPointArcTween]. the analogue for [Offset] interporation.
/// * [Tween], for a discussion on how to use interpolation objects.
/// * [MaterialPointArcTween], the analogue for [Offset] interporation.
/// * [RectTween], which does a linear rectangle interpolation.
class MaterialRectArcTween extends RectTween {
/// Creates a [Tween] for animating [Rect]s along a circular arc.
///
/// The [begin] and [end] points are required, cannot be null, and are
/// immutable.
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
/// filled in later.
MaterialRectArcTween({
@required Rect begin,
@required Rect end
}) : super(begin: begin, end: end) {
Rect begin,
Rect end,
}) : super(begin: begin, end: end);
bool _dirty = true;
void _initialize() {
assert(begin != null);
assert(end != null);
final Offset centersVector = end.center - begin.center;
_diagonal = _maxBy<_Diagonal>(_allDiagonals, (_Diagonal d) => _diagonalSupport(centersVector, d));
final _Diagonal diagonal = _maxBy<_Diagonal>(_allDiagonals, (_Diagonal d) => _diagonalSupport(centersVector, d));
_beginArc = new MaterialPointArcTween(
begin: _cornerFor(begin, _diagonal.beginId),
end: _cornerFor(end, _diagonal.beginId)
begin: _cornerFor(begin, diagonal.beginId),
end: _cornerFor(end, diagonal.beginId)
);
_endArc = new MaterialPointArcTween(
begin: _cornerFor(begin, _diagonal.endId),
end: _cornerFor(end, _diagonal.endId)
begin: _cornerFor(begin, diagonal.endId),
end: _cornerFor(end, diagonal.endId)
);
_dirty = false;
}
_Diagonal _diagonal;
MaterialPointArcTween _beginArc;
MaterialPointArcTween _endArc;
double _diagonalSupport(Offset centersVector, _Diagonal diagonal) {
final Offset delta = _cornerFor(begin, diagonal.endId) - _cornerFor(begin, diagonal.beginId);
final double length = delta.distance;
return centersVector.dx * delta.dx / length + centersVector.dy * delta.dy / length;
}
Offset _cornerFor(Rect rect, _CornerId id) {
switch (id) {
......@@ -225,34 +269,48 @@ class MaterialRectArcTween extends RectTween {
return Offset.zero;
}
double _diagonalSupport(Offset centersVector, _Diagonal diagonal) {
final Offset delta = _cornerFor(begin, diagonal.endId) - _cornerFor(begin, diagonal.beginId);
final double length = delta.distance;
return centersVector.dx * delta.dx / length + centersVector.dy * delta.dy / length;
}
/// The path of the corresponding [begin], [end] rectangle corners that lead
/// the animation.
MaterialPointArcTween get beginArc => _beginArc;
MaterialPointArcTween get beginArc {
if (begin == null)
return null;
if (_dirty)
_initialize();
return _beginArc;
}
MaterialPointArcTween _beginArc;
/// The path of the corresponding [begin], [end] rectangle corners that trail
/// the animation.
MaterialPointArcTween get endArc => _endArc;
MaterialPointArcTween get endArc {
if (end == null)
return null;
if (_dirty)
_initialize();
return _endArc;
}
MaterialPointArcTween _endArc;
/// Setting the arc's [begin] parameter is not supported. Construct a new arc instead.
@override
set begin(Rect value) {
assert(false); // not supported
if (value != begin) {
super.begin = value;
_dirty = true;
}
}
/// Setting the arc's [end] parameter is not supported. Construct a new arc instead.
@override
set end(Rect value) {
assert(false); // not supported
if (value != end) {
super.end = value;
_dirty = true;
}
}
@override
Rect lerp(double t) {
if (_dirty)
_initialize();
if (t == 0.0)
return begin;
if (t == 1.0)
......@@ -260,22 +318,8 @@ class MaterialRectArcTween extends RectTween {
return new Rect.fromPoints(_beginArc.lerp(t), _endArc.lerp(t));
}
@override
bool operator ==(dynamic other) {
if (identical(this, other))
return true;
if (other is! MaterialRectArcTween)
return false;
final MaterialRectArcTween typedOther = other;
return begin == typedOther.begin
&& end == typedOther.end;
}
@override
int get hashCode => hashValues(begin, end);
@override
String toString() {
return '$runtimeType($begin \u2192 $end beginArc=$beginArc, endArc=$endArc)';
return '$runtimeType($begin \u2192 $end; beginArc=$beginArc, endArc=$endArc)';
}
}
......@@ -129,9 +129,18 @@ class Theme extends InheritedWidget {
}
}
/// An animated value that interpolates [ThemeData]s.
/// An interpolation between two [ThemeData]s.
///
/// This class specializes the interpolation of [Tween<ThemeData>] to call the
/// [ThemeData.lerp] method.
///
/// See [Tween] for a discussion on how to use interpolation objects.
class ThemeDataTween extends Tween<ThemeData> {
/// Creates an interpolation between [begin] and [end].
/// Creates a [ThemeData] tween.
///
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
/// filled in later.
ThemeDataTween({ ThemeData begin, ThemeData end }) : super(begin: begin, end: end);
@override
......
......@@ -441,7 +441,11 @@ 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);
return new ThemeData.raw(
brightness: t < 0.5 ? begin.brightness : end.brightness,
primaryColor: Color.lerp(begin.primaryColor, end.primaryColor, t),
......
......@@ -9,13 +9,17 @@ import 'package:flutter/painting.dart';
///
/// This class specializes the interpolation of Tween<FractionalOffset> to be
/// appropriate for rectangles.
///
/// See [Tween] for a discussion on how to use interpolation objects.
class FractionalOffsetTween extends Tween<FractionalOffset> {
/// Creates a fractional offset tween.
///
/// The [begin] and [end] arguments must not be null.
/// The [begin] and [end] properties may be null; the null value
/// is treated as meaning the top left corner.
FractionalOffsetTween({ FractionalOffset begin, FractionalOffset end })
: super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
FractionalOffset lerp(double t) => FractionalOffset.lerp(begin, end, t);
}
......@@ -265,7 +265,7 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
}
void _updateMoveAnimation() {
_moveAnimation = new Tween<FractionalOffset>(
_moveAnimation = new FractionalOffsetTween(
begin: FractionalOffset.topLeft,
end: _directionIsXAxis ?
new FractionalOffset(_dragExtent.sign, 0.0) :
......
......@@ -13,60 +13,104 @@ import 'text.dart';
import 'ticker_provider.dart';
/// An interpolation between two [BoxConstraints].
///
/// This class specializes the interpolation of [Tween<BoxConstraints>] to use
/// [BoxConstraints.lerp].
///
/// See [Tween] for a discussion on how to use interpolation objects.
class BoxConstraintsTween extends Tween<BoxConstraints> {
/// Creates a box constraints tween.
/// Creates a [BoxConstraints] tween.
///
/// The [begin] and [end] arguments must not be null.
/// The [begin] and [end] properties may be null; the null value
/// is treated as a tight constraint of zero size.
BoxConstraintsTween({ BoxConstraints begin, BoxConstraints end }) : super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
BoxConstraints lerp(double t) => BoxConstraints.lerp(begin, end, t);
}
/// An interpolation between two [Decoration]s.
///
/// This class specializes the interpolation of [Tween<BoxConstraints>] to use
/// [Decoration.lerp].
///
/// Typically this will only have useful results if the [begin] and [end]
/// decorations have the same type; decorations of differing types generally do
/// not have a useful animation defined, and will just jump to the [end]
/// immediately.
///
/// See [Tween] for a discussion on how to use interpolation objects.
class DecorationTween extends Tween<Decoration> {
/// Creates a decoration tween.
///
/// The [begin] and [end] arguments must not be null.
/// The [begin] and [end] properties may be null. If both are null, then the
/// result is always null. If [end] is not null, then its lerping logic is
/// used (via [Decoration.lerpTo]). Otherwise, [begin]'s lerping logic is used
/// (via [Decoration.lerpFrom]).
DecorationTween({ Decoration begin, Decoration end }) : super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
Decoration lerp(double t) => Decoration.lerp(begin, end, t);
}
/// An interpolation between two [EdgeInsets]s.
///
/// This class specializes the interpolation of [Tween<EdgeInsets>] to use
/// [EdgeInsets.lerp].
///
/// See [Tween] for a discussion on how to use interpolation objects.
class EdgeInsetsTween extends Tween<EdgeInsets> {
/// Creates an edge insets tween.
/// Creates an [EdgeInsets] tween.
///
/// The [begin] and [end] arguments must not be null.
/// The [begin] and [end] properties may be null; the null value
/// is treated as an [EdgeInsets] with no inset.
EdgeInsetsTween({ EdgeInsets begin, EdgeInsets end }) : super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
EdgeInsets lerp(double t) => EdgeInsets.lerp(begin, end, t);
}
/// An interpolation between two [BorderRadius]s.
///
/// This class specializes the interpolation of [Tween<BorderRadius>] to use
/// [BorderRadius.lerp].
///
/// See [Tween] for a discussion on how to use interpolation objects.
class BorderRadiusTween extends Tween<BorderRadius> {
/// Creates a border radius tween.
/// Creates a [BorderRadius] tween.
///
/// The [begin] and [end] arguments must not be null.
/// The [begin] and [end] properties may be null; the null value
/// is treated as a right angle (no radius).
BorderRadiusTween({ BorderRadius begin, BorderRadius end }) : super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
BorderRadius lerp(double t) => BorderRadius.lerp(begin, end, t);
}
/// An interpolation between two [Matrix4]s.
///
/// This class specializes the interpolation of [Tween<Matrix4>] to be
/// appropriate for transformation matrices.
///
/// Currently this class works only for translations.
///
/// See [Tween] for a discussion on how to use interpolation objects.
class Matrix4Tween extends Tween<Matrix4> {
/// Creates a [Matrix4] tween.
///
/// The [begin] and [end] arguments must not be null.
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
/// filled in later.
Matrix4Tween({ Matrix4 begin, Matrix4 end }) : super(begin: begin, end: end);
@override
Matrix4 lerp(double t) {
assert(begin != null);
assert(end != null);
// TODO(abarth): We should use [Matrix4.decompose] and animate the
// decomposed parameters instead of just animating the translation.
final Vector3 beginT = begin.getTranslation();
......@@ -78,13 +122,21 @@ class Matrix4Tween extends Tween<Matrix4> {
/// An interpolation between two [TextStyle]s.
///
/// This class specializes the interpolation of [Tween<TextStyle>] to use
/// [TextStyle.lerp].
///
/// This will not work well if the styles don't set the same fields.
///
/// See [Tween] for a discussion on how to use interpolation objects.
class TextStyleTween extends Tween<TextStyle> {
/// Creates a text style tween.
///
/// The [begin] and [end] arguments must not be null.
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
/// filled in later.
TextStyleTween({ TextStyle begin, TextStyle end }) : super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
TextStyle lerp(double t) => TextStyle.lerp(begin, end, t);
}
......
......@@ -293,16 +293,19 @@ class FadeTransition extends AnimatedWidget {
/// An interpolation between two relative rects.
///
/// This class specializes the interpolation of Tween<RelativeRect> to be
/// appropriate for rectangles that are described in terms of offsets from
/// other rectangles.
/// This class specializes the interpolation of [Tween<RelativeRect>] to
/// use [RelativeRect.tween].
///
/// See [Tween] for a discussion on how to use interpolation objects.
class RelativeRectTween extends Tween<RelativeRect> {
/// Creates a relative rect tween.
/// Creates a [RelativeRect] tween.
///
/// The [begin] and [end] arguments must not be null.
/// The [begin] and [end] properties may be null; the null value
/// is treated as [RelativeRect.fill].
RelativeRectTween({ RelativeRect begin, RelativeRect end })
: super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
RelativeRect lerp(double t) => RelativeRect.lerp(begin, end, t);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment