1 | define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/fx","dojo/fx","./_base","dojo/_base/array","dojo/dom","dojo/dom-style","dojo/dom-class", |
---|
2 | "dojo/_base/connect"], |
---|
3 | function(dojo,lang,baseFx,coreFx,dojoxFx,arrayUtil,dom,domStyle,domClass,connectUtil){ |
---|
4 | dojo.experimental("dojox.fx.style"); |
---|
5 | |
---|
6 | |
---|
7 | var _getStyleSnapshot = function(/* Object */cache){ |
---|
8 | // summary: |
---|
9 | // uses a dojo.getComputedStyle(node) cache reference and |
---|
10 | // iterates through the 'documented/supported animate-able' |
---|
11 | // properties. |
---|
12 | // |
---|
13 | // returns: Array |
---|
14 | // an array of raw, calculcated values (no keys), to be normalized/compared |
---|
15 | // elsewhere |
---|
16 | return arrayUtil.map(dojoxFx._allowedProperties, function(style){ |
---|
17 | return cache[style]; // String |
---|
18 | }); // Array |
---|
19 | }; |
---|
20 | |
---|
21 | var _getCalculatedStyleChanges = function(node, cssClass, addClass){ |
---|
22 | // summary: |
---|
23 | // Calculate the difference in style properties between two states |
---|
24 | // description: |
---|
25 | // calculate and normalize(?) the differences between two states |
---|
26 | // of a node (args.node) by quickly adding or removing a class, and |
---|
27 | // iterating over the results of dojox.fx._getStyleSnapshot() |
---|
28 | // addClass: |
---|
29 | // true to calculate what adding a class would do, |
---|
30 | // false to calculate what removing the class would do |
---|
31 | |
---|
32 | node = dom.byId(node); |
---|
33 | var cs = domStyle.getComputedStyle(node); |
---|
34 | |
---|
35 | // take our snapShots |
---|
36 | var _before = _getStyleSnapshot(cs); |
---|
37 | dojo[(addClass ? "addClass" : "removeClass")](node, cssClass); |
---|
38 | var _after = _getStyleSnapshot(cs); |
---|
39 | dojo[(addClass ? "removeClass" : "addClass")](node, cssClass); |
---|
40 | |
---|
41 | var calculated = {}, i = 0; |
---|
42 | arrayUtil.forEach(dojoxFx._allowedProperties, function(prop){ |
---|
43 | if(_before[i] != _after[i]){ |
---|
44 | // FIXME: the static units: px is not good, either. need to parse unit from computed style? |
---|
45 | calculated[prop] = parseInt(_after[i]) /* start: parseInt(_before[i]), units: 'px' */ ; |
---|
46 | } |
---|
47 | i++; |
---|
48 | }); |
---|
49 | return calculated; |
---|
50 | }; |
---|
51 | |
---|
52 | var styleFx = { |
---|
53 | // summary: |
---|
54 | // dojox.fx CSS Class Animations |
---|
55 | // description: |
---|
56 | // a set of functions to animate properties based on |
---|
57 | // normalized CSS class definitions. |
---|
58 | |
---|
59 | addClass: function(node, cssClass, args){ |
---|
60 | // summary: |
---|
61 | // Animate the effects of adding a class to a node |
---|
62 | // description: |
---|
63 | // Creates an animation that will animate |
---|
64 | // the properties of a node to the properties |
---|
65 | // defined in a standard CSS .class definition. |
---|
66 | // (calculating the differences itself) |
---|
67 | // node: String|DomNode |
---|
68 | // A String ID or DomNode referce to animate |
---|
69 | // cssClass: String |
---|
70 | // The CSS class name to add to the node |
---|
71 | // args: Object? |
---|
72 | // Additional optional `dojo.animateProperty` arguments, such as |
---|
73 | // duration, easing and so on. |
---|
74 | // example: |
---|
75 | // | |
---|
76 | // | .bar { line-height: 12px; } |
---|
77 | // | .foo { line-height: 40px; } |
---|
78 | // | <div class="bar" id="test"> |
---|
79 | // | Multi<br>line<br>text |
---|
80 | // | </div> |
---|
81 | // | |
---|
82 | // | // animate to line-height:40px |
---|
83 | // | dojo.fx.addClass("test", "foo").play(); |
---|
84 | // |
---|
85 | node = dom.byId(node); |
---|
86 | |
---|
87 | var pushClass = (function(n){ |
---|
88 | // summary: |
---|
89 | // onEnd we want to add the class to the node |
---|
90 | // (as dojo.addClass naturally would) in case our |
---|
91 | // class parsing misses anything the browser would |
---|
92 | // otherwise interpret. this may cause some flicker, |
---|
93 | // and will only apply the class so children can inherit |
---|
94 | // after the animation is done (potentially more flicker) |
---|
95 | return function(){ |
---|
96 | domClass.add(n, cssClass); |
---|
97 | n.style.cssText = _beforeStyle; |
---|
98 | } |
---|
99 | })(node); |
---|
100 | |
---|
101 | // _getCalculatedStleChanges is the core of our style/class animations |
---|
102 | var mixedProperties = _getCalculatedStyleChanges(node, cssClass, true); |
---|
103 | var _beforeStyle = node.style.cssText; |
---|
104 | var _anim = baseFx.animateProperty(lang.mixin({ |
---|
105 | node: node, |
---|
106 | properties: mixedProperties |
---|
107 | }, args)); |
---|
108 | connectUtil.connect(_anim, "onEnd", _anim, pushClass); |
---|
109 | return _anim; // dojo.Animation |
---|
110 | }, |
---|
111 | |
---|
112 | removeClass: function(node, cssClass, args){ |
---|
113 | // summary: |
---|
114 | // Animate the effects of removing a class from a node |
---|
115 | // description: |
---|
116 | // Creates an animation that will animate the properties of a |
---|
117 | // node (args.node) to the properties calculated after removing |
---|
118 | // a standard CSS className from a that node. |
---|
119 | // |
---|
120 | // calls dojo.removeClass(args.cssClass) onEnd of animation |
---|
121 | // |
---|
122 | // standard dojo.Animation object rules apply. |
---|
123 | // example: |
---|
124 | // | // animate the removal of "foo" from a node with id="bar" |
---|
125 | // | dojox.fx.removeClass("bar", "foo").play() |
---|
126 | |
---|
127 | node = dom.byId(node); |
---|
128 | |
---|
129 | var pullClass = (function(n){ |
---|
130 | // summary: |
---|
131 | // onEnd we want to remove the class from the node |
---|
132 | // (as dojo.removeClass naturally would) in case our class |
---|
133 | // parsing misses anything the browser would otherwise |
---|
134 | // interpret. this may cause some flicker, and will only |
---|
135 | // apply the class so children can inherit after the |
---|
136 | // animation is done (potentially more flicker) |
---|
137 | |
---|
138 | return function(){ |
---|
139 | domClass.remove(n, cssClass); |
---|
140 | n.style.cssText = _beforeStyle; |
---|
141 | } |
---|
142 | })(node); |
---|
143 | |
---|
144 | var mixedProperties = _getCalculatedStyleChanges(node, cssClass); |
---|
145 | var _beforeStyle = node.style.cssText; |
---|
146 | var _anim = baseFx.animateProperty(lang.mixin({ |
---|
147 | node: node, |
---|
148 | properties: mixedProperties |
---|
149 | }, args)); |
---|
150 | connectUtil.connect(_anim, "onEnd", _anim, pullClass); |
---|
151 | return _anim; // dojo.Animation |
---|
152 | }, |
---|
153 | |
---|
154 | toggleClass: function(node, cssClass, condition, args){ |
---|
155 | // summary: |
---|
156 | // Animate the effects of Toggling a class on a Node |
---|
157 | // description: |
---|
158 | // creates an animation that will animate the effect of |
---|
159 | // toggling a class on or off of a node. |
---|
160 | // Adds a class to node if not present, or removes if present. |
---|
161 | // Pass a boolean condition if you want to explicitly add or remove. |
---|
162 | // node: String|DomNode |
---|
163 | // The domNode (or string of the id) to toggle |
---|
164 | // cssClass: String |
---|
165 | // String of the classname to add to the node |
---|
166 | // condition: Boolean? |
---|
167 | // If passed, true means to add the class, false means to remove. |
---|
168 | // args: Object? |
---|
169 | // Additional `dojo.Animation` args to pass along. |
---|
170 | // example: |
---|
171 | // | // add the class "sampleClass" to a node id="theNode" |
---|
172 | // | dojox.fx.toggleClass("theNode","sampleClass",true).play(); |
---|
173 | // example: |
---|
174 | // | // toggle the class "sampleClass" on the node id="theNode" |
---|
175 | // | dojox.fx.toggleClass("theNode","sampleClass").play(); |
---|
176 | |
---|
177 | if(typeof condition == "undefined"){ |
---|
178 | condition = !domClass.contains(node, cssClass); |
---|
179 | } |
---|
180 | return dojoxFx[(condition ? "addClass" : "removeClass")](node, cssClass, args); // dojo.Animation |
---|
181 | }, |
---|
182 | |
---|
183 | _allowedProperties: [ |
---|
184 | // summary: |
---|
185 | // Our pseudo map of properties we will check for. |
---|
186 | // description: |
---|
187 | // it should be much more intuitive. a way to normalize and |
---|
188 | // "predict" intent, or even something more clever ... |
---|
189 | // open to suggestions. |
---|
190 | |
---|
191 | // no-brainers: |
---|
192 | "width", |
---|
193 | "height", |
---|
194 | // only if position = absolute || relative? |
---|
195 | "left", "top", // "right", "bottom", |
---|
196 | // these need to be filtered through dojo.colors? |
---|
197 | // "background", // normalize to: |
---|
198 | /* "backgroundImage", */ |
---|
199 | // "backgroundPosition", // FIXME: to be effective, this needs "#px #px"? |
---|
200 | "backgroundColor", |
---|
201 | |
---|
202 | "color", |
---|
203 | |
---|
204 | // "border", |
---|
205 | //"borderBottomColor", |
---|
206 | "borderBottomWidth", |
---|
207 | //"borderTopColor", |
---|
208 | "borderTopWidth", |
---|
209 | //"borderLeftColor", |
---|
210 | "borderLeftWidth", |
---|
211 | //"borderRightColor", |
---|
212 | "borderRightWidth", |
---|
213 | |
---|
214 | // "padding", // normalize to: |
---|
215 | "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", |
---|
216 | // "margin", // normalize to: |
---|
217 | "marginLeft", "marginTop", "marginRight", "marginBottom", |
---|
218 | |
---|
219 | // unit import/delicate?: |
---|
220 | "lineHeight", |
---|
221 | "letterSpacing", |
---|
222 | "fontSize" |
---|
223 | ] |
---|
224 | }; |
---|
225 | lang.mixin(dojoxFx,styleFx); |
---|
226 | return styleFx; |
---|
227 | }); |
---|