Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(263)

Side by Side Diff: sky/framework/components/scrollable.dart

Issue 999423004: Drive overscroll animations with a physics simulation (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: More comments Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/framework/animation/simulation.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 import '../animation/curves.dart'; 5 import '../animation/curves.dart';
6 import '../animation/fling_curve.dart'; 6 import '../animation/fling_curve.dart';
7 import '../animation/generator.dart'; 7 import '../animation/generator.dart';
8 import '../animation/scroll_curve.dart'; 8 import '../animation/scroll_curve.dart';
9 import '../animation/kinematics.dart';
10 import '../animation/simulation.dart';
9 import '../fn.dart'; 11 import '../fn.dart';
10 import 'dart:sky' as sky; 12 import 'dart:sky' as sky;
11 13
12 abstract class Scrollable extends Component { 14 abstract class Scrollable extends Component {
13 ScrollCurve scrollCurve; 15 ScrollCurve scrollCurve;
14 double get scrollOffset => _scrollOffset; 16 double get scrollOffset => _scrollOffset;
15 17
16 double _scrollOffset = 0.0; 18 double _scrollOffset = 0.0;
17 FlingCurve _flingCurve; 19 FlingCurve _flingCurve;
18 int _flingAnimationId; 20 int _flingAnimationId;
19 AnimationGenerator _scrollAnimation; 21 Simulation _simulation;
20 22
21 Scrollable({Object key, this.scrollCurve}) : super(key: key) { 23 Scrollable({Object key, this.scrollCurve}) : super(key: key) {
22 events.listen('pointerdown', _handlePointerDown); 24 events.listen('pointerdown', _handlePointerDown);
23 events.listen('pointerup', _handlePointerUpOrCancel); 25 events.listen('pointerup', _handlePointerUpOrCancel);
24 events.listen('pointercancel', _handlePointerUpOrCancel); 26 events.listen('pointercancel', _handlePointerUpOrCancel);
25 events.listen('gestureflingstart', _handleFlingStart); 27 events.listen('gestureflingstart', _handleFlingStart);
26 events.listen('gestureflingcancel', _handleFlingCancel); 28 events.listen('gestureflingcancel', _handleFlingCancel);
27 events.listen('gesturescrollupdate', _handleScrollUpdate); 29 events.listen('gesturescrollupdate', _handleScrollUpdate);
28 events.listen('wheel', _handleWheel); 30 events.listen('wheel', _handleWheel);
29 } 31 }
30 32
31 void didUnmount() { 33 void didUnmount() {
32 super.didUnmount(); 34 super.didUnmount();
33 _stopFling(); 35 _stopFling();
34 _stopScrollAnimation(); 36 _stopSimulation();
35 } 37 }
36 38
37 bool scrollBy(double scrollDelta) { 39 bool scrollBy(double scrollDelta) {
38 var newScrollOffset = scrollCurve.apply(_scrollOffset, scrollDelta); 40 var newScrollOffset = scrollCurve.apply(_scrollOffset, scrollDelta);
39 if (newScrollOffset == _scrollOffset) 41 if (newScrollOffset == _scrollOffset)
40 return false; 42 return false;
41 setState(() { 43 setState(() {
42 _scrollOffset = newScrollOffset; 44 _scrollOffset = newScrollOffset;
43 }); 45 });
44 return true; 46 return true;
45 } 47 }
46 48
47 void animateScrollTo(double targetScrollOffset, {
48 double initialDelay: 0.0,
49 double duration: 0.0,
50 Curve curve: linear}) {
51 _stopScrollAnimation();
52 _scrollAnimation = new AnimationGenerator(
53 duration: duration,
54 begin: _scrollOffset,
55 end: targetScrollOffset,
56 initialDelay: initialDelay,
57 curve: curve);
58 _scrollAnimation.onTick.listen((newScrollOffset) {
59 if (!scrollBy(newScrollOffset - _scrollOffset))
60 _stopScrollAnimation();
61 }, onDone: () {
62 _scrollAnimation = null;
63 });
64 }
65
66 void _scheduleFlingUpdate() { 49 void _scheduleFlingUpdate() {
67 _flingAnimationId = sky.window.requestAnimationFrame(_updateFling); 50 _flingAnimationId = sky.window.requestAnimationFrame(_updateFling);
68 } 51 }
69 52
70 void _stopFling() { 53 void _stopFling() {
71 if (_flingAnimationId == null) 54 if (_flingAnimationId == null)
72 return; 55 return;
73 sky.window.cancelAnimationFrame(_flingAnimationId); 56 sky.window.cancelAnimationFrame(_flingAnimationId);
74 _flingCurve = null; 57 _flingCurve = null;
75 _flingAnimationId = null; 58 _flingAnimationId = null;
76 } 59 }
77 60
78 void _stopScrollAnimation() { 61 void _stopSimulation() {
79 if (_scrollAnimation == null) 62 if (_simulation == null)
80 return; 63 return;
81 _scrollAnimation.cancel(); 64 _simulation.cancel();
82 _scrollAnimation = null; 65 _simulation = null;
83 } 66 }
84 67
85 void _updateFling(double timeStamp) { 68 void _updateFling(double timeStamp) {
86 double scrollDelta = _flingCurve.update(timeStamp); 69 double scrollDelta = _flingCurve.update(timeStamp);
87 if (!scrollBy(scrollDelta)) 70 if (!scrollBy(scrollDelta))
88 return _settle(); 71 return _settle();
89 _scheduleFlingUpdate(); 72 _scheduleFlingUpdate();
90 } 73 }
91 74
92 void _settle() { 75 void _settle() {
93 _stopFling(); 76 _stopFling();
94 if (_scrollOffset < 0.0) 77 Particle particle = new Particle(position: scrollOffset);
95 animateScrollTo(0.0, duration: 200.0, curve: easeOut); 78 _simulation = scrollCurve.release(particle);
79 if (_simulation == null)
80 return;
81 _simulation.onTick.listen((_) {
82 setState(() {
83 _scrollOffset = particle.position;
84 });
85 });
96 } 86 }
97 87
98 void _handlePointerDown(_) { 88 void _handlePointerDown(_) {
99 _stopFling(); 89 _stopFling();
100 _stopScrollAnimation(); 90 _stopSimulation();
101 } 91 }
102 92
103 void _handlePointerUpOrCancel(_) { 93 void _handlePointerUpOrCancel(_) {
104 if (_flingCurve == null) 94 if (_flingCurve == null)
105 _settle(); 95 _settle();
106 } 96 }
107 97
108 void _handleScrollUpdate(sky.GestureEvent event) { 98 void _handleScrollUpdate(sky.GestureEvent event) {
109 scrollBy(-event.dy); 99 scrollBy(-event.dy);
110 } 100 }
111 101
112 void _handleFlingStart(sky.GestureEvent event) { 102 void _handleFlingStart(sky.GestureEvent event) {
113 _stopScrollAnimation(); 103 _stopSimulation();
114 _flingCurve = new FlingCurve(-event.velocityY, event.timeStamp); 104 _flingCurve = new FlingCurve(-event.velocityY, event.timeStamp);
115 _scheduleFlingUpdate(); 105 _scheduleFlingUpdate();
116 } 106 }
117 107
118 void _handleFlingCancel(sky.GestureEvent event) { 108 void _handleFlingCancel(sky.GestureEvent event) {
119 _settle(); 109 _settle();
120 } 110 }
121 111
122 void _handleWheel(sky.WheelEvent event) { 112 void _handleWheel(sky.WheelEvent event) {
123 scrollBy(-event.offsetY); 113 scrollBy(-event.offsetY);
124 } 114 }
125 } 115 }
OLDNEW
« no previous file with comments | « sky/framework/animation/simulation.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698