diff --git a/examples/flutter_gallery/lib/demo/material/bottom_navigation_demo.dart b/examples/flutter_gallery/lib/demo/material/bottom_navigation_demo.dart index 63b57919ca1..74651f88a5d 100644 --- a/examples/flutter_gallery/lib/demo/material/bottom_navigation_demo.dart +++ b/examples/flutter_gallery/lib/demo/material/bottom_navigation_demo.dart @@ -47,9 +47,9 @@ class NavigationIconView { return new FadeTransition( opacity: _animation, child: new SlideTransition( - position: new AlignmentTween( - begin: const Alignment(0.0, 0.4), // Slightly down. - end: Alignment.center, + position: new Tween( + begin: const Offset(0.0, 0.02), // Slightly down. + end: Offset.zero, ).animate(_animation), child: new IconTheme( data: new IconThemeData( diff --git a/examples/flutter_gallery/lib/demo/material/drawer_demo.dart b/examples/flutter_gallery/lib/demo/material/drawer_demo.dart index 85c1e3284ed..f35f1b007da 100644 --- a/examples/flutter_gallery/lib/demo/material/drawer_demo.dart +++ b/examples/flutter_gallery/lib/demo/material/drawer_demo.dart @@ -25,7 +25,7 @@ class _DrawerDemoState extends State with TickerProviderStateMixin { AnimationController _controller; Animation _drawerContentsOpacity; - Animation _drawerDetailsPosition; + Animation _drawerDetailsPosition; bool _showDrawerContents = true; @override @@ -39,9 +39,9 @@ class _DrawerDemoState extends State with TickerProviderStateMixin { parent: new ReverseAnimation(_controller), curve: Curves.fastOutSlowIn, ); - _drawerDetailsPosition = new AlignmentTween( - begin: const Alignment(0.0, -2.0), - end: Alignment.center, + _drawerDetailsPosition = new Tween( + begin: const Offset(0.0, -1.0), + end: Offset.zero, ).animate(new CurvedAnimation( parent: _controller, curve: Curves.fastOutSlowIn, diff --git a/packages/flutter/lib/src/cupertino/route.dart b/packages/flutter/lib/src/cupertino/route.dart index 6ad11015bb0..46355adae01 100644 --- a/packages/flutter/lib/src/cupertino/route.dart +++ b/packages/flutter/lib/src/cupertino/route.dart @@ -10,22 +10,22 @@ import 'package:flutter/widgets.dart'; const double _kBackGestureWidth = 20.0; const double _kMinFlingVelocity = 1.0; // Screen widths per second. -// Fractional offset from offscreen to the right to fully on screen. -final AlignmentTween _kRightMiddleTween = new AlignmentTween( - begin: Alignment.centerRight * 2.0, - end: Alignment.center, +// Offset from offscreen to the right to fully on screen. +final Tween _kRightMiddleTween = new Tween( + begin: const Offset(1.0, 0.0), + end: Offset.zero, ); -// Fractional offset from fully on screen to 1/3 offscreen to the left. -final AlignmentTween _kMiddleLeftTween = new AlignmentTween( - begin: Alignment.center, - end: const Alignment(-2.0/3.0, 0.0), +// Offset from fully on screen to 1/3 offscreen to the left. +final Tween _kMiddleLeftTween = new Tween( + begin: Offset.zero, + end: const Offset(-1.0/3.0, 0.0), ); -// Fractional offset from offscreen below to fully on screen. -final AlignmentTween _kBottomUpTween = new AlignmentTween( - begin: Alignment.bottomCenter * 2.0, - end: Alignment.center, +// Offset from offscreen below to fully on screen. +final Tween _kBottomUpTween = new Tween( + begin: const Offset(0.0, 1.0), + end: Offset.zero, ); // Custom decoration from no shadow to page shadow mimicking iOS page @@ -318,9 +318,9 @@ class CupertinoPageTransition extends StatelessWidget { super(key: key); // When this page is coming in to cover another page. - final Animation _primaryPositionAnimation; + final Animation _primaryPositionAnimation; // When this page is becoming covered by another page. - final Animation _secondaryPositionAnimation; + final Animation _secondaryPositionAnimation; final Animation _primaryShadowAnimation; /// The widget below this widget in the tree. @@ -361,7 +361,7 @@ class CupertinoFullscreenDialogTransition extends StatelessWidget { ), super(key: key); - final Animation _positionAnimation; + final Animation _positionAnimation; /// The widget below this widget in the tree. final Widget child; diff --git a/packages/flutter/lib/src/material/page.dart b/packages/flutter/lib/src/material/page.dart index e086207df33..967277d2f75 100644 --- a/packages/flutter/lib/src/material/page.dart +++ b/packages/flutter/lib/src/material/page.dart @@ -9,9 +9,9 @@ import 'package:flutter/widgets.dart'; import 'theme.dart'; // Fractional offset from 1/4 screen below the top to fully on screen. -final AlignmentTween _kBottomUpTween = new AlignmentTween( - begin: Alignment.bottomCenter * 0.5, - end: Alignment.center +final Tween _kBottomUpTween = new Tween( + begin: const Offset(0.0, 0.25), + end: Offset.zero, ); // Used for Android and Fuchsia. @@ -26,7 +26,7 @@ class _MountainViewPageTransition extends StatelessWidget { )), super(key: key); - final Animation _positionAnimation; + final Animation _positionAnimation; final Widget child; @override diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart index 3447072e23b..1034460a6fb 100644 --- a/packages/flutter/lib/src/rendering/proxy_box.dart +++ b/packages/flutter/lib/src/rendering/proxy_box.dart @@ -1896,27 +1896,33 @@ class RenderFittedBox extends RenderProxyBox { /// Applies a translation transformation before painting its child. /// -/// The translation is expressed as a [Alignment] relative to the -/// RenderFractionalTranslation box's size. Hit tests will only be detected -/// inside the bounds of the RenderFractionalTranslation, even if the contents -/// are offset such that they overflow. +/// The translation is expressed as a [Offset] scaled to the child's size. For +/// example, an [Offset] with a `dx` of 0.25 will result in a horizontal +/// translation of one quarter the width of the child. +/// +/// Hit tests will only be detected inside the bounds of the +/// [RenderFractionalTranslation], even if the contents are offset such that +/// they overflow. class RenderFractionalTranslation extends RenderProxyBox { /// Creates a render object that translates its child's painting. /// /// The [translation] argument must not be null. RenderFractionalTranslation({ - Alignment translation, + @required Offset translation, this.transformHitTests: true, RenderBox child - }) : assert(translation == null || (translation.x != null && translation.y != null)), + }) : assert(translation != null), _translation = translation, super(child); - /// The translation to apply to the child, relative to the child's center. - Alignment get translation => _translation; - Alignment _translation; - set translation(Alignment value) { - assert(value == null || (value.x != null && value.y != null)); + /// The translation to apply to the child, scaled to the child's size. + /// + /// For example, an [Offset] with a `dx` of 0.25 will result in a horizontal + /// translation of one quarter the width of the child. + Offset get translation => _translation; + Offset _translation; + set translation(Offset value) { + assert(value != null); if (_translation == value) return; _translation = value; @@ -1935,11 +1941,9 @@ class RenderFractionalTranslation extends RenderProxyBox { bool hitTest(HitTestResult result, { Offset position }) { assert(!debugNeedsLayout); if (transformHitTests) { - final double halfWidth = size.width / 2.0; - final double halfHeight = size.height / 2.0; position = new Offset( - position.dx - translation.x * halfWidth, - position.dy - translation.y * halfHeight, + position.dx - translation.dx * size.width, + position.dy - translation.dy * size.height, ); } return super.hitTest(result, position: position); @@ -1949,26 +1953,25 @@ class RenderFractionalTranslation extends RenderProxyBox { void paint(PaintingContext context, Offset offset) { assert(!debugNeedsLayout); if (child != null) { - final double halfWidth = size.width / 2.0; - final double halfHeight = size.height / 2.0; super.paint(context, new Offset( - offset.dx + translation.x * halfWidth, - offset.dy + translation.y * halfHeight, + offset.dx + translation.dx * size.width, + offset.dy + translation.dy * size.height, )); } } @override void applyPaintTransform(RenderBox child, Matrix4 transform) { - final double halfWidth = size.width / 2.0; - final double halfHeight = size.height / 2.0; - transform.translate(translation.x * halfWidth, translation.y * halfHeight); + transform.translate( + translation.dx * size.width, + translation.dy * size.height, + ); } @override void debugFillProperties(DiagnosticPropertiesBuilder description) { super.debugFillProperties(description); - description.add(new DiagnosticsProperty('translation', translation)); + description.add(new DiagnosticsProperty('translation', translation)); description.add(new DiagnosticsProperty('transformHitTests', transformHitTests)); } } diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart index 5beb4e6d310..3a455cf9ead 100644 --- a/packages/flutter/lib/src/widgets/basic.dart +++ b/packages/flutter/lib/src/widgets/basic.dart @@ -987,8 +987,15 @@ class FittedBox extends SingleChildRenderObjectWidget { } } -/// A widget that applies a translation expressed as a fraction of the box's -/// size before painting its child. +/// Applies a translation transformation before painting its child. +/// +/// The translation is expressed as a [Offset] scaled to the child's size. For +/// example, an [Offset] with a `dx` of 0.25 will result in a horizontal +/// translation of one quarter the width of the child. +/// +/// Hit tests will only be detected inside the bounds of the +/// [FractionalTranslation], even if the contents are offset such that +/// they overflow. class FractionalTranslation extends SingleChildRenderObjectWidget { /// Creates a widget that translates its child's painting. /// @@ -1001,8 +1008,11 @@ class FractionalTranslation extends SingleChildRenderObjectWidget { }) : assert(translation != null), super(key: key, child: child); - /// The translation to apply to the child, relative to the child's center. - final Alignment translation; + /// The translation to apply to the child, scaled to the child's size. + /// + /// For example, an [Offset] with a `dx` of 0.25 will result in a horizontal + /// translation of one quarter the width of the child. + final Offset translation; /// Whether to apply the translation when performing hit tests. final bool transformHitTests; diff --git a/packages/flutter/lib/src/widgets/dismissible.dart b/packages/flutter/lib/src/widgets/dismissible.dart index e83245fcaa1..491f2c2c303 100644 --- a/packages/flutter/lib/src/widgets/dismissible.dart +++ b/packages/flutter/lib/src/widgets/dismissible.dart @@ -135,21 +135,19 @@ class _DismissibleClipper extends CustomClipper { super(reclip: moveAnimation); final Axis axis; - final Animation moveAnimation; + final Animation moveAnimation; @override Rect getClip(Size size) { assert(axis != null); switch (axis) { case Axis.horizontal: - final double halfWidth = size.width / 2.0; - final double offset = halfWidth + moveAnimation.value.x * halfWidth; + final double offset = moveAnimation.value.dx * size.width; if (offset < 0) return new Rect.fromLTRB(size.width + offset, 0.0, size.width, size.height); return new Rect.fromLTRB(0.0, 0.0, offset, size.height); case Axis.vertical: - final double halfHeight = size.height / 2.0; - final double offset = halfHeight + moveAnimation.value.y * halfHeight; + final double offset = moveAnimation.value.dy * size.height; if (offset < 0) return new Rect.fromLTRB(0.0, size.height + offset, size.width, size.height); return new Rect.fromLTRB(0.0, 0.0, size.width, offset); @@ -177,7 +175,7 @@ class _DismissibleState extends State with TickerProviderStateMixin } AnimationController _moveController; - Animation _moveAnimation; + Animation _moveAnimation; AnimationController _resizeController; Animation _resizeAnimation; @@ -270,10 +268,10 @@ class _DismissibleState extends State with TickerProviderStateMixin } void _updateMoveAnimation() { - final double end = _dragExtent.sign * 2.0; - _moveAnimation = new AlignmentTween( - begin: Alignment.center, - end: _directionIsXAxis ? new Alignment(end, 0.0) : new Alignment(0.0, end), + final double end = _dragExtent.sign; + _moveAnimation = new Tween( + begin: Offset.zero, + end: _directionIsXAxis ? new Offset(end, 0.0) : new Offset(0.0, end), ).animate(_moveController); } diff --git a/packages/flutter/lib/src/widgets/routes.dart b/packages/flutter/lib/src/widgets/routes.dart index 14e0307fdd8..fc47c43c6df 100644 --- a/packages/flutter/lib/src/widgets/routes.dart +++ b/packages/flutter/lib/src/widgets/routes.dart @@ -632,9 +632,9 @@ abstract class ModalRoute extends TransitionRoute with LocalHistoryRoute( + /// begin: const Offset(0.0, 1.0), + /// end: Offset.zero, /// ).animate(animation), /// child: child, // child is the value returned by pageBuilder /// ); @@ -670,13 +670,13 @@ abstract class ModalRoute extends TransitionRoute with LocalHistoryRoute { } /// Animates the position of a widget relative to its normal position. +/// +/// The translation is expressed as a [Offset] scaled to the child's size. For +/// example, an [Offset] with a `dx` of 0.25 will result in a horizontal +/// translation of one quarter the width of the child. class SlideTransition extends AnimatedWidget { /// Creates a fractional translation transition. /// /// The [position] argument must not be null. const SlideTransition({ Key key, - @required Animation position, + @required Animation position, this.transformHitTests: true, this.child, - }) : super(key: key, listenable: position); + }) : assert(position != null), + super(key: key, listenable: position); /// The animation that controls the position of the child. /// - /// If the current value of the position animation is (dx, dy), the child will - /// be translated horizontally by width * dx and vertically by height * dy. - Animation get position => listenable; + /// If the current value of the position animation is `(dx, dy)`, the child + /// will be translated horizontally by `width * dx` and vertically by + /// `height * dy`. + Animation get position => listenable; /// Whether hit testing should be affected by the slide animation. ///