Index: sky/framework/components/drawer.dart |
diff --git a/sky/framework/components/drawer.dart b/sky/framework/components/drawer.dart |
index 77a36a98c8bd0b3b48bbee26009cd2076dda28c0..731a8331e5854aa61f2c44707d015a777fc3acb3 100644 |
--- a/sky/framework/components/drawer.dart |
+++ b/sky/framework/components/drawer.dart |
@@ -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 '../animation/animation.dart'; |
+import '../animation/animated_value.dart'; |
import '../animation/curves.dart'; |
import '../fn.dart'; |
import '../theme/colors.dart'; |
@@ -18,34 +18,30 @@ const double _kBaseSettleDurationMS = 246.0; |
const double _kMaxSettleDurationMS = 600.0; |
const Curve _kAnimationCurve = parabolicRise; |
-class DrawerAnimation extends Animation { |
- Stream<double> get onPositionChanged => onValueChanged; |
+class DrawerController { |
+ final AnimatedValue position = new AnimatedValue(-_kWidth); |
- bool get _isMostlyClosed => value <= -_kWidth / 2; |
- |
- DrawerAnimation() { |
- value = -_kWidth; |
- } |
+ bool get _isMostlyClosed => position.value <= -_kWidth / 2; |
void toggle(_) => _isMostlyClosed ? _open() : _close(); |
void handleMaskTap(_) => _close(); |
- void handlePointerDown(_) => stop(); |
+ void handlePointerDown(_) => position.stop(); |
void handlePointerMove(sky.PointerEvent event) { |
- if (isAnimating) |
+ if (position.isAnimating) |
return; |
- value = math.min(0.0, math.max(value + event.dx, -_kWidth)); |
+ position.value = math.min(0.0, math.max(position.value + event.dx, -_kWidth)); |
} |
void handlePointerUp(_) { |
- if (!isAnimating) |
+ if (!position.isAnimating) |
_settle(); |
} |
void handlePointerCancel(_) { |
- if (!isAnimating) |
+ if (!position.isAnimating) |
_settle(); |
} |
@@ -56,11 +52,11 @@ class DrawerAnimation extends Animation { |
void _settle() => _isMostlyClosed ? _close() : _open(); |
void _animateToPosition(double targetPosition) { |
- double distance = (targetPosition - value).abs(); |
+ double distance = (targetPosition - position.value).abs(); |
if (distance != 0) { |
double targetDuration = distance / _kWidth * _kBaseSettleDurationMS; |
double duration = math.min(targetDuration, _kMaxSettleDurationMS); |
- animateTo(targetPosition, duration, curve: _kAnimationCurve); |
+ position.animateTo(targetPosition, duration, curve: _kAnimationCurve); |
} |
} |
@@ -71,10 +67,10 @@ class DrawerAnimation extends Animation { |
return; |
double targetPosition = direction < 0.0 ? -_kWidth : 0.0; |
- double distance = (targetPosition - value).abs(); |
+ double distance = (targetPosition - position.value).abs(); |
double duration = distance / velocityX; |
- animateTo(targetPosition, duration, curve: linear); |
+ position.animateTo(targetPosition, duration, curve: linear); |
} |
} |
@@ -101,58 +97,49 @@ class Drawer extends Component { |
background-color: ${Grey[50]}; |
will-change: transform; |
position: absolute; |
- width: 304px; |
+ width: ${_kWidth}px; |
top: 0; |
left: 0; |
bottom: 0;''' |
); |
- DrawerAnimation animation; |
List<Node> children; |
int level; |
+ DrawerController controller; |
+ |
+ AnimatedValueListener _position; |
Drawer({ |
Object key, |
- this.animation, |
+ this.controller, |
this.children, |
this.level: 0 |
}) : super(key: key) { |
- events.listen('pointerdown', animation.handlePointerDown); |
- events.listen('pointermove', animation.handlePointerMove); |
- events.listen('pointerup', animation.handlePointerUp); |
- events.listen('pointercancel', animation.handlePointerCancel); |
+ events.listen('pointerdown', controller.handlePointerDown); |
+ events.listen('pointermove', controller.handlePointerMove); |
+ events.listen('pointerup', controller.handlePointerUp); |
+ events.listen('pointercancel', controller.handlePointerCancel); |
+ _position = new AnimatedValueListener(this, controller.position); |
} |
- double _position = -_kWidth; |
- |
- bool _listening = false; |
- |
- void _ensureListening() { |
- if (_listening) |
- return; |
- |
- _listening = true; |
- animation.onPositionChanged.listen((position) { |
- setState(() { |
- _position = position; |
- }); |
- }); |
+ void didUnmount() { |
+ _position.stopListening(); |
} |
Node build() { |
- _ensureListening(); |
+ _position.ensureListening(); |
- bool isClosed = _position <= -_kWidth; |
+ bool isClosed = _position.value <= -_kWidth; |
String inlineStyle = 'display: ${isClosed ? 'none' : ''}'; |
- String maskInlineStyle = 'opacity: ${(_position / _kWidth + 1) * 0.5}'; |
- String contentInlineStyle = 'transform: translateX(${_position}px)'; |
+ String maskInlineStyle = 'opacity: ${(_position.value / _kWidth + 1) * 0.5}'; |
+ String contentInlineStyle = 'transform: translateX(${_position.value}px)'; |
Container mask = new Container( |
key: 'Mask', |
style: _maskStyle, |
inlineStyle: maskInlineStyle |
- )..events.listen('gesturetap', animation.handleMaskTap) |
- ..events.listen('gestureflingstart', animation.handleFlingStart); |
+ )..events.listen('gesturetap', controller.handleMaskTap) |
+ ..events.listen('gestureflingstart', controller.handleFlingStart); |
Material content = new Material( |
key: 'Content', |