提交 70aa7795 编写于 作者: A Adam Barth

Scrollable should settle back to 0.0

This CL teaches Scrollable how to settle back to a scroll offset of 0.0 after a
fling or a scroll. There's still some room for improvement:

1) Some of this logic should be factored out into the scroll curve object.
2) We don't produce the correct animation curves when we fling into the
   overscroll region because we wait for the fling velocity to reach zero
   before we start the settling animation.

R=ojan@chromium.org, eseidel@chromium.org

Review URL: https://codereview.chromium.org/1005753002
上级 52d2d677
......@@ -61,14 +61,15 @@ class AnimationGenerator extends FrameGenerator {
Stream<double> _stream;
bool _done = false;
AnimationGenerator(this.duration, {
AnimationGenerator({
this.initialDelay: 0.0,
this.duration,
this.begin: 0.0,
this.end: 1.0,
this.curve: linear,
Function onDone
}):super(onDone: onDone) {
assert(duration > 0);
assert(duration != null && duration > 0.0);
double startTime = 0.0;
_stream = super.onTick.map((timeStamp) {
if (startTime == 0.0)
......@@ -132,8 +133,12 @@ class Animation {
{ Curve curve: linear, double initialDelay: 0.0 }) {
stop();
_animation = new AnimationGenerator(duration, begin: _value, end: newValue,
curve: curve, initialDelay: initialDelay);
_animation = new AnimationGenerator(
duration: duration,
begin: _value,
end: newValue,
curve: curve,
initialDelay: initialDelay);
_animation.onTick.listen(_setValue, onDone: () {
_animation = null;
......
......@@ -27,8 +27,11 @@ class SplashAnimation {
: _offsetX = x - rect.left,
_offsetY = y - rect.top {
_animation = new AnimationGenerator(_kSplashDuration,
end: _kSplashSize, curve: easeOut, onDone: onDone);
_animation = new AnimationGenerator(
duration:_kSplashDuration,
end: _kSplashSize,
curve: easeOut,
onDone: onDone);
_styleChanged = _animation.onTick.map((p) => '''
top: ${_offsetY - p/2}px;
......
......@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../animation/curves.dart';
import '../animation/fling_curve.dart';
import '../animation/generator.dart';
import '../animation/scroll_curve.dart';
import '../fn.dart';
import 'dart:sky' as sky;
......@@ -14,8 +16,12 @@ abstract class Scrollable extends Component {
double _scrollOffset = 0.0;
FlingCurve _flingCurve;
int _flingAnimationId;
AnimationGenerator _scrollAnimation;
Scrollable({Object key, this.scrollCurve}) : super(key: key) {
events.listen('pointerdown', _handlePointerDown);
events.listen('pointerup', _handlePointerUpOrCancel);
events.listen('pointercancel', _handlePointerUpOrCancel);
events.listen('gestureflingstart', _handleFlingStart);
events.listen('gestureflingcancel', _handleFlingCancel);
events.listen('gesturescrollupdate', _handleScrollUpdate);
......@@ -25,6 +31,7 @@ abstract class Scrollable extends Component {
void didUnmount() {
super.didUnmount();
_stopFling();
_stopScrollAnimation();
}
bool scrollBy(double scrollDelta) {
......@@ -37,6 +44,25 @@ abstract class Scrollable extends Component {
return true;
}
void animateScrollTo(double targetScrollOffset, {
double initialDelay: 0.0,
double duration: 0.0,
Curve curve: linear}) {
_stopScrollAnimation();
_scrollAnimation = new AnimationGenerator(
duration: duration,
begin: _scrollOffset,
end: targetScrollOffset,
initialDelay: initialDelay,
curve: curve);
_scrollAnimation.onTick.listen((newScrollOffset) {
if (!scrollBy(newScrollOffset - _scrollOffset))
_stopScrollAnimation();
}, onDone: () {
_scrollAnimation = null;
});
}
void _scheduleFlingUpdate() {
_flingAnimationId = sky.window.requestAnimationFrame(_updateFling);
}
......@@ -49,26 +75,48 @@ abstract class Scrollable extends Component {
_flingAnimationId = null;
}
void _stopScrollAnimation() {
if (_scrollAnimation == null)
return;
_scrollAnimation.cancel();
_scrollAnimation = null;
}
void _updateFling(double timeStamp) {
double scrollDelta = _flingCurve.update(timeStamp);
if (!scrollBy(scrollDelta))
return _stopFling();
return _settle();
_scheduleFlingUpdate();
}
void _settle() {
_stopFling();
if (_scrollOffset < 0.0)
animateScrollTo(0.0, duration: 200.0, curve: easeOut);
}
void _handlePointerDown(_) {
_stopFling();
_stopScrollAnimation();
}
void _handlePointerUpOrCancel(_) {
if (_flingCurve == null)
_settle();
}
void _handleScrollUpdate(sky.GestureEvent event) {
scrollBy(-event.dy);
}
void _handleFlingStart(sky.GestureEvent event) {
setState(() {
_flingCurve = new FlingCurve(-event.velocityY, event.timeStamp);
_scheduleFlingUpdate();
});
_stopScrollAnimation();
_flingCurve = new FlingCurve(-event.velocityY, event.timeStamp);
_scheduleFlingUpdate();
}
void _handleFlingCancel(sky.GestureEvent event) {
_stopFling();
_settle();
}
void _handleWheel(sky.WheelEvent event) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册