Commit e4940a01 authored by Adam Barth's avatar Adam Barth

Merge pull request #1314 from abarth/port_material2

Finish porting material.dart to AnimationController
parents 5ac6f931 08b27fd7
......@@ -122,22 +122,22 @@ class AnimationController extends Animated<double>
}
/// A label that is used in the [toString] output. Intended to aid with
/// identifying performance instances in debug output.
/// identifying animation controller instances in debug output.
final String debugLabel;
/// Returns a [Animation] for this performance,
/// Returns a [Animated<double>] for this animation controller,
/// so that a pointer to this object can be passed around without
/// allowing users of that pointer to mutate the Performance state.
/// allowing users of that pointer to mutate the AnimationController state.
Animated<double> get view => this;
/// The length of time this performance should last.
/// The length of time this animation should last.
Duration duration;
SimulationStepper _timeline;
AnimationDirection get direction => _direction;
AnimationDirection _direction = AnimationDirection.forward;
/// The progress of this performance along the timeline.
/// The progress of this animation along the timeline.
///
/// Note: Setting this value stops the current animation.
double get value => _timeline.value.clamp(0.0, 1.0);
......@@ -282,7 +282,7 @@ class CurvedAnimation extends Animated<double> with ProxyAnimatedMixin {
///
/// The curve direction is only reset when we hit the beginning or the end of
/// the timeline to avoid discontinuities in the value of any variables this
/// performance is used to animate.
/// a animation is used to animate.
AnimationDirection _curveDirection;
void _handleStatusChanged(PerformanceStatus status) {
......
......@@ -61,22 +61,22 @@ class DrawerController extends StatefulComponent {
class DrawerControllerState extends State<DrawerController> {
void initState() {
super.initState();
_performance = new Performance(duration: _kBaseSettleDuration)
..addListener(_performanceChanged)
..addStatusListener(_performanceStatusChanged);
_controller = new AnimationController(duration: _kBaseSettleDuration)
..addListener(_animationChanged)
..addStatusListener(_animationStatusChanged);
}
void dispose() {
_performance
..removeListener(_performanceChanged)
..removeStatusListener(_performanceStatusChanged)
_controller
..removeListener(_animationChanged)
..removeStatusListener(_animationStatusChanged)
..stop();
super.dispose();
}
void _performanceChanged() {
void _animationChanged() {
setState(() {
// The performance's state is our build state, and it changed already.
// The animation controller's state is our build state, and it changed already.
});
}
......@@ -92,7 +92,7 @@ class DrawerControllerState extends State<DrawerController> {
}
}
void _performanceStatusChanged(PerformanceStatus status) {
void _animationStatusChanged(PerformanceStatus status) {
switch (status) {
case PerformanceStatus.forward:
_ensureHistoryEntry();
......@@ -113,7 +113,7 @@ class DrawerControllerState extends State<DrawerController> {
close();
}
Performance _performance;
AnimationController _controller;
double _width = _kEdgeDragWidth;
void _handleSizeChanged(Size newSize) {
......@@ -123,20 +123,20 @@ class DrawerControllerState extends State<DrawerController> {
}
void _handlePointerDown(_) {
_performance.stop();
_controller.stop();
_ensureHistoryEntry();
}
void _move(double delta) {
_performance.progress += delta / _width;
_controller.value += delta / _width;
}
void _settle(Offset velocity) {
if (_performance.isDismissed)
if (_controller.isDismissed)
return;
if (velocity.dx.abs() >= _kMinFlingVelocity) {
_performance.fling(velocity: velocity.dx / _width);
} else if (_performance.progress < 0.5) {
_controller.fling(velocity: velocity.dx / _width);
} else if (_controller.value < 0.5) {
close();
} else {
open();
......@@ -144,18 +144,18 @@ class DrawerControllerState extends State<DrawerController> {
}
void open() {
_performance.fling(velocity: 1.0);
_controller.fling(velocity: 1.0);
}
void close() {
_performance.fling(velocity: -1.0);
_controller.fling(velocity: -1.0);
}
final AnimatedColorValue _color = new AnimatedColorValue(Colors.transparent, end: Colors.black54);
final ColorTween _color = new ColorTween(begin: Colors.transparent, end: Colors.black54);
final GlobalKey _gestureDetectorKey = new GlobalKey();
Widget build(BuildContext context) {
if (_performance.status == PerformanceStatus.dismissed) {
if (_controller.status == PerformanceStatus.dismissed) {
return new Align(
alignment: const FractionalOffset(0.0, 0.5),
child: new GestureDetector(
......@@ -167,7 +167,6 @@ class DrawerControllerState extends State<DrawerController> {
)
);
} else {
_performance.updateVariable(_color);
return new GestureDetector(
key: _gestureDetectorKey,
onHorizontalDragUpdate: _move,
......@@ -179,7 +178,7 @@ class DrawerControllerState extends State<DrawerController> {
onTap: close,
child: new DecoratedBox(
decoration: new BoxDecoration(
backgroundColor: _color.value
backgroundColor: _color.evaluate(_controller)
),
child: new Container()
)
......@@ -190,7 +189,7 @@ class DrawerControllerState extends State<DrawerController> {
onPointerDown: _handlePointerDown,
child: new Align(
alignment: const FractionalOffset(1.0, 0.5),
widthFactor: _performance.progress,
widthFactor: _controller.value,
child: new SizeObserver(
onSizeChanged: _handleSizeChanged,
child: new RepaintBoundary(
......
......@@ -344,15 +344,21 @@ class _InkSplash extends InkFeature implements InkSplash {
this.repositionToReferenceBox,
VoidCallback onRemoved
}) : super(renderer: renderer, referenceBox: referenceBox, onRemoved: onRemoved) {
_radius = new ValuePerformance<double>(
variable: new AnimatedValue<double>(_kSplashInitialSize, end: targetRadius),
duration: _kUnconfirmedSplashDuration
)..addListener(renderer.markNeedsPaint)
..play();
_alpha = new ValuePerformance<int>(
variable: new AnimatedIntValue(color.alpha, end: 0),
duration: _kHighlightFadeDuration
)..addListener(_handleAlphaChange);
_radiusController = new AnimationController(duration: _kUnconfirmedSplashDuration)
..addListener(renderer.markNeedsPaint)
..forward();
_radius = new Tween<double>(
begin: _kSplashInitialSize,
end: targetRadius
).animate(_radiusController);
_alphaController = new AnimationController(duration: _kHighlightFadeDuration)
..addListener(renderer.markNeedsPaint)
..addStatusListener(_handleAlphaStatusChanged);
_alpha = new IntTween(
begin: color.alpha,
end: 0
).animate(_alphaController);
}
final Point position;
......@@ -361,30 +367,32 @@ class _InkSplash extends InkFeature implements InkSplash {
final bool clipToReferenceBox;
final bool repositionToReferenceBox;
ValuePerformance<double> _radius;
ValuePerformance<int> _alpha;
Animated<double> _radius;
AnimationController _radiusController;
Animated<int> _alpha;
AnimationController _alphaController;
void confirm() {
int duration = (targetRadius / _kSplashConfirmedVelocity).floor();
_radius.duration = new Duration(milliseconds: duration);
_radius.play();
_alpha.play();
_radiusController
..duration = new Duration(milliseconds: duration)
..forward();
_alphaController.forward();
}
void cancel() {
_alpha.play();
_alphaController.forward();
}
void _handleAlphaChange() {
if (_alpha.value == _alpha.variable.end)
void _handleAlphaStatusChanged(PerformanceStatus status) {
if (status == PerformanceStatus.completed)
dispose();
else
renderer.markNeedsPaint();
}
void dispose() {
_radius.stop();
_alpha.stop();
_radiusController.stop();
_alphaController.stop();
super.dispose();
}
......@@ -398,7 +406,7 @@ class _InkSplash extends InkFeature implements InkSplash {
if (clipToReferenceBox)
canvas.clipRect(Point.origin & referenceBox.size);
if (repositionToReferenceBox)
center = Point.lerp(center, Point.origin, _radius.progress);
center = Point.lerp(center, Point.origin, _radiusController.value);
canvas.drawCircle(center, _radius.value, paint);
canvas.restore();
} else {
......@@ -407,7 +415,7 @@ class _InkSplash extends InkFeature implements InkSplash {
canvas.clipRect(originOffset.toPoint() & referenceBox.size);
}
if (repositionToReferenceBox)
center = Point.lerp(center, referenceBox.size.center(Point.origin), _radius.progress);
center = Point.lerp(center, referenceBox.size.center(Point.origin), _radiusController.value);
canvas.drawCircle(center + originOffset, _radius.value, paint);
if (clipToReferenceBox)
canvas.restore();
......@@ -424,11 +432,14 @@ class _InkHighlight extends InkFeature implements InkHighlight {
VoidCallback onRemoved
}) : _color = color,
super(renderer: renderer, referenceBox: referenceBox, onRemoved: onRemoved) {
_alpha = new ValuePerformance<int>(
variable: new AnimatedIntValue(0, end: color.alpha),
duration: _kHighlightFadeDuration
)..addListener(_handleAlphaChange)
..play();
_alphaController = new AnimationController(duration: _kHighlightFadeDuration)
..addListener(renderer.markNeedsPaint)
..addStatusListener(_handleAlphaStatusChanged)
..forward();
_alpha = new IntTween(
begin: 0,
end: color.alpha
).animate(_alphaController);
}
Color get color => _color;
......@@ -444,27 +455,27 @@ class _InkHighlight extends InkFeature implements InkHighlight {
bool get active => _active;
bool _active = true;
ValuePerformance<int> _alpha;
Animated<int> _alpha;
AnimationController _alphaController;
void activate() {
_active = true;
_alpha.forward();
_alphaController.forward();
}
void deactivate() {
_active = false;
_alpha.reverse();
_alphaController.reverse();
}
void _handleAlphaChange() {
if (_alpha.value == 0.0 && !_active)
void _handleAlphaStatusChanged(PerformanceStatus status) {
if (status == PerformanceStatus.dismissed && !_active)
dispose();
else
renderer.markNeedsPaint();
}
void dispose() {
_alpha.stop();
_alphaController.stop();
super.dispose();
}
......
......@@ -444,8 +444,8 @@ class _PersistentBottomSheet extends StatefulComponent {
class _PersistentBottomSheetState extends State<_PersistentBottomSheet> {
// We take ownership of the performance given in the first configuration.
// We also share control of that performance with out BottomSheet widget.
// We take ownership of the animation controller given in the first configuration.
// We also share control of that animation with out BottomSheet widget.
void initState() {
super.initState();
......
......@@ -60,16 +60,17 @@ class ScrollbarPainter extends ScrollableListPainter {
paintScrollbar(context, offset);
}
ValuePerformance<double> _fade;
AnimationController _fade;
Future scrollStarted() {
_fade ??= new ValuePerformance<double>()
..duration = _kScrollbarThumbFadeDuration
..variable = new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.ease)
..addListener(() {
_opacity = _fade.value;
if (_fade == null) {
_fade = new AnimationController(duration: _kScrollbarThumbFadeDuration);
CurvedAnimation curve = new CurvedAnimation(parent: _fade, curve: Curves.ease);
curve.addListener(() {
_opacity = curve.value;
renderObject?.markNeedsPaint();
});
}
return _fade.forward();
}
......
......@@ -90,10 +90,14 @@ class _RenderSlider extends RenderConstrainedBox {
..onStart = _handleDragStart
..onUpdate = _handleDragUpdate
..onEnd = _handleDragEnd;
_reaction = new ValuePerformance<double>(
variable: new AnimatedValue<double>(_kThumbRadius, end: _kReactionRadius, curve: Curves.ease),
duration: kRadialReactionDuration
)..addListener(markNeedsPaint);
_reactionController = new AnimationController(duration: kRadialReactionDuration);
_reaction = new Tween<double>(
begin: _kThumbRadius,
end: _kReactionRadius
).animate(new CurvedAnimation(
parent: _reactionController,
curve: Curves.ease
))..addListener(markNeedsPaint);
}
double get value => _value;
......@@ -118,7 +122,9 @@ class _RenderSlider extends RenderConstrainedBox {
ValueChanged<double> onChanged;
double get _trackLength => size.width - 2.0 * _kReactionRadius;
ValuePerformance<double> _reaction;
Animated<double> _reaction;
AnimationController _reactionController;
HorizontalDragGestureRecognizer _drag;
bool _active = false;
......@@ -129,7 +135,7 @@ class _RenderSlider extends RenderConstrainedBox {
_active = true;
_currentDragValue = (globalToLocal(globalPosition).x - _kReactionRadius) / _trackLength;
onChanged(_currentDragValue.clamp(0.0, 1.0));
_reaction.forward();
_reactionController.forward();
markNeedsPaint();
}
}
......@@ -145,7 +151,7 @@ class _RenderSlider extends RenderConstrainedBox {
if (_active) {
_active = false;
_currentDragValue = 0.0;
_reaction.reverse();
_reactionController.reverse();
markNeedsPaint();
}
}
......
......@@ -147,24 +147,24 @@ class _RenderSwitch extends RenderToggleable {
void _handleDragStart(Point globalPosition) {
if (onChanged != null)
reaction.forward();
reactionController.forward();
}
void _handleDragUpdate(double delta) {
if (onChanged != null) {
position.variable
position
..curve = null
..reverseCurve = null;
position.progress += delta / _trackInnerLength;
positionController.value += delta / _trackInnerLength;
}
}
void _handleDragEnd(Offset velocity) {
if (position.progress >= 0.5)
position.forward();
if (position.value >= 0.5)
positionController.forward();
else
position.reverse();
reaction.reverse();
positionController.reverse();
reactionController.reverse();
}
void handleEvent(PointerEvent event, BoxHitTestEntry entry) {
......@@ -181,8 +181,8 @@ class _RenderSwitch extends RenderToggleable {
final bool isActive = onChanged != null;
Color thumbColor = isActive ? Color.lerp(inactiveColor, activeColor, position.progress) : inactiveColor;
Color trackColor = isActive ? Color.lerp(inactiveTrackColor, activeTrackColor, position.progress) : inactiveTrackColor;
Color thumbColor = isActive ? Color.lerp(inactiveColor, activeColor, position.value) : inactiveColor;
Color trackColor = isActive ? Color.lerp(inactiveTrackColor, activeTrackColor, position.value) : inactiveTrackColor;
// Paint the track
Paint paint = new Paint()
......
......@@ -416,7 +416,7 @@ class TabBarSelection<T> extends StatefulComponent {
class TabBarSelectionState<T> extends State<TabBarSelection<T>> {
Animated<double> get animation => _controller.view;
// Both the TabBar and TabBarView classes access _performance because they
// Both the TabBar and TabBarView classes access _controller because they
// alternately drive selection progress between tabs.
final AnimationController _controller = new AnimationController(duration: _kTabBarScroll, value: 1.0);
final Map<T, int> _valueToIndex = new Map<T, int>();
......@@ -470,7 +470,7 @@ class TabBarSelectionState<T> extends State<TabBarSelection<T>> {
_valueIsChanging = true;
// If the selected value change was triggered by a drag gesture, the current
// value of _performance.progress will reflect where the gesture ended. While
// value of _controller.value will reflect where the gesture ended. While
// the drag was underway progress indicates where the indicator and TabBarView
// scrollPosition are vis the indices of the two tabs adjacent to the selected
// one. So 0.5 means the drag didn't move at all, 0.0 means the drag extended
......
......@@ -336,10 +336,12 @@ class _Dial extends StatefulComponent {
class _DialState extends State<_Dial> {
void initState() {
super.initState();
_theta = new ValuePerformance(
variable: new AnimatedValue<double>(_getThetaForTime(config.selectedTime), curve: Curves.ease),
duration: _kDialAnimateDuration
)..addListener(() => setState(() { }));
_thetaController = new AnimationController(duration: _kDialAnimateDuration);
_thetaTween = new Tween<double>(begin: _getThetaForTime(config.selectedTime));
_theta = _thetaTween.animate(new CurvedAnimation(
parent: _thetaController,
curve: Curves.ease
))..addListener(() => setState(() { }));
}
void didUpdateConfig(_Dial oldConfig) {
......@@ -347,7 +349,9 @@ class _DialState extends State<_Dial> {
_animateTo(_getThetaForTime(config.selectedTime));
}
ValuePerformance<double> _theta;
Tween<double> _thetaTween;
Animated<double> _theta;
AnimationController _thetaController;
bool _dragging = false;
static double _nearest(double target, double a, double b) {
......@@ -358,11 +362,12 @@ class _DialState extends State<_Dial> {
double currentTheta = _theta.value;
double beginTheta = _nearest(targetTheta, currentTheta, currentTheta + _kTwoPi);
beginTheta = _nearest(targetTheta, beginTheta, currentTheta - _kTwoPi);
_theta
..variable.begin = beginTheta
..variable.end = targetTheta
..progress = 0.0
..play();
_thetaTween
..begin = beginTheta
..end = targetTheta;
_thetaController
..value = 0.0
..forward();
}
double _getThetaForTime(TimeOfDay time) {
......@@ -397,7 +402,9 @@ class _DialState extends State<_Dial> {
void _updateThetaForPan() {
setState(() {
Offset offset = _position - _center;
_theta.variable.value = (math.atan2(offset.dx, offset.dy) - math.PI / 2.0) % _kTwoPi;
_thetaTween
..begin = (math.atan2(offset.dx, offset.dy) - math.PI / 2.0) % _kTwoPi
..end = null;
});
}
......
......@@ -34,16 +34,24 @@ abstract class RenderToggleable extends RenderConstrainedBox {
..onTap = _handleTap
..onTapUp = _handleTapUp
..onTapCancel = _handleTapCancel;
_position = new ValuePerformance<double>(
variable: new AnimatedValue<double>(0.0, end: 1.0),
_positionController = new AnimationController(
duration: _kToggleDuration,
progress: _value ? 1.0 : 0.0
value: _value ? 1.0 : 0.0
);
_position = new CurvedAnimation(
parent: _positionController
)..addListener(markNeedsPaint)
..addStatusListener(_handlePositionStateChanged);
_reaction = new ValuePerformance<double>(
variable: new AnimatedValue<double>(minRadialReactionRadius, end: kRadialReactionRadius, curve: Curves.ease),
duration: kRadialReactionDuration
)..addListener(markNeedsPaint);
_reactionController = new AnimationController(duration: kRadialReactionDuration);
_reaction = new Tween<double>(
begin: minRadialReactionRadius,
end: kRadialReactionRadius
).animate(new CurvedAnimation(
parent: _reactionController,
curve: Curves.ease
))..addListener(markNeedsPaint);
}
bool get value => _value;
......@@ -53,10 +61,10 @@ abstract class RenderToggleable extends RenderConstrainedBox {
if (value == _value)
return;
_value = value;
_position.variable
_position
..curve = Curves.easeIn
..reverseCurve = Curves.easeOut;
_position.play(value ? AnimationDirection.forward : AnimationDirection.reverse);
_positionController.play(value ? AnimationDirection.forward : AnimationDirection.reverse);
}
Color get activeColor => _activeColor;
......@@ -83,11 +91,15 @@ abstract class RenderToggleable extends RenderConstrainedBox {
ValueChanged<bool> onChanged;
ValuePerformance<double> get position => _position;
ValuePerformance<double> _position;
CurvedAnimation get position => _position;
CurvedAnimation _position;
AnimationController get positionController => _positionController;
AnimationController _positionController;
ValuePerformance<double> get reaction => _reaction;
ValuePerformance<double> _reaction;
AnimationController get reactionController => _reactionController;
AnimationController _reactionController;
Animated<double> _reaction;
TapGestureRecognizer _tap;
......@@ -102,7 +114,7 @@ abstract class RenderToggleable extends RenderConstrainedBox {
void _handleTapDown(Point globalPosition) {
if (isInteractive)
_reaction.forward();
_reactionController.forward();
}
void _handleTap() {
......@@ -112,12 +124,12 @@ abstract class RenderToggleable extends RenderConstrainedBox {
void _handleTapUp(Point globalPosition) {
if (isInteractive)
_reaction.reverse();
_reactionController.reverse();
}
void _handleTapCancel() {
if (isInteractive)
_reaction.reverse();
_reactionController.reverse();
}
bool hitTestSelf(Point position) => true;
......@@ -128,10 +140,10 @@ abstract class RenderToggleable extends RenderConstrainedBox {
}
void paintRadialReaction(Canvas canvas, Offset offset) {
if (!reaction.isDismissed) {
if (!_reaction.isDismissed) {
// TODO(abarth): We should have a different reaction color when position is zero.
Paint reactionPaint = new Paint()..color = activeColor.withAlpha(kRadialReactionAlpha);
canvas.drawCircle(offset.toPoint(), reaction.value, reactionPaint);
canvas.drawCircle(offset.toPoint(), _reaction.value, reactionPaint);
}
}
}
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