Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 'dart:sky' as sky; | 5 import 'dart:sky' as sky; |
| 6 | 6 |
| 7 import 'package:vector_math/vector_math.dart'; | 7 import 'package:vector_math/vector_math.dart'; |
| 8 import 'package:sky/animation/animation_performance.dart'; | 8 import 'package:sky/animation/animation_performance.dart'; |
| 9 import 'package:sky/base/lerp.dart'; | 9 import 'package:sky/base/lerp.dart'; |
| 10 import 'package:sky/painting/text_style.dart'; | 10 import 'package:sky/painting/text_style.dart'; |
| 11 import 'package:sky/theme/colors.dart'; | 11 import 'package:sky/theme/colors.dart'; |
| 12 import 'package:sky/widgets/animated_container.dart'; | |
| 12 import 'package:sky/widgets/basic.dart'; | 13 import 'package:sky/widgets/basic.dart'; |
| 13 import 'package:sky/widgets/card.dart'; | 14 import 'package:sky/widgets/card.dart'; |
| 14 import 'package:sky/widgets/scaffold.dart'; | 15 import 'package:sky/widgets/scaffold.dart'; |
| 15 import 'package:sky/widgets/theme.dart'; | 16 import 'package:sky/widgets/theme.dart'; |
| 16 import 'package:sky/widgets/tool_bar.dart'; | 17 import 'package:sky/widgets/tool_bar.dart'; |
| 17 import 'package:sky/widgets/widget.dart'; | 18 import 'package:sky/widgets/widget.dart'; |
| 18 | 19 |
| 19 | 20 |
| 20 const int _kCardDismissFadeoutMS = 300; | 21 const int _kCardDismissFadeoutMS = 300; |
| 21 const double _kMinCardFlingVelocity = 0.4; | 22 const double _kMinCardFlingVelocity = 0.4; |
| 22 const double _kDismissCardThreshold = 0.70; | 23 const double _kDismissCardThreshold = 0.70; |
| 23 | 24 |
| 24 class CardCollectionApp extends App { | 25 class CardCollectionApp extends App { |
| 25 | 26 |
| 26 final TextStyle cardLabelStyle = | 27 final TextStyle cardLabelStyle = |
| 27 new TextStyle(color: White, fontSize: 18.0, fontWeight: bold); | 28 new TextStyle(color: White, fontSize: 18.0, fontWeight: bold); |
| 28 | 29 |
| 29 CardCollectionApp() { | 30 CardCollectionApp() { |
| 30 _activeCardAnimation = new AnimationPerformance() | 31 _activeCardTransform = new AnimatedContainer() |
| 31 ..variable = new AnimatedType(0.0, 1.0) | 32 ..position = new AnimatedType<Point>(Point.origin) |
| 32 ..duration = new Duration(milliseconds: _kCardDismissFadeoutMS) | 33 ..opacity = new AnimatedType<double>(1.0, end: 0.0); |
| 33 ..addListener(_handleAnimationProgressChanged); | 34 _activeCardAnimation = _activeCardTransform.createPerformance( |
| 35 [_activeCardTransform.position, _activeCardTransform.opacity], | |
| 36 duration: new Duration(milliseconds: _kCardDismissFadeoutMS)); | |
| 37 _activeCardAnimation.addListener(_handleAnimationProgressChanged); | |
| 34 } | 38 } |
| 35 | 39 |
| 36 int _activeCardIndex = -1; | 40 int _activeCardIndex = -1; |
| 41 AnimatedContainer _activeCardTransform; | |
| 37 AnimationPerformance _activeCardAnimation; | 42 AnimationPerformance _activeCardAnimation; |
| 38 double _activeCardWidth; | 43 double _activeCardWidth; |
| 39 double _activeCardDragX = 0.0; | 44 double _activeCardDragX = 0.0; |
| 40 bool _activeCardDragUnderway = false; | 45 bool _activeCardDragUnderway = false; |
| 41 Set<int> _dismissedCardIndices = new Set<int>(); | 46 Set<int> _dismissedCardIndices = new Set<int>(); |
| 42 | 47 |
| 43 double get _activeCardOpacity => 1.0 - _activeCardAnimation.progress; | 48 Point get _activeCardDragEndPoint { |
| 44 | 49 return new Point(_activeCardDragX.sign * _activeCardWidth * _kDismissCardThr eshold, 0.0); |
| 45 double get _activeCardOffset { | |
| 46 return _activeCardAnimation.progress * _activeCardDragX.sign * _activeCardWi dth * _kDismissCardThreshold; | |
| 47 } | 50 } |
| 48 | 51 |
| 49 void _handleAnimationProgressChanged() { | 52 void _handleAnimationProgressChanged() { |
| 50 setState(() { | 53 setState(() { |
| 51 if (_activeCardAnimation.isCompleted && !_activeCardDragUnderway) | 54 if (_activeCardAnimation.isCompleted && !_activeCardDragUnderway) |
| 52 _dismissedCardIndices.add(_activeCardIndex); | 55 _dismissedCardIndices.add(_activeCardIndex); |
| 53 }); | 56 }); |
| 54 } | 57 } |
| 55 | 58 |
| 56 void _handleSizeChanged(Size newSize) { | 59 void _handleSizeChanged(Size newSize) { |
| 57 _activeCardWidth = newSize.width; | 60 _activeCardWidth = newSize.width; |
| 61 _activeCardTransform.position.end = _activeCardDragEndPoint; | |
| 58 } | 62 } |
| 59 | 63 |
| 60 void _handlePointerDown(sky.PointerEvent event, int cardIndex) { | 64 void _handlePointerDown(sky.PointerEvent event, int cardIndex) { |
| 61 setState(() { | 65 setState(() { |
| 62 _activeCardIndex = cardIndex; | 66 _activeCardIndex = cardIndex; |
| 63 _activeCardDragUnderway = true; | 67 _activeCardDragUnderway = true; |
| 64 _activeCardDragX = 0.0; | 68 _activeCardDragX = 0.0; |
| 65 _activeCardAnimation.progress = 0.0; | 69 _activeCardAnimation.progress = 0.0; |
| 66 }); | 70 }); |
| 67 } | 71 } |
| 68 | 72 |
| 69 void _handlePointerMove(sky.PointerEvent event) { | 73 void _handlePointerMove(sky.PointerEvent event) { |
| 70 if (_activeCardWidth == null || _activeCardIndex < 0) | 74 if (_activeCardWidth == null || _activeCardIndex < 0) |
| 71 return; | 75 return; |
| 72 | 76 |
| 77 double oldDragX = _activeCardDragX; | |
| 73 _activeCardDragX += event.dx; | 78 _activeCardDragX += event.dx; |
| 74 setState(() { | 79 setState(() { |
| 75 if (!_activeCardAnimation.isAnimating) | 80 if (!_activeCardAnimation.isAnimating) { |
| 81 if (oldDragX.sign != _activeCardDragX.sign) | |
| 82 _activeCardTransform.position.end = _activeCardDragEndPoint; | |
| 76 _activeCardAnimation.progress = _activeCardDragX.abs() / (_activeCardWid th * _kDismissCardThreshold); | 83 _activeCardAnimation.progress = _activeCardDragX.abs() / (_activeCardWid th * _kDismissCardThreshold); |
| 84 } | |
| 77 }); | 85 }); |
| 78 } | 86 } |
| 79 | 87 |
| 80 void _handlePointerUpOrCancel(_) { | 88 void _handlePointerUpOrCancel(_) { |
| 81 if (_activeCardWidth == null || _activeCardIndex < 0) | 89 if (_activeCardWidth == null || _activeCardIndex < 0) |
| 82 return; | 90 return; |
| 83 | 91 |
| 84 setState(() { | 92 setState(() { |
| 85 _activeCardDragUnderway = false; | 93 _activeCardDragUnderway = false; |
| 86 if (_activeCardAnimation.isCompleted) | 94 if (_activeCardAnimation.isCompleted) |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 110 Widget label = new Center(child: new Text("Item ${index}", style: cardLabelS tyle)); | 118 Widget label = new Center(child: new Text("Item ${index}", style: cardLabelS tyle)); |
| 111 Widget card = new Card( | 119 Widget card = new Card( |
| 112 child: new Padding(child: label, padding: const EdgeDims.all(8.0)), | 120 child: new Padding(child: label, padding: const EdgeDims.all(8.0)), |
| 113 color: color | 121 color: color |
| 114 ); | 122 ); |
| 115 | 123 |
| 116 // TODO(hansmuller) The code below changes the card's widget tree when | 124 // TODO(hansmuller) The code below changes the card's widget tree when |
| 117 // the user starts dragging it. Currently this causes Sky to drop the | 125 // the user starts dragging it. Currently this causes Sky to drop the |
| 118 // rest of the pointer gesture, see https://github.com/domokit/mojo/issues/3 12. | 126 // rest of the pointer gesture, see https://github.com/domokit/mojo/issues/3 12. |
| 119 // As a workaround, always create the Transform and Opacity nodes. | 127 // As a workaround, always create the Transform and Opacity nodes. |
| 120 /* | |
| 121 if (index == _activeCardIndex) { | 128 if (index == _activeCardIndex) { |
| 122 Matrix4 transform = new Matrix4.identity(); | 129 card = _activeCardTransform.build(card); |
| 123 transform.translate(_activeCardOffset, 0.0); | 130 } else { |
| 124 card = new Transform(child: card, transform: transform); | 131 card = new Transform(child: card, transform: new Matrix4.identity()); |
| 125 if (_activeCardAnimation != null) | 132 card = new Opacity(child: card, opacity: 1.0); |
|
abarth-chromium
2015/07/09 23:20:13
It's lame that we need to do this by hand. Maybe
Matt Perry
2015/07/09 23:25:50
This is just a hacky workaround until https://gith
| |
| 126 card = new Opacity(child: card, opacity: _activeCardOpacity); | |
| 127 } | 133 } |
| 128 */ | |
| 129 Matrix4 transform = new Matrix4.identity(); | |
| 130 double opacity = 1.0; | |
| 131 if (index == _activeCardIndex) { | |
| 132 transform.translate(_activeCardOffset, 0.0); | |
| 133 opacity = _activeCardOpacity; | |
| 134 } | |
| 135 card = new Transform( | |
| 136 child: new Opacity(child: card, opacity: opacity), | |
| 137 transform: transform); | |
| 138 | 134 |
| 139 return new Listener( | 135 return new Listener( |
| 140 child: card, | 136 child: card, |
| 141 onPointerDown: (event) { _handlePointerDown(event, index); }, | 137 onPointerDown: (event) { _handlePointerDown(event, index); }, |
| 142 onPointerMove: _handlePointerMove, | 138 onPointerMove: _handlePointerMove, |
| 143 onPointerUp: _handlePointerUpOrCancel, | 139 onPointerUp: _handlePointerUpOrCancel, |
| 144 onPointerCancel: _handlePointerUpOrCancel, | 140 onPointerCancel: _handlePointerUpOrCancel, |
| 145 onGestureFlingStart: _handleFlingStart | 141 onGestureFlingStart: _handleFlingStart |
| 146 ); | 142 ); |
| 147 } | 143 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 171 body: _buildCardCollection( | 167 body: _buildCardCollection( |
| 172 [48.0, 64.0, 82.0, 46.0, 60.0, 55.0, 84.0, 96.0, 50.0, | 168 [48.0, 64.0, 82.0, 46.0, 60.0, 55.0, 84.0, 96.0, 50.0, |
| 173 48.0, 64.0, 82.0, 46.0, 60.0, 55.0, 84.0, 96.0, 50.0]) | 169 48.0, 64.0, 82.0, 46.0, 60.0, 55.0, 84.0, 96.0, 50.0]) |
| 174 ); | 170 ); |
| 175 } | 171 } |
| 176 } | 172 } |
| 177 | 173 |
| 178 void main() { | 174 void main() { |
| 179 runApp(new CardCollectionApp()); | 175 runApp(new CardCollectionApp()); |
| 180 } | 176 } |
| OLD | NEW |