_base.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. define("dojox/fx/_base", ["dojo/_base/array","dojo/_base/lang", "dojo/_base/fx", "dojo/fx", "dojo/dom", "dojo/dom-style",
  2. "dojo/dom-geometry", "dojo/_base/connect", "dojo/_base/html"],
  3. function(arrayUtil, lang, baseFx, coreFx, dom, domStyle, domGeom, connectUtil, htmlUtil){
  4. // summary: Experimental and extended Animations beyond Dojo Core / Base functionality.
  5. // Provides advanced Lines, Animations, and convenience aliases.
  6. var dojoxFx = lang.getObject("dojox.fx", true);
  7. /*
  8. lang.mixin(dojox.fx, {
  9. // anim: Function
  10. // Alias of `dojo.anim` - the shorthand `dojo.animateProperty` with auto-play
  11. anim: dojo.fx.anim,
  12. // animateProperty: Function
  13. // Alias of `dojo.animateProperty` - animate any CSS property
  14. animateProperty: dojox.fx.animateProperty,
  15. // fadeTo: Function
  16. // Fade an element from an opacity to an opacity.
  17. // Omit `start:` property to detect. `end:` property is required.
  18. // Ultimately an alias to `dojo._fade`
  19. fadeTo: dojo._fade,
  20. // fadeIn: Function
  21. // Alias of `dojo.fadeIn` - Fade a node in.
  22. fadeIn: dojo.fadeIn,
  23. // fadeOut: Function
  24. // Alias of `dojo.fadeOut` - Fades a node out.
  25. fadeOut: dojo.fadeOut,
  26. // combine: Function
  27. // Alias of `dojo.fx.combine` - Run an array of animations in parallel
  28. combine: dojo.fx.combine,
  29. // chain: Function
  30. // Alias of `dojo.fx.chain` - Run an array of animations in sequence
  31. chain: dojo.fx.chain,
  32. // slideTo: Function
  33. // Alias of `dojo.fx.slideTo` - Slide a node to a defined top/left coordinate
  34. slideTo: dojo.fx.slideTo,
  35. // wipeIn: Function
  36. // Alias of `dojo.fx.wipeIn` - Wipe a node to visible
  37. wipeIn: dojo.fx.wipeIn,
  38. // wipeOut: Function
  39. // Alias of `dojo.fx.wipeOut` - Wipe a node to non-visible
  40. wipeOut: dojo.fx.wipeOut
  41. });
  42. */
  43. dojoxFx.sizeTo = function(/* Object */args){
  44. // summary:
  45. // Creates an animation that will size a node
  46. //
  47. // description:
  48. // Returns an animation that will size the target node
  49. // defined in args Object about it's center to
  50. // a width and height defined by (args.width, args.height),
  51. // supporting an optional method: chain||combine mixin
  52. // (defaults to chain).
  53. //
  54. // - works best on absolutely or relatively positioned elements
  55. //
  56. // example:
  57. // | // size #myNode to 400px x 200px over 1 second
  58. // | dojo.fx.sizeTo({
  59. // | node:'myNode',
  60. // | duration: 1000,
  61. // | width: 400,
  62. // | height: 200,
  63. // | method: "combine"
  64. // | }).play();
  65. //
  66. var node = args.node = dom.byId(args.node),
  67. abs = "absolute";
  68. var method = args.method || "chain";
  69. if(!args.duration){ args.duration = 500; } // default duration needed
  70. if(method == "chain"){ args.duration = Math.floor(args.duration / 2); }
  71. var top, newTop, left, newLeft, width, height = null;
  72. var init = (function(n){
  73. return function(){
  74. var cs = domStyle.getComputedStyle(n),
  75. pos = cs.position,
  76. w = cs.width,
  77. h = cs.height
  78. ;
  79. top = (pos == abs ? n.offsetTop : parseInt(cs.top) || 0);
  80. left = (pos == abs ? n.offsetLeft : parseInt(cs.left) || 0);
  81. width = (w == "auto" ? 0 : parseInt(w));
  82. height = (h == "auto" ? 0 : parseInt(h));
  83. newLeft = left - Math.floor((args.width - width) / 2);
  84. newTop = top - Math.floor((args.height - height) / 2);
  85. if(pos != abs && pos != 'relative'){
  86. var ret = domStyle.coords(n, true);
  87. top = ret.y;
  88. left = ret.x;
  89. n.style.position = abs;
  90. n.style.top = top + "px";
  91. n.style.left = left + "px";
  92. }
  93. }
  94. })(node);
  95. var anim1 = baseFx.animateProperty(lang.mixin({
  96. properties: {
  97. height: function(){
  98. init();
  99. return { end: args.height || 0, start: height };
  100. },
  101. top: function(){
  102. return { start: top, end: newTop };
  103. }
  104. }
  105. }, args));
  106. var anim2 = baseFx.animateProperty(lang.mixin({
  107. properties: {
  108. width: function(){
  109. return { start: width, end: args.width || 0 }
  110. },
  111. left: function(){
  112. return { start: left, end: newLeft }
  113. }
  114. }
  115. }, args));
  116. var anim = coreFx[(args.method == "combine" ? "combine" : "chain")]([anim1, anim2]);
  117. return anim; // dojo.Animation
  118. };
  119. dojoxFx.slideBy = function(/* Object */args){
  120. // summary:
  121. // Returns an animation to slide a node by a defined offset.
  122. //
  123. // description:
  124. // Returns an animation that will slide a node (args.node) from it's
  125. // current position to it's current posision plus the numbers defined
  126. // in args.top and args.left. standard dojo.fx mixin's apply.
  127. //
  128. // example:
  129. // | // slide domNode 50px down, and 22px left
  130. // | dojox.fx.slideBy({
  131. // | node: domNode, duration:400,
  132. // | top: 50, left: -22
  133. // | }).play();
  134. var node = args.node = dom.byId(args.node),
  135. top, left;
  136. var init = (function(n){
  137. return function(){
  138. var cs = domStyle.getComputedStyle(n);
  139. var pos = cs.position;
  140. top = (pos == 'absolute' ? n.offsetTop : parseInt(cs.top) || 0);
  141. left = (pos == 'absolute' ? n.offsetLeft : parseInt(cs.left) || 0);
  142. if(pos != 'absolute' && pos != 'relative'){
  143. var ret = domGeom.coords(n, true);
  144. top = ret.y;
  145. left = ret.x;
  146. n.style.position = "absolute";
  147. n.style.top = top + "px";
  148. n.style.left = left + "px";
  149. }
  150. }
  151. })(node);
  152. init();
  153. var _anim = baseFx.animateProperty(lang.mixin({
  154. properties: {
  155. // FIXME: is there a way to update the _Line after creation?
  156. // null start values allow chaining to work, animateProperty will
  157. // determine them for us (except in ie6? -- ugh)
  158. top: top + (args.top || 0),
  159. left: left + (args.left || 0)
  160. }
  161. }, args));
  162. connectUtil.connect(_anim, "beforeBegin", _anim, init);
  163. return _anim; // dojo.Animation
  164. };
  165. dojoxFx.crossFade = function(/* Object */args){
  166. // summary:
  167. // Returns an animation cross fading two element simultaneously
  168. //
  169. // args:
  170. // args.nodes: Array - two element array of domNodes, or id's
  171. //
  172. // all other standard animation args mixins apply. args.node ignored.
  173. //
  174. // simple check for which node is visible, maybe too simple?
  175. var node1 = args.nodes[0] = dom.byId(args.nodes[0]),
  176. op1 = htmlUtil.style(node1,"opacity"),
  177. node2 = args.nodes[1] = dom.byId(args.nodes[1]),
  178. op2 = htmlUtil.style(node2, "opacity")
  179. ;
  180. var _anim = coreFx.combine([
  181. baseFx[(op1 == 0 ? "fadeIn" : "fadeOut")](lang.mixin({
  182. node: node1
  183. },args)),
  184. baseFx[(op1 == 0 ? "fadeOut" : "fadeIn")](lang.mixin({
  185. node: node2
  186. },args))
  187. ]);
  188. return _anim; // dojo.Animation
  189. };
  190. dojoxFx.highlight = function(/*Object*/ args){
  191. // summary:
  192. // Highlight a node
  193. //
  194. // description:
  195. // Returns an animation that sets the node background to args.color
  196. // then gradually fades back the original node background color
  197. //
  198. // example:
  199. // | dojox.fx.highlight({ node:"foo" }).play();
  200. var node = args.node = dom.byId(args.node);
  201. args.duration = args.duration || 400;
  202. // Assign default color light yellow
  203. var startColor = args.color || '#ffff99',
  204. endColor = htmlUtil.style(node, "backgroundColor")
  205. ;
  206. // safari "fix"
  207. // safari reports rgba(0, 0, 0, 0) (black) as transparent color, while
  208. // other browsers return "transparent", rendered as white by default by
  209. // dojo.Color; now dojo.Color maps "transparent" to
  210. // djConfig.transparentColor ([r, g, b]), if present; so we can use
  211. // the color behind the effect node
  212. if(endColor == "rgba(0, 0, 0, 0)"){
  213. endColor = "transparent";
  214. }
  215. var anim = baseFx.animateProperty(lang.mixin({
  216. properties: {
  217. backgroundColor: { start: startColor, end: endColor }
  218. }
  219. }, args));
  220. if(endColor == "transparent"){
  221. connectUtil.connect(anim, "onEnd", anim, function(){
  222. node.style.backgroundColor = endColor;
  223. });
  224. }
  225. return anim; // dojo.Animation
  226. };
  227. dojoxFx.wipeTo = function(/*Object*/ args){
  228. // summary:
  229. // Animate a node wiping to a specific width or height
  230. //
  231. // description:
  232. // Returns an animation that will expand the
  233. // node defined in 'args' object from it's current to
  234. // the height or width value given by the args object.
  235. //
  236. // default to height:, so leave height null and specify width:
  237. // to wipeTo a width. note: this may be deprecated by a
  238. //
  239. // Note that the final value should not include
  240. // units and should be an integer. Thus a valid args object
  241. // would look something like this:
  242. //
  243. // | dojox.fx.wipeTo({ node: "nodeId", height: 200 }).play();
  244. //
  245. // Node must have no margin/border/padding, so put another
  246. // node inside your target node for additional styling.
  247. args.node = dom.byId(args.node);
  248. var node = args.node, s = node.style;
  249. var dir = (args.width ? "width" : "height"),
  250. endVal = args[dir],
  251. props = {}
  252. ;
  253. props[dir] = {
  254. // wrapped in functions so we wait till the last second to query (in case value has changed)
  255. start: function(){
  256. // start at current [computed] height, but use 1px rather than 0
  257. // because 0 causes IE to display the whole panel
  258. s.overflow = "hidden";
  259. if(s.visibility == "hidden" || s.display == "none"){
  260. s[dir] = "1px";
  261. s.display = "";
  262. s.visibility = "";
  263. return 1;
  264. }else{
  265. var now = htmlUtil.style(node,dir);
  266. return Math.max(now, 1);
  267. }
  268. },
  269. end: endVal
  270. };
  271. var anim = baseFx.animateProperty(lang.mixin({ properties: props }, args));
  272. return anim; // dojo.Animation
  273. };
  274. return dojoxFx;
  275. });