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 '../animation/animated_value.dart'; | 5 import '../animation/animated_value.dart'; |
6 import '../animation/curves.dart'; | 6 import '../animation/curves.dart'; |
7 import '../fn2.dart'; | 7 import '../fn2.dart'; |
8 import '../theme/view_configuration.dart' as config; | 8 import '../theme/view_configuration.dart' as config; |
9 import 'dart:async'; | 9 import 'dart:async'; |
10 import 'dart:math' as math; | 10 import 'dart:math' as math; |
11 | 11 |
12 const double _kSplashConfirmedDuration = 350.0; | 12 const double _kSplashConfirmedDuration = 350.0; |
13 const double _kSplashUnconfirmedDuration = config.kDefaultLongPressTimeout; | 13 const double _kSplashUnconfirmedDuration = config.kDefaultLongPressTimeout; |
14 const double _kSplashAbortDuration = 100.0; | 14 const double _kSplashAbortDuration = 100.0; |
15 const double _kSplashInitialDelay = 0.0; // we could delay initially in case the
user scrolls | 15 const double _kSplashInitialDelay = 0.0; // we could delay initially in case the
user scrolls |
16 | 16 |
17 double _getSplashTargetSize(Rect rect, double x, double y) { | 17 double _getSplashTargetSize(Rect rect, double x, double y) { |
18 return 2.0 * math.max(math.max(x - rect.x, rect.x + rect.width - x), | 18 return 2.0 * math.max(math.max(x - rect.x, rect.x + rect.width - x), |
19 math.max(y - rect.y, rect.y + rect.height - y)); | 19 math.max(y - rect.y, rect.y + rect.height - y)); |
20 } | 20 } |
21 | 21 |
22 class SplashController { | 22 class SplashController { |
| 23 |
| 24 SplashController(Rect rect, double x, double y, |
| 25 { this.pointer, Function onDone }) |
| 26 : _offsetX = x - rect.x, |
| 27 _offsetY = y - rect.y, |
| 28 _targetSize = _getSplashTargetSize(rect, x, y) { |
| 29 |
| 30 _styleStream = _size.onValueChanged.map((p) { |
| 31 if (p == _targetSize) { |
| 32 onDone(); |
| 33 } |
| 34 double size; |
| 35 if (_growing) { |
| 36 size = p; |
| 37 _lastSize = p; |
| 38 } else { |
| 39 size = _lastSize; |
| 40 } |
| 41 return ''' |
| 42 top: ${_offsetY - size/2}px; |
| 43 left: ${_offsetX - size/2}px; |
| 44 width: ${size}px; |
| 45 height: ${size}px; |
| 46 border-radius: ${size}px; |
| 47 opacity: ${1.0 - (p / _targetSize)};'''; |
| 48 }); |
| 49 |
| 50 start(); |
| 51 } |
| 52 |
23 final int pointer; | 53 final int pointer; |
24 Stream<String> get onStyleChanged => _styleStream; | 54 Stream<String> get onStyleChanged => _styleStream; |
25 | 55 |
26 final AnimatedValue _size = new AnimatedValue(0.0); | 56 final AnimatedValue _size = new AnimatedValue(0.0); |
27 double _offsetX; | 57 double _offsetX; |
28 double _offsetY; | 58 double _offsetY; |
29 double _lastSize = 0.0; | 59 double _lastSize = 0.0; |
30 bool _growing = true; | 60 bool _growing = true; |
31 double _targetSize; | 61 double _targetSize; |
32 Stream<String> _styleStream; | 62 Stream<String> _styleStream; |
(...skipping 15 matching lines...) Expand all Loading... |
48 double durationRemaining = _size.remainingTime; | 78 double durationRemaining = _size.remainingTime; |
49 if (durationRemaining <= _kSplashAbortDuration) | 79 if (durationRemaining <= _kSplashAbortDuration) |
50 return; | 80 return; |
51 _size.animateTo(_targetSize, _kSplashAbortDuration, curve: easeOut); | 81 _size.animateTo(_targetSize, _kSplashAbortDuration, curve: easeOut); |
52 } | 82 } |
53 | 83 |
54 void cancel() { | 84 void cancel() { |
55 _size.stop(); | 85 _size.stop(); |
56 } | 86 } |
57 | 87 |
58 SplashController(Rect rect, double x, double y, | |
59 { this.pointer, Function onDone }) | |
60 : _offsetX = x - rect.x, | |
61 _offsetY = y - rect.y, | |
62 _targetSize = _getSplashTargetSize(rect, x, y) { | |
63 | |
64 _styleStream = _size.onValueChanged.map((p) { | |
65 if (p == _targetSize) { | |
66 onDone(); | |
67 } | |
68 double size; | |
69 if (_growing) { | |
70 size = p; | |
71 _lastSize = p; | |
72 } else { | |
73 size = _lastSize; | |
74 } | |
75 return ''' | |
76 top: ${_offsetY - size/2}px; | |
77 left: ${_offsetX - size/2}px; | |
78 width: ${size}px; | |
79 height: ${size}px; | |
80 border-radius: ${size}px; | |
81 opacity: ${1.0 - (p / _targetSize)};'''; | |
82 }); | |
83 | |
84 start(); | |
85 } | |
86 } | 88 } |
87 | 89 |
88 class InkSplash extends Component { | 90 class InkSplash extends Component { |
| 91 |
| 92 InkSplash(Stream<String> onStyleChanged) |
| 93 : onStyleChanged = onStyleChanged, |
| 94 super(stateful: true, key: onStyleChanged.hashCode); |
| 95 |
89 static final Style _clipperStyle = new Style(''' | 96 static final Style _clipperStyle = new Style(''' |
90 position: absolute; | 97 position: absolute; |
91 pointer-events: none; | 98 pointer-events: none; |
92 overflow: hidden; | 99 overflow: hidden; |
93 top: 0; | 100 top: 0; |
94 left: 0; | 101 left: 0; |
95 bottom: 0; | 102 bottom: 0; |
96 right: 0;'''); | 103 right: 0;'''); |
97 | 104 |
98 static final Style _splashStyle = new Style(''' | 105 static final Style _splashStyle = new Style(''' |
99 position: absolute; | 106 position: absolute; |
100 background-color: rgba(0, 0, 0, 0.2);'''); | 107 background-color: rgba(0, 0, 0, 0.2);'''); |
101 | 108 |
102 Stream<String> onStyleChanged; | 109 Stream<String> onStyleChanged; |
103 | 110 |
104 double _offsetX; | 111 double _offsetX; |
105 double _offsetY; | 112 double _offsetY; |
106 String _inlineStyle; | 113 String _inlineStyle; |
107 | 114 |
108 InkSplash(Stream<String> onStyleChanged) | |
109 : onStyleChanged = onStyleChanged, | |
110 super(stateful: true, key: onStyleChanged.hashCode); | |
111 | |
112 bool _listening = false; | 115 bool _listening = false; |
113 | 116 |
114 void _ensureListening() { | 117 void _ensureListening() { |
115 if (_listening) | 118 if (_listening) |
116 return; | 119 return; |
117 | 120 |
118 _listening = true; | 121 _listening = true; |
119 | 122 |
120 onStyleChanged.listen((style) { | 123 onStyleChanged.listen((style) { |
121 setState(() { | 124 setState(() { |
122 _inlineStyle = style; | 125 _inlineStyle = style; |
123 }); | 126 }); |
124 }); | 127 }); |
125 } | 128 } |
126 | 129 |
127 UINode build() { | 130 UINode build() { |
128 _ensureListening(); | 131 _ensureListening(); |
129 | 132 |
130 return new Container( | 133 return new Container( |
131 style: _clipperStyle, | 134 style: _clipperStyle, |
132 children: [ | 135 children: [ |
133 new Container( | 136 new Container( |
134 inlineStyle: _inlineStyle, | 137 inlineStyle: _inlineStyle, |
135 style: _splashStyle | 138 style: _splashStyle |
136 ) | 139 ) |
137 ] | 140 ] |
138 ); | 141 ); |
139 } | 142 } |
| 143 |
140 } | 144 } |
OLD | NEW |