提交 c7573c12 编写于 作者: R Rafael Weinstein

Add initialDelay to AnimationGenerator and add Animation class.

This patch allows for an initial delay before an animation begins and also adds an Animation class which encapsulates a value which is long-lived, can be explicitly set and also animated from its current value to another value.

BUG=
R=abarth@chromium.org

Review URL: https://codereview.chromium.org/994143002
上级 a01babc0
......@@ -6,39 +6,34 @@ const double _kBaseSettleDurationMS = 246.0;
const double _kMaxSettleDurationMS = 600.0;
const Cubic _kAnimationCurve = easeOut;
class DrawerAnimation {
class DrawerAnimation extends Animation {
Stream<double> get onPositionChanged => _controller.stream;
Stream<double> get onPositionChanged => onValueChanged;
StreamController _controller;
AnimationGenerator _animation;
double _position;
bool get _isAnimating => _animation != null;
bool get _isMostlyClosed => _position <= -_kWidth / 2;
bool get _isMostlyClosed => value <= -_kWidth / 2;
DrawerAnimation() {
_controller = new StreamController(sync: true);
_setPosition(-_kWidth);
value = -_kWidth;
}
void toggle(_) => _isMostlyClosed ? _open() : _close();
void handleMaskTap(_) => _close();
void handlePointerDown(_) => _cancelAnimation();
void handlePointerDown(_) => stop();
void handlePointerMove(sky.PointerEvent event) {
assert(_animation == null);
_setPosition(_position + event.dx);
assert(!isAnimating);
value = math.min(0.0, math.max(value + event.dx, -_kWidth));
}
void handlePointerUp(_) {
if (!_isAnimating)
if (!isAnimating)
_settle();
}
void handlePointerCancel(_) {
if (!_isAnimating)
if (!isAnimating)
_settle();
}
......@@ -48,35 +43,12 @@ class DrawerAnimation {
void _settle() => _isMostlyClosed ? _close() : _open();
void _setPosition(double value) {
_position = math.min(0.0, math.max(value, -_kWidth));
_controller.add(_position);
}
void _cancelAnimation() {
if (_animation != null) {
_animation.cancel();
_animation = null;
}
}
void _animate(double duration, double begin, double end, Curve curve) {
_cancelAnimation();
_animation = new AnimationGenerator(duration, begin: begin, end: end,
curve: curve);
_animation.onTick.listen(_setPosition, onDone: () {
_animation = null;
});
}
void _animateToPosition(double targetPosition) {
double distance = (targetPosition - _position).abs();
double distance = (targetPosition - value).abs();
if (distance != 0) {
double targetDuration = distance / _kWidth * _kBaseSettleDurationMS;
double duration = math.min(targetDuration, _kMaxSettleDurationMS);
_animate(duration, _position, targetPosition, _kAnimationCurve);
animateTo(targetPosition, duration, curve: _kAnimationCurve);
}
}
......@@ -87,10 +59,10 @@ class DrawerAnimation {
return;
double targetPosition = direction < 0.0 ? -_kWidth : 0.0;
double distance = (targetPosition - _position).abs();
double distance = (targetPosition - value).abs();
double duration = distance / velocityX;
_animate(duration, _position, targetPosition, linear);
animateTo(targetPosition, duration, curve: linear);
}
}
......
......@@ -53,6 +53,7 @@ class FrameGenerator {
class AnimationGenerator extends FrameGenerator {
Stream<double> get onTick => _stream;
final double initialDelay;
final double duration;
final double begin;
final double end;
......@@ -61,6 +62,7 @@ class AnimationGenerator extends FrameGenerator {
bool _done = false;
AnimationGenerator(this.duration, {
this.initialDelay: 0.0,
this.begin: 0.0,
this.end: 1.0,
this.curve: linear,
......@@ -71,9 +73,12 @@ class AnimationGenerator extends FrameGenerator {
_stream = super.onTick.map((timeStamp) {
if (startTime == 0.0)
startTime = timeStamp;
return math.min((timeStamp - startTime) / duration, 1.0);
double t = (timeStamp - (startTime + initialDelay)) / duration;
return math.max(0.0, math.min(t, 1.0));
})
.takeWhile(_checkForCompletion)
.takeWhile(_checkForCompletion) //
.where((t) => t >= 0.0)
.map(_transform);
}
......@@ -83,10 +88,55 @@ class AnimationGenerator extends FrameGenerator {
return begin + (end - begin) * curve.transform(t);
}
// This is required because Dart Streams don't have takeUntil (inclusive).
bool _checkForCompletion(double t) {
if (_done)
return false;
_done = t >= 1;
return true;
}
}
class Animation {
Stream<double> get onValueChanged => _controller.stream;
double get value => _value;
void set value(double value) {
stop();
_setValue(value);
}
bool get isAnimating => _animation != null;
StreamController _controller = new StreamController(sync: true);
AnimationGenerator _animation;
double _value;
void _setValue(double value) {
_value = value;
_controller.add(_value);
}
void stop() {
if (_animation != null) {
_animation.cancel();
_animation = null;
}
}
void animateTo(double newValue, double duration,
{ Curve curve: linear, double initialDelay: 0.0 }) {
stop();
_animation = new AnimationGenerator(duration, begin: _value, end: newValue,
curve: curve, initialDelay: initialDelay);
_animation.onTick.listen(_setValue, onDone: () {
_animation = null;
});
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册