style.js 7.7 KB

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