Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 } | |
| OLD | NEW |