OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. All rights reserved. | 2 * Copyright 2014 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style | 4 * Use of this source code is governed by a BSD-style |
5 * license that can be found in the LICENSE file or at | 5 * license that can be found in the LICENSE file or at |
6 * https://developers.google.com/open-source/licenses/bsd | 6 * https://developers.google.com/open-source/licenses/bsd |
7 */ | 7 */ |
8 part of charted.selection.transition; | 8 part of charted.selection.transition; |
9 | 9 |
10 // handle transitions on an element-basis, so we can cancel if another is | 10 // handle transitions on an element-basis, so we can cancel if another is |
11 // scheduled | 11 // scheduled |
12 Map<Element, int> _transitionMap = {}; | 12 Map<Element, int> _transitionMap = {}; |
13 | 13 |
14 class _TransitionImpl implements Transition { | 14 class _TransitionImpl implements Transition { |
15 SelectionCallback _delay = (d, i, c) => 0; | 15 SelectionCallback _delay = (d, i, c) => 0; |
16 SelectionCallback _duration = | 16 SelectionCallback _duration = (d, i, c) => |
17 (d, i, c) => Transition.defaultDurationMilliseconds; | 17 Transition.defaultDurationMilliseconds; |
18 Selection _selection; | 18 Selection _selection; |
19 Map _attrs = {}; | 19 Map _attrs = {}; |
20 Map _styles = {}; | 20 Map _styles = {}; |
21 Map _attrTweens = {}; | 21 Map _attrTweens = {}; |
22 Map _styleTweens = {}; | 22 Map _styleTweens = {}; |
23 Map<AnimationTimer, Element> _timerMap = {}; | 23 Map<AnimationTimer, Element> _timerMap = {}; |
24 Map<Element, List<Map>> _attrMap = {}; | 24 Map<Element, List<Map>> _attrMap = {}; |
25 Map<Element, int> _durationMap = {}; | 25 Map<Element, int> _durationMap = {}; |
26 bool _interrupted = false; | 26 bool _interrupted = false; |
27 bool _remove = false; | 27 bool _remove = false; |
28 var _timerDelay = 0; | 28 var _timerDelay = 0; |
29 | 29 |
30 _TransitionImpl(this._selection, [num delay = 0]) { | 30 _TransitionImpl(this._selection, [num delay = 0]) { |
31 _transitionNode(delay); | 31 _transitionNode(delay); |
32 _timerDelay = delay; | 32 _timerDelay = delay; |
33 } | 33 } |
34 | 34 |
35 Interpolator ease = clampEasingFn( | 35 Interpolator ease = |
36 Transition.defaultEasingMode(Transition.defaultEasingType)); | 36 clampEasingFn(Transition.defaultEasingMode(Transition.defaultEasingType)); |
37 | 37 |
38 void delay(int millisecond) { | 38 void delay(int millisecond) { |
39 delayWithCallback(toCallback(millisecond)); | 39 delayWithCallback(toCallback(millisecond)); |
40 } | 40 } |
41 | 41 |
42 void delayWithCallback(SelectionCallback fn) { | 42 void delayWithCallback(SelectionCallback fn) { |
43 _delay = fn; | 43 _delay = fn; |
44 } | 44 } |
45 | 45 |
46 void duration(int millisecond) { | 46 void duration(int millisecond) { |
(...skipping 30 matching lines...) Expand all Loading... |
77 _styleTweens[property] = {'callback': tween, 'priority': priority}; | 77 _styleTweens[property] = {'callback': tween, 'priority': priority}; |
78 } | 78 } |
79 | 79 |
80 // Starts a timer that registers all attributes, durations, and delays for the | 80 // Starts a timer that registers all attributes, durations, and delays for the |
81 // transition of the current selection. | 81 // transition of the current selection. |
82 _transitionNode(num delay) { | 82 _transitionNode(num delay) { |
83 new AnimationTimer((elapsed) { | 83 new AnimationTimer((elapsed) { |
84 _selection.each((d, i, c) { | 84 _selection.each((d, i, c) { |
85 var tweenList = []; | 85 var tweenList = []; |
86 _attrs.forEach((key, value) { | 86 _attrs.forEach((key, value) { |
87 tweenList.add(_getAttrInterpolator(c, key, value(d, i, c))); | 87 tweenList.add(_getAttrInterpolator(c, key, value(d, i, c))); |
88 }); | 88 }); |
89 _attrTweens.forEach((key, value) { | 89 _attrTweens.forEach((key, value) { |
90 tweenList.add((t) => c.setAttribute(key, | 90 tweenList.add( |
91 value(d, i, c.getAttribute(key))(t))); | 91 (t) => c.setAttribute(key, value(d, i, c.getAttribute(key))(t))); |
92 }); | 92 }); |
93 _styles.forEach((key, value) { | 93 _styles.forEach((key, value) { |
94 tweenList.add(_getStyleInterpolator(c, key, | 94 tweenList.add(_getStyleInterpolator( |
95 value['callback'](d, i, c), value['priority'])); | 95 c, key, value['callback'](d, i, c), value['priority'])); |
96 }); | 96 }); |
97 _styleTweens.forEach((key, value) { | 97 _styleTweens.forEach((key, value) { |
98 tweenList.add((t) => c.style.setProperty(key, | 98 tweenList.add((t) => c.style.setProperty( |
99 value['callback'](d, i, | 99 key, |
100 c.style.getPropertyValue(key))(t).toString(), value['priority'])); | 100 value['callback'](d, i, c.style.getPropertyValue(key))(t) |
| 101 .toString(), |
| 102 value['priority'])); |
101 }); | 103 }); |
102 | 104 |
103 _attrMap[c] = tweenList; | 105 _attrMap[c] = tweenList; |
104 _durationMap[c] = _duration(d, i, c); | 106 _durationMap[c] = _duration(d, i, c); |
105 _timerMap[new AnimationTimer(_tick, delay: _delay(d, i, c))] = c; | 107 _timerMap[new AnimationTimer(_tick, delay: _delay(d, i, c))] = c; |
106 | 108 |
107 if(!_transitionMap.containsKey(c)) { | 109 if (!_transitionMap.containsKey(c)) { |
108 _transitionMap[c] = 1; | 110 _transitionMap[c] = 1; |
109 } else { | 111 } else { |
110 _transitionMap[c]++; | 112 _transitionMap[c]++; |
111 } | 113 } |
112 }); | 114 }); |
113 return true; | 115 return true; |
114 }, delay: delay); | 116 }, delay: delay); |
115 } | 117 } |
116 | 118 |
117 // Returns the correct interpolator function for the old and new attribute. | 119 // Returns the correct interpolator function for the old and new attribute. |
118 _getAttrInterpolator(Element element, String attrName, newValue) { | 120 _getAttrInterpolator(Element element, String attrName, newValue) { |
119 var attr = element.attributes[attrName]; | 121 var attr = element.attributes[attrName]; |
120 var interpolator = createStringInterpolator(attr, newValue.toString()); | 122 var interpolator = createStringInterpolator(attr, newValue.toString()); |
121 return (t) => element.setAttribute(attrName, interpolator(t).toString()); | 123 return (t) => element.setAttribute(attrName, interpolator(t).toString()); |
122 } | 124 } |
123 | 125 |
124 // Returns the correct interpolator function for the old and new style. | 126 // Returns the correct interpolator function for the old and new style. |
125 _getStyleInterpolator(Element element, String styleName, newValue, priority) { | 127 _getStyleInterpolator(Element element, String styleName, newValue, priority) { |
126 var style = element.style.getPropertyValue(styleName); | 128 var style = element.style.getPropertyValue(styleName); |
127 | 129 |
128 var interpolator = createStringInterpolator(style, newValue.toString()); | 130 var interpolator = createStringInterpolator(style, newValue.toString()); |
129 | 131 |
130 return (t) => element.style.setProperty(styleName, | 132 return (t) => element.style |
131 interpolator(t).toString(), priority); | 133 .setProperty(styleName, interpolator(t).toString(), priority); |
132 } | 134 } |
133 | 135 |
134 // Ticks of the transition, this is the callback registered to the | 136 // Ticks of the transition, this is the callback registered to the |
135 // ChartedTimer, called on each animation frame until the transition duration | 137 // ChartedTimer, called on each animation frame until the transition duration |
136 // has been reached. | 138 // has been reached. |
137 bool _tick(elapsed) { | 139 bool _tick(elapsed) { |
138 if (_interrupted) { | 140 if (_interrupted) { |
139 return true; | 141 return true; |
140 } | 142 } |
141 var activeNode = _timerMap[AnimationTimer.active]; | 143 var activeNode = _timerMap[AnimationTimer.active]; |
142 var t = elapsed / _durationMap[activeNode]; | 144 var t = elapsed / _durationMap[activeNode]; |
143 for (Interpolator tween in _attrMap[activeNode]) { | 145 for (Interpolator tween in _attrMap[activeNode]) { |
144 tween(ease(t)); | 146 tween(ease(t)); |
145 } | 147 } |
146 | 148 |
147 if (t >= 1) { | 149 if (t >= 1) { |
148 if (_remove && _transitionMap[activeNode] == 1) { | 150 if (_remove && _transitionMap[activeNode] == 1) { |
149 activeNode.remove(); | 151 activeNode.remove(); |
150 } | 152 } |
151 | 153 |
152 if(_transitionMap[activeNode] > 1) { | 154 if (_transitionMap[activeNode] > 1) { |
153 _transitionMap[activeNode]--; | 155 _transitionMap[activeNode]--; |
154 } else { | 156 } else { |
155 _transitionMap.remove(activeNode); | 157 _transitionMap.remove(activeNode); |
156 } | 158 } |
157 | 159 |
158 return true; | 160 return true; |
159 } | 161 } |
160 | 162 |
161 return false; | 163 return false; |
162 } | 164 } |
(...skipping 15 matching lines...) Expand all Loading... |
178 var t = new Transition(_selection.selectAll(selector)); | 180 var t = new Transition(_selection.selectAll(selector)); |
179 t.ease = ease; | 181 t.ease = ease; |
180 t.delayWithCallback(_delay); | 182 t.delayWithCallback(_delay); |
181 t.durationWithCallback(_duration); | 183 t.durationWithCallback(_duration); |
182 return t; | 184 return t; |
183 } | 185 } |
184 | 186 |
185 Transition transition() { | 187 Transition transition() { |
186 var e = _selection.first; | 188 var e = _selection.first; |
187 var delay = _delay(_selection.scope.datum(e), 0, e) + | 189 var delay = _delay(_selection.scope.datum(e), 0, e) + |
188 _duration(_selection.scope.datum(e), 0, e) + _timerDelay; | 190 _duration(_selection.scope.datum(e), 0, e) + |
| 191 _timerDelay; |
189 var t = new _TransitionImpl(_selection, delay); | 192 var t = new _TransitionImpl(_selection, delay); |
190 t.ease = ease; | 193 t.ease = ease; |
191 t.durationWithCallback(_duration); | 194 t.durationWithCallback(_duration); |
192 return t; | 195 return t; |
193 } | 196 } |
194 | 197 |
195 void remove() { | 198 void remove() { |
196 _remove = true; | 199 _remove = true; |
197 } | 200 } |
198 } | 201 } |
OLD | NEW |