| 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'; | |
| 8 import 'package:sky/animation/animation_performance.dart'; | 7 import 'package:sky/animation/animation_performance.dart'; |
| 9 import 'package:sky/widgets/animation_builder.dart'; | |
| 10 import 'package:sky/widgets/animated_component.dart'; | 8 import 'package:sky/widgets/animated_component.dart'; |
| 11 import 'package:sky/widgets/basic.dart'; | 9 import 'package:sky/widgets/basic.dart'; |
| 12 import 'package:sky/widgets/widget.dart'; | 10 import 'package:sky/widgets/widget.dart'; |
| 11 import 'package:vector_math/vector_math.dart'; |
| 13 | 12 |
| 14 const int _kCardDismissFadeoutMS = 300; | 13 const Duration _kCardDismissFadeout = const Duration(milliseconds: 300); |
| 15 const double _kMinFlingVelocity = 700.0; | 14 const double _kMinFlingVelocity = 700.0; |
| 16 const double _kMinFlingVelocityDelta = 400.0; | 15 const double _kMinFlingVelocityDelta = 400.0; |
| 17 const double _kDismissCardThreshold = 0.6; | 16 const double _kDismissCardThreshold = 0.6; |
| 18 | 17 |
| 19 typedef void DismissedCallback(); | 18 typedef void DismissedCallback(); |
| 20 | 19 |
| 21 class Dismissable extends AnimatedComponent { | 20 class Dismissable extends AnimatedComponent { |
| 22 | 21 |
| 23 Dismissable({ | 22 Dismissable({ |
| 24 String key, | 23 String key, |
| 25 this.child, | 24 this.child, |
| 26 this.onDismissed | 25 this.onDismissed |
| 27 // TODO(hansmuller): direction | 26 // TODO(hansmuller): direction |
| 28 }) : super(key: key); | 27 }) : super(key: key); |
| 29 | 28 |
| 30 Widget child; | 29 Widget child; |
| 31 DismissedCallback onDismissed; | 30 DismissedCallback onDismissed; |
| 32 | 31 |
| 33 AnimationBuilder _transform; | 32 AnimatedType<Point> _position; |
| 33 AnimatedType<double> _opacity; |
| 34 AnimationPerformance _performance; | 34 AnimationPerformance _performance; |
| 35 |
| 35 double _width; | 36 double _width; |
| 36 double _dragX = 0.0; | 37 double _dragX = 0.0; |
| 37 bool _dragUnderway = false; | 38 bool _dragUnderway = false; |
| 38 | 39 |
| 39 void initState() { | 40 void initState() { |
| 40 _transform = new AnimationBuilder() | 41 _position = new AnimatedType<Point>(Point.origin); |
| 41 ..position = new AnimatedType<Point>(Point.origin) | 42 _opacity = new AnimatedType<double>(1.0, end: 0.0); |
| 42 ..opacity = new AnimatedType<double>(1.0, end: 0.0); | 43 _performance = new AnimationPerformance() |
| 43 | 44 ..duration = _kCardDismissFadeout |
| 44 _performance = _transform.createPerformance( | 45 ..variable = new AnimatedList([_position, _opacity]) |
| 45 [_transform.position, _transform.opacity], | 46 ..addListener(_handleAnimationProgressChanged); |
| 46 duration: new Duration(milliseconds: _kCardDismissFadeoutMS)); | |
| 47 _performance.addListener(_handleAnimationProgressChanged); | |
| 48 watch(_performance); | 47 watch(_performance); |
| 49 } | 48 } |
| 50 | 49 |
| 51 void syncFields(Dismissable source) { | 50 void syncFields(Dismissable source) { |
| 52 child = source.child; | 51 child = source.child; |
| 53 onDismissed = source.onDismissed; | 52 onDismissed = source.onDismissed; |
| 54 super.syncFields(source); | 53 super.syncFields(source); |
| 55 } | 54 } |
| 56 | 55 |
| 57 Point get _activeCardDragEndPoint { | 56 Point get _activeCardDragEndPoint { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 70 | 69 |
| 71 void _handleAnimationProgressChanged() { | 70 void _handleAnimationProgressChanged() { |
| 72 setState(() { | 71 setState(() { |
| 73 if (_performance.isCompleted && !_dragUnderway) | 72 if (_performance.isCompleted && !_dragUnderway) |
| 74 _maybeCallOnDismissed(); | 73 _maybeCallOnDismissed(); |
| 75 }); | 74 }); |
| 76 } | 75 } |
| 77 | 76 |
| 78 void _handleSizeChanged(Size newSize) { | 77 void _handleSizeChanged(Size newSize) { |
| 79 _width = newSize.width; | 78 _width = newSize.width; |
| 80 _transform.position.end = _activeCardDragEndPoint; | 79 _position.end = _activeCardDragEndPoint; |
| 81 } | 80 } |
| 82 | 81 |
| 83 void _handlePointerDown(sky.PointerEvent event) { | 82 void _handlePointerDown(sky.PointerEvent event) { |
| 84 setState(() { | 83 setState(() { |
| 85 _dragUnderway = true; | 84 _dragUnderway = true; |
| 86 _dragX = 0.0; | 85 _dragX = 0.0; |
| 87 _performance.progress = 0.0; | 86 _performance.progress = 0.0; |
| 88 }); | 87 }); |
| 89 } | 88 } |
| 90 | 89 |
| 91 void _handlePointerMove(sky.PointerEvent event) { | 90 void _handlePointerMove(sky.PointerEvent event) { |
| 92 if (!_isActive) | 91 if (!_isActive) |
| 93 return; | 92 return; |
| 94 | 93 |
| 95 double oldDragX = _dragX; | 94 double oldDragX = _dragX; |
| 96 _dragX += event.dx; | 95 _dragX += event.dx; |
| 97 setState(() { | 96 setState(() { |
| 98 if (!_performance.isAnimating) { | 97 if (!_performance.isAnimating) { |
| 99 if (oldDragX.sign != _dragX.sign) | 98 if (oldDragX.sign != _dragX.sign) |
| 100 _transform.position.end = _activeCardDragEndPoint; | 99 _position.end = _activeCardDragEndPoint; |
| 101 _performance.progress = _dragX.abs() / (_width * _kDismissCardThreshold)
; | 100 _performance.progress = _dragX.abs() / (_width * _kDismissCardThreshold)
; |
| 102 } | 101 } |
| 103 }); | 102 }); |
| 104 } | 103 } |
| 105 | 104 |
| 106 void _handlePointerUpOrCancel(_) { | 105 void _handlePointerUpOrCancel(_) { |
| 107 if (!_isActive) | 106 if (!_isActive) |
| 108 return; | 107 return; |
| 109 | 108 |
| 110 setState(() { | 109 setState(() { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 123 } | 122 } |
| 124 | 123 |
| 125 void _handleFlingStart(sky.GestureEvent event) { | 124 void _handleFlingStart(sky.GestureEvent event) { |
| 126 if (!_isActive) | 125 if (!_isActive) |
| 127 return; | 126 return; |
| 128 | 127 |
| 129 if (_isHorizontalFlingGesture(event)) { | 128 if (_isHorizontalFlingGesture(event)) { |
| 130 _dragUnderway = false; | 129 _dragUnderway = false; |
| 131 double distance = 1.0 - _performance.progress; | 130 double distance = 1.0 - _performance.progress; |
| 132 if (distance > 0.0) { | 131 if (distance > 0.0) { |
| 133 double duration = _kCardDismissFadeoutMS * 1000.0 * distance / event.vel
ocityX.abs(); | 132 double duration = _kCardDismissFadeout.inSeconds * distance / event.velo
cityX.abs(); |
| 134 _dragX = event.velocityX.sign; | 133 _dragX = event.velocityX.sign; |
| 135 _performance.timeline.animateTo(1.0, duration: duration); | 134 _performance.timeline.animateTo(1.0, duration: duration); |
| 136 } | 135 } |
| 137 } | 136 } |
| 138 } | 137 } |
| 139 | 138 |
| 140 Widget build() { | 139 Widget build() { |
| 141 // TODO(hansmuller) The code below changes the widget tree when | 140 Matrix4 transform = new Matrix4.identity(); |
| 142 // the user starts dragging. Currently this causes Sky to drop the | 141 transform.translate(_position.value.x, _position.value.y); |
| 143 // rest of the pointer gesture, see https://github.com/domokit/mojo/issues/3
12. | |
| 144 // As a workaround, always create the Transform and Opacity nodes. | |
| 145 Widget transformedChild = child; | |
| 146 if (_isActive) { | |
| 147 transformedChild = _transform.build(transformedChild); | |
| 148 } else { | |
| 149 transformedChild = new Transform(child: transformedChild, transform: new M
atrix4.identity()); | |
| 150 transformedChild = new Opacity(child: transformedChild, opacity: 1.0); | |
| 151 } | |
| 152 | |
| 153 return new Listener( | 142 return new Listener( |
| 154 onPointerDown: _handlePointerDown, | 143 onPointerDown: _handlePointerDown, |
| 155 onPointerMove: _handlePointerMove, | 144 onPointerMove: _handlePointerMove, |
| 156 onPointerUp: _handlePointerUpOrCancel, | 145 onPointerUp: _handlePointerUpOrCancel, |
| 157 onPointerCancel: _handlePointerUpOrCancel, | 146 onPointerCancel: _handlePointerUpOrCancel, |
| 158 onGestureFlingStart: _handleFlingStart, | 147 onGestureFlingStart: _handleFlingStart, |
| 159 child: new SizeObserver( | 148 child: new SizeObserver( |
| 160 child: transformedChild, | 149 callback: _handleSizeChanged, |
| 161 callback: _handleSizeChanged | 150 child: new Opacity( |
| 151 opacity: _opacity.value, |
| 152 child: new Transform( |
| 153 transform: transform, |
| 154 child: child |
| 155 ) |
| 156 ) |
| 162 ) | 157 ) |
| 163 ); | 158 ); |
| 164 } | 159 } |
| 165 } | 160 } |
| OLD | NEW |