1 if(!dojo._hasResource["dojox.fx.style"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojox.fx.style"] = true;
3 dojo.provide("dojox.fx.style");
4 dojo.experimental("dojox.fx.style");
6 // summary: dojox.fx CSS Class _Animations:
8 // description: a set of functions to animate properties based on
9 // normalized CSS class definitions.
11 // provides: addClass, removeClass, and toggleClass
13 dojo.require("dojox.fx._base");
15 // FIXME: should the call signatures match dojo.addClass/removeClass/toggleClass and extend
16 // by having a third (or fourth) param to mix in additional _Animation args for advanced
17 // usage (delay: curve: repeat: easing: etc ... )
19 dojox.fx.addClass = function(/*dojox.fx._arg.StyleArgs*/ args){
20 // summary: Animate the effects of adding a class to a node
22 // Creates an animation that will animate
23 // the properties of a node to the properties
24 // defined in a standard CSS .class definition.
25 // (calculating the differences itself)
29 // | .bar { line-height: 12px; }
30 // | .foo { line-height: 40px; }
31 // | <div class="bar" id="test">
32 // | Multi<br>line<br>text
35 // | // animate to line-height:40px
36 // | dojo.fx.addClass({ node:"test", cssClass:"foo" }).play();
38 var node = (args.node = dojo.byId(args.node));
40 var pushClass = (function(n){
41 // summary: onEnd we want to add the class to the node
42 // (as dojo.addClass naturally would) in case our
43 // class parsing misses anything the browser would
44 // otherwise interpret. this may cause some flicker,
45 // and will only apply the class so children can inherit
46 // after the animation is done (potentially more flicker)
48 dojo.addClass(n, args.cssClass);
49 n.style.cssText = _beforeStyle;
53 // _getCalculatedStleChanges is the core of our style/class animations
54 var mixedProperties = dojox.fx._getCalculatedStyleChanges(args,true);
55 var _beforeStyle = node.style.cssText;
56 var _anim = dojo.animateProperty(dojo.mixin({
57 properties: mixedProperties
59 dojo.connect(_anim,"onEnd",_anim,pushClass);
60 return _anim; // dojo._Animation
63 dojox.fx.removeClass = function(/*dojox.fx._arg.StyleArgs*/ args){
64 // summary: Animate the effects of removing a class from a node
66 // Creates an animation that will animate the properties of a
67 // node (args.node) to the properties calculated after removing
68 // a standard CSS className from a that node.
70 // calls dojo.removeClass(args.cssClass) onEnd of animation
72 // standard dojo._Animation object rules apply.
75 // | // animate the removal of "foo" from a node with id="bar"
76 // | dojox.fx.removeClass({
81 var node = (args.node = dojo.byId(args.node));
83 var pullClass = (function(n){
84 // summary: onEnd we want to remove the class from the node
85 // (as dojo.removeClass naturally would) in case our class
86 // parsing misses anything the browser would otherwise
87 // interpret. this may cause some flicker, and will only
88 // apply the class so children can inherit after the
89 // animation is done (potentially more flicker)
92 dojo.removeClass(n, args.cssClass);
93 n.style.cssText = _beforeStyle;
97 var mixedProperties = dojox.fx._getCalculatedStyleChanges(args,false);
98 var _beforeStyle = node.style.cssText;
99 var _anim = dojo.animateProperty(dojo.mixin({
100 properties: mixedProperties
102 dojo.connect(_anim,"onEnd",_anim,pullClass);
103 return _anim; // dojo._Animation
106 dojox.fx.toggleClass = function(/*DomNode|String*/node, /*String*/cssClass, /*Boolean?*/condition){
108 // Animate the effects of Toggling a class on a Node
111 // creates an animation that will animate the effect of
112 // toggling a class on or off of a node.
113 // Adds a class to node if not present, or removes if present.
114 // Pass a boolean condition if you want to explicitly add or remove.
116 // The domNode (or string of the id) to toggle
118 // String of the classname to add to the node
120 // If passed, true means to add the class, false means to remove.
123 // | // add the class "sampleClass" to a node id="theNode"
124 // | dojox.fx.toggleClass("theNode","sampleClass",true).play();
126 // | // toggle the class "sampleClass" on the node id="theNode"
127 // | dojox.fx.toggleClass("theNode","sampleClass").play();
129 if(typeof condition == "undefined"){
130 condition = !dojo.hasClass(node, cssClass);
132 return dojox.fx[(condition ? "addClass" : "removeClass")]({ node: node, cssClass:cssClass }); // dojo._Animation
133 // TODO: support 4th param animMixin to allow passing of easing and duration and other _Animtion options
136 dojox.fx._allowedProperties = [
137 // summary: Our pseudo map of properties we will check for.
139 // it should be much more intuitive. a way to normalize and
140 // "predict" intent, or even something more clever ...
141 // open to suggestions.
146 // only if position = absolute || relative?
147 "left", "top", // "right", "bottom",
148 // these need to be filtered through dojo.colors?
149 // "background", // normalize to:
150 /* "backgroundImage", */
151 // "backgroundPosition", // FIXME: to be effective, this needs "#px #px"?
157 "borderBottomColor", "borderBottomWidth",
158 "borderTopColor","borderTopWidth",
159 "borderLeftColor","borderLeftWidth",
160 "borderRightColor","borderRightWidth",
162 // "padding", // normalize to:
163 "paddingLeft", "paddingRight", "paddingTop", "paddingBottom",
164 // "margin", // normalize to:
165 "marginLeft", "marginTop", "marginRight", "marginBottom",
167 // unit import/delicate?:
173 dojox.fx._getStyleSnapshot = function(/* Object */cache){
175 // uses a dojo.getComputedStyle(node) cache reference and
176 // iterates through the 'documented/supported animate-able'
180 // an array of raw, calculcated values (no keys), to be normalized/compared
182 return dojo.map(dojox.fx._allowedProperties,function(style){
183 return cache[style]; // String
187 dojox.fx._getCalculatedStyleChanges = function(/*dojox.fx._arg.StyleArgs*/ args, /*Boolean*/addClass){
188 // summary: calclate the difference in style properties between two states
190 // calculate and normalize(?) the differences between two states
191 // of a node (args.node) by quickly adding or removing a class, and
192 // iterateing over the results of dojox.fx._getStyleSnapshot()
195 // true to calculate what adding a class would do,
196 // false to calculate what removing the class would do
198 var node = (args.node = dojo.byId(args.node));
199 var cs = dojo.getComputedStyle(node);
201 // take our snapShots
202 var _before = dojox.fx._getStyleSnapshot(cs);
203 dojo[(addClass ? "addClass" : "removeClass")](node,args.cssClass);
204 var _after = dojox.fx._getStyleSnapshot(cs);
205 dojo[(addClass ? "removeClass" : "addClass")](node,args.cssClass);
209 dojo.forEach(dojox.fx._allowedProperties,function(prop){
210 if(_before[i] != _after[i]){
211 // FIXME: the static unit: px is not good, either. need to parse unit from computed style?
212 calculated[prop] = { end: parseInt(_after[i]) /* start: parseInt(_before[i]), unit: 'px' */ };