_base.js 8.9 KB

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