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

Side by Side Diff: sky/sdk/example/widgets/card_collection.dart

Issue 1231603003: Card "swipe-away" dismiss (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
« no previous file with comments | « no previous file | 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
(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/base/lerp.dart';
10 import 'package:sky/painting/text_style.dart';
11 import 'package:sky/theme/colors.dart';
12 import 'package:sky/widgets/basic.dart';
13 import 'package:sky/widgets/card.dart';
14 import 'package:sky/widgets/scaffold.dart';
15 import 'package:sky/widgets/theme.dart';
16 import 'package:sky/widgets/tool_bar.dart';
17 import 'package:sky/widgets/widget.dart';
18
19
20 const int _kCardDismissFadeoutMS = 300;
21 const double _kMinCardFlingVelocity = 0.4;
22 const double _kDismissCardThreshold = 0.70;
23
24 class CardCollectionApp extends App {
25
26 final TextStyle cardLabelStyle =
27 new TextStyle(color: White, fontSize: 18.0, fontWeight: bold);
28
29 CardCollectionApp() {
30 _activeCardAnimation = new AnimationPerformance()
31 ..variable = new AnimatedType(0.0, 1.0)
32 ..duration = new Duration(milliseconds: _kCardDismissFadeoutMS);
33 _activeCardAnimation.timeline.onValueChanged.listen(_handleAnimationProgress Changed);
34 }
35
36 int _activeCardIndex = -1;
37 double _activeCardAnchorX;
38 AnimationPerformance _activeCardAnimation;
39 double _activeCardWidth;
40 bool _activeCardDragUnderway = false;
41 Set<int> _dismissedCardIndices = new Set<int>();
42
43 double get _activeCardOpacity => 1.0 - _activeCardAnimation.progress;
44
45 double get _activeCardOffset {
46 return _activeCardAnimation.progress * _activeCardWidth * _kDismissCardThres hold;
47 }
48
49 void _handleAnimationProgressChanged(_) {
50 setState(() {
51 if (_activeCardAnimation.isCompleted && !_activeCardDragUnderway)
Matt Perry 2015/07/08 22:21:59 would this be simpler if AnimationPerformance supp
hansmuller 2015/07/08 23:07:15 I'm not sure. I'd still need to add a callback wit
52 _dismissedCardIndices.add(_activeCardIndex);
53 });
54 }
55
56 void _handleSizeChanged(Size newSize) {
57 _activeCardWidth = newSize.width;
58 }
59
60 void _handlePointerDown(sky.PointerEvent event, int cardIndex) {
61 setState(() {
62 _activeCardIndex = cardIndex;
63 _activeCardDragUnderway = true;
64 _activeCardAnchorX = null;
65 _activeCardAnimation.progress = 0.0;
66 });
67 }
68
69 void _handlePointerMove(sky.PointerEvent event) {
70 if (_activeCardWidth == null || _activeCardIndex < 0)
71 return;
72
73 if (_activeCardAnchorX == null)
74 _activeCardAnchorX = event.x - event.dx;
abarth-chromium 2015/07/08 21:12:02 Unfortunately, the dx property gives you the delta
hansmuller 2015/07/08 21:22:50 I assumed that, in this case, the last event was t
75
76 setState(() {
77 double eventOffsetX = event.x - _activeCardAnchorX;
78 if (!_activeCardAnimation.isAnimating)
79 _activeCardAnimation.progress = eventOffsetX / (_activeCardWidth * _kDis missCardThreshold);
80 });
81 }
82
83 void _handlePointerUpOrCancel(_) {
84 if (_activeCardWidth == null || _activeCardIndex < 0)
85 return;
86
87 setState(() {
88 _activeCardDragUnderway = false;
89 if (_activeCardAnimation.isCompleted)
90 _dismissedCardIndices.add(_activeCardIndex);
91 else if (!_activeCardAnimation.isAnimating)
92 _activeCardAnimation.progress = 0.0;
93 });
94 }
95
96 void _handleFlingStart(sky.GestureEvent event) {
97 if (_activeCardWidth == null || _activeCardIndex < 0)
98 return;
99
100 _activeCardDragUnderway = false;
101 double velocityX = event.velocityX / 1000;
102 if (velocityX.abs() >= _kMinCardFlingVelocity)
103 _activeCardAnimation.fling(velocity: velocityX / _activeCardWidth);
104 }
105
106 Widget _buildCard(int index, Color color) {
107 Widget label = new Center(child: new Text("Item ${index}", style: cardLabelS tyle));
108 Widget card = new Card(
109 child: new Padding(child: label, padding: const EdgeDims.all(8.0)),
110 color: color
111 );
112
113 if (index == _activeCardIndex && _activeCardOffset > 0.0) {
114 Matrix4 transform = new Matrix4.identity();
Matt Perry 2015/07/08 22:21:59 This'll get a little nicer once I check in my Anim
115 transform.translate(_activeCardOffset, 0.0);
116 card = new Transform(child: card, transform: transform);
117 if (_activeCardAnimation != null)
118 card = new Opacity(child: card, opacity: _activeCardOpacity);
119 }
120
121 return new Listener(
122 child: card,
123 onPointerDown: (event) { _handlePointerDown(event, index); }
124 );
125 }
126
127 Widget _buildCardCollection(List<double> heights) {
128 List<Widget> items = <Widget>[];
129 for(int index = 0; index < heights.length; index++) {
130 if (_dismissedCardIndices.contains(index))
131 continue;
132 Color color = lerpColor(Red[500], Blue[500], index / heights.length);
133 items.add(new Container(
134 child: _buildCard(index, color),
135 height: heights[index]
136 ));
137 }
138
139 Widget collection = new Container(
140 child: new SizeObserver(child: new Block(items), callback: _handleSizeChan ged),
141 padding: const EdgeDims.symmetric(vertical: 12.0, horizontal: 8.0),
142 decoration: new BoxDecoration(backgroundColor: Theme.of(this).primarySwatc h[50])
143 );
144
145 return new Listener(
146 child: collection,
147 onPointerMove: _handlePointerMove,
148 onPointerUp: _handlePointerUpOrCancel,
149 onPointerCancel: _handlePointerUpOrCancel,
150 onGestureFlingStart: _handleFlingStart
151 );
152 }
153
154 Widget build() {
155 return new Scaffold(
156 toolbar: new ToolBar(center: new Text('Swipe Away')),
157 body: _buildCardCollection(
158 [48.0, 64.0, 82.0, 46.0, 60.0, 55.0, 84.0, 96.0, 50.0,
159 48.0, 64.0, 82.0, 46.0, 60.0, 55.0, 84.0, 96.0, 50.0])
160 );
161 }
162 }
163
164 void main() {
165 runApp(new CardCollectionApp());
166 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698