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