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

Side by Side Diff: sky/sdk/lib/widgets/dismissable.dart

Issue 1237713002: Dismissable component (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 5 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 import 'dart:sky' as sky;
6
7 import 'package:vector_math/vector_math.dart';
8 import 'package:sky/animation/animation_performance.dart';
9 import 'package:sky/widgets/animation_builder.dart';
10 import 'package:sky/widgets/basic.dart';
11 import 'package:sky/widgets/widget.dart';
12
13 const int _kCardDismissFadeoutMS = 300;
14 const double _kMinFlingVelocity = 700.0;
15 const double _kMinFlingVelocityDelta = 400.0;
16 const double _kDismissCardThreshold = 0.6;
17
18 typedef void DismissedCallback();
19
20 class Dismissable extends StatefulComponent {
abarth-chromium 2015/07/13 19:20:17 Don't we want to subclass AnimatedComponent?
hansmuller 2015/07/13 19:34:38 I hadn't noticed that. Yes.
21
22 Dismissable({
23 String key,
24 this.child,
25 this.onDismissed
26 // TODO(hansmuller): direction
27 }) : super(key: key);
28
29 Widget child;
30 DismissedCallback onDismissed;
31
32 AnimationBuilder _transform;
33 AnimationPerformance _performance;
34 double _width;
35 double _dragX = 0.0;
36 bool _dragUnderway = false;
37
38 void initState() {
39 _transform = new AnimationBuilder()
40 ..position = new AnimatedType<Point>(Point.origin)
41 ..opacity = new AnimatedType<double>(1.0, end: 0.0);
42
43 _performance = _transform.createPerformance(
44 [_transform.position, _transform.opacity],
45 duration: new Duration(milliseconds: _kCardDismissFadeoutMS));
46 _performance.addListener(_handleAnimationProgressChanged);
abarth-chromium 2015/07/13 19:20:16 watchPerformance(_performance) That handles addin
hansmuller 2015/07/13 19:34:38 Done.
47 }
48
49 void syncFields(Dismissable source) {
50 child = source.child;
51 onDismissed = source.onDismissed;
52 }
53
54 Point get _activeCardDragEndPoint {
55 assert(_width != null);
56 return new Point(_dragX.sign * _width * _kDismissCardThreshold, 0.0);
57 }
58
59 bool get _isActive {
60 return _width != null && (_dragUnderway || _performance.isAnimating);
61 }
62
63 void _maybeCallOnDismissed() {
64 if (onDismissed != null)
65 onDismissed();
66 }
67
68 void _handleAnimationProgressChanged() {
69 setState(() {
70 if (_performance.isCompleted && !_dragUnderway)
71 _maybeCallOnDismissed();
72 });
73 }
74
75 void _handleSizeChanged(Size newSize) {
76 _width = newSize.width;
77 _transform.position.end = _activeCardDragEndPoint;
78 }
79
80 void _handlePointerDown(sky.PointerEvent event) {
81 setState(() {
82 _dragUnderway = true;
83 _dragX = 0.0;
84 _performance.progress = 0.0;
85 });
86 }
87
88 void _handlePointerMove(sky.PointerEvent event) {
89 if (!_isActive)
90 return;
91
92 double oldDragX = _dragX;
93 _dragX += event.dx;
94 setState(() {
95 if (!_performance.isAnimating) {
96 if (oldDragX.sign != _dragX.sign)
97 _transform.position.end = _activeCardDragEndPoint;
98 _performance.progress = _dragX.abs() / (_width * _kDismissCardThreshold) ;
99 }
100 });
101 }
102
103 void _handlePointerUpOrCancel(_) {
104 if (!_isActive)
105 return;
106
107 setState(() {
108 _dragUnderway = false;
109 if (_performance.isCompleted)
110 _maybeCallOnDismissed();
111 else if (!_performance.isAnimating)
112 _performance.progress = 0.0;
113 });
114 }
115
116 bool _isHorizontalFlingGesture(sky.GestureEvent event) {
117 double vx = event.velocityX.abs();
118 double vy = event.velocityY.abs();
119 return vx - vy > _kMinFlingVelocityDelta && vx > _kMinFlingVelocity;
120 }
121
122 void _handleFlingStart(sky.GestureEvent event) {
123 if (!_isActive)
124 return;
125
126 if (_isHorizontalFlingGesture(event)) {
127 _dragUnderway = false;
128 double distance = 1.0 - _performance.progress;
129 if (distance > 0.0) {
130 double duration = _kCardDismissFadeoutMS * 1000.0 * distance / event.vel ocityX.abs();
131 _dragX = event.velocityX.sign;
132 _performance.timeline.animateTo(1.0, duration: duration);
133 }
134 }
135 }
136
137 Widget build() {
138 // TODO(hansmuller) The code below changes the widget tree when
139 // the user starts dragging. Currently this causes Sky to drop the
140 // rest of the pointer gesture, see https://github.com/domokit/mojo/issues/3 12.
141 // As a workaround, always create the Transform and Opacity nodes.
142 Widget transformedChild = child;
143 if (_isActive) {
144 transformedChild = _transform.build(transformedChild);
145 } else {
146 transformedChild = new Transform(child: transformedChild, transform: new M atrix4.identity());
147 transformedChild = new Opacity(child: transformedChild, opacity: 1.0);
148 }
149
150 return new Listener(
151 onPointerDown: _handlePointerDown,
152 onPointerMove: _handlePointerMove,
153 onPointerUp: _handlePointerUpOrCancel,
154 onPointerCancel: _handlePointerUpOrCancel,
155 onGestureFlingStart: _handleFlingStart,
156 child: new SizeObserver(
157 child: transformedChild,
158 callback: _handleSizeChanged
159 )
160 );
161 }
162 }
OLDNEW
« sky/sdk/example/widgets/card_collection.dart ('K') | « sky/sdk/example/widgets/card_collection.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698