split.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  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.split"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.fx.split"] = true;
  8. dojo.provide("dojox.fx.split");
  9. dojo.require("dojo.fx");
  10. dojo.require("dojo.fx.easing");
  11. dojo.mixin(dojox.fx,{
  12. _split: function(/*Object*/ args){
  13. // summary: Split a node into rectangular pieces and animate them.
  14. //
  15. // description:
  16. // Returns an animation that will split the node into a grid
  17. // of pieces that move independently.
  18. //
  19. // args:
  20. // args.crop: Boolean - If true, pieces will only be visible inside node's boundries
  21. // args.rows: Integer - The number of horizontal pieces (default is 3)
  22. // args.columns: Integer - The number of vertical pieces (default is 3)
  23. // args.pieceAnimation: Function(piece, x, y, coords) - Returns either the dojo.Animation
  24. // or an array of dojo.Animation objects for the piece at location (x, y) in the node's grid;
  25. // coords is the result of dojo.coords(args.node, true);
  26. args.rows = args.rows || 3;
  27. args.columns = args.columns || 3;
  28. args.duration = args.duration || 1000;
  29. var node = args.node = dojo.byId(args.node),
  30. parentNode = node.parentNode,
  31. pNode = parentNode,
  32. body = dojo.body(),
  33. _pos = "position"
  34. ;
  35. while(pNode && pNode != body && dojo.style(pNode, _pos) == "static"){
  36. pNode = pNode.parentNode;
  37. }
  38. var pCoords = pNode != body ? dojo.position(pNode, true) : { x: 0, y: 0 },
  39. coords = dojo.position(node, true),
  40. nodeHeight = dojo.style(node, "height"),
  41. nodeWidth = dojo.style(node, "width"),
  42. hBorder = dojo.style(node, "borderLeftWidth") + dojo.style(node, "borderRightWidth"),
  43. vBorder = dojo.style(node, "borderTopWidth") + dojo.style(node, "borderBottomWidth"),
  44. pieceHeight = Math.ceil(nodeHeight / args.rows),
  45. pieceWidth = Math.ceil(nodeWidth / args.columns),
  46. container = dojo.create(node.tagName, {
  47. style: {
  48. position: "absolute",
  49. padding: 0,
  50. margin: 0,
  51. border:"none",
  52. top: coords.y - pCoords.y + "px",
  53. left: coords.x - pCoords.x + "px",
  54. height: nodeHeight + vBorder + "px",
  55. width: nodeWidth + hBorder + "px",
  56. background: "none",
  57. overflow: args.crop ? "hidden" : "visible",
  58. zIndex: dojo.style(node, "zIndex")
  59. }
  60. }, node, "after"),
  61. animations = [],
  62. pieceHelper = dojo.create(node.tagName, {
  63. style: {
  64. position: "absolute",
  65. border: "none",
  66. padding: 0,
  67. margin: 0,
  68. height: pieceHeight + hBorder + "px",
  69. width: pieceWidth + vBorder + "px",
  70. overflow: "hidden"
  71. }
  72. });
  73. // Create the pieces and their animations
  74. for(var y = 0, ly = args.rows; y < ly; y++){
  75. for(var x = 0, lx = args.columns; x < lx; x++){
  76. // Create the piece
  77. var piece = dojo.clone(pieceHelper),
  78. pieceContents = dojo.clone(node),
  79. pTop = y * pieceHeight,
  80. pLeft = x * pieceWidth
  81. ;
  82. // IE hack
  83. pieceContents.style.filter = "";
  84. // removing the id attribute from the cloned nodes
  85. dojo.removeAttr(pieceContents, "id");
  86. dojo.style(piece, {
  87. border: "none",
  88. overflow: "hidden",
  89. top: pTop + "px",
  90. left: pLeft + "px"
  91. });
  92. dojo.style(pieceContents, {
  93. position: "static",
  94. opacity: "1",
  95. marginTop: -pTop + "px",
  96. marginLeft: -pLeft + "px"
  97. });
  98. piece.appendChild(pieceContents);
  99. container.appendChild(piece);
  100. var pieceAnimation = args.pieceAnimation(piece, x, y, coords);
  101. if(dojo.isArray(pieceAnimation)){
  102. // if pieceAnimation is an array, append its elements
  103. animations = animations.concat(pieceAnimation);
  104. }else{
  105. // otherwise, append it
  106. animations.push(pieceAnimation);
  107. }
  108. }
  109. }
  110. var anim = dojo.fx.combine(animations);
  111. dojo.connect(anim, "onEnd", anim, function(){
  112. container.parentNode.removeChild(container);
  113. });
  114. if(args.onPlay){
  115. dojo.connect(anim, "onPlay", anim, args.onPlay);
  116. }
  117. if(args.onEnd){
  118. dojo.connect(anim, "onEnd", anim, args.onEnd);
  119. }
  120. return anim; // dojo.Animation
  121. },
  122. explode: function(/*Object*/ args){
  123. // summary: Explode a node into rectangular pieces
  124. //
  125. // description:
  126. // Returns an animation that will split the node into a grid
  127. // of pieces that fly away from the center.
  128. //
  129. // args:
  130. // args.rows: Integer - The number of horizontal pieces (default is 3)
  131. // args.columns: Integer - The number of vertical pieces (default is 3)
  132. // args.random: Float - If set, pieces fly to random distances, for random durations,
  133. // and in slightly random directions. The value defines how much
  134. // randomness is introduced.
  135. // args.distance: Float - Multiplier for the distance the pieces fly (even when random)
  136. // args.fade: Boolean - If true, pieces fade out while in motion (default is true)
  137. // args.fadeEasing: Function - If args.fade is true, the fade animations use this easing function
  138. // args.unhide: Boolean - If true, the animation is reversed
  139. // args.sync: Boolean - If args.unhide is true, all the pieces converge at the same time
  140. // (default is true)
  141. var node = args.node = dojo.byId(args.node);
  142. args.rows = args.rows || 3;
  143. args.columns = args.columns || 3;
  144. args.distance = args.distance || 1;
  145. args.duration = args.duration || 1000;
  146. args.random = args.random || 0;
  147. if(!args.fade){
  148. args.fade = true;
  149. }
  150. if(typeof args.sync == "undefined"){
  151. args.sync = true;
  152. }
  153. args.random = Math.abs(args.random);
  154. // Returns the animation object for each piece
  155. args.pieceAnimation = function(piece, x, y, coords){
  156. var pieceHeight = coords.h / args.rows,
  157. pieceWidth = coords.w / args.columns,
  158. distance = args.distance * 2,
  159. duration = args.duration,
  160. ps = piece.style,
  161. startTop = parseInt(ps.top),
  162. startLeft = parseInt(ps.left),
  163. delay = 0,
  164. randomX = 0,
  165. randomY = 0;
  166. if(args.random){
  167. var seed = (Math.random() * args.random) + Math.max(1 - args.random, 0);
  168. distance *= seed;
  169. duration *= seed;
  170. // To syncronize, give each piece an appropriate delay so they end together
  171. delay = ((args.unhide && args.sync) || (!args.unhide && !args.sync)) ? (args.duration - duration) : 0;
  172. // Slightly randomize the direction of each piece
  173. randomX = Math.random() - 0.5;
  174. randomY = Math.random() - 0.5;
  175. }
  176. var distanceY = ((coords.h - pieceHeight) / 2 - pieceHeight * y),
  177. distanceX = ((coords.w - pieceWidth) / 2 - pieceWidth * x),
  178. distanceXY = Math.sqrt(Math.pow(distanceX, 2) + Math.pow(distanceY, 2)),
  179. endTop = parseInt(startTop - distanceY * distance + distanceXY * randomY),
  180. endLeft = parseInt(startLeft - distanceX * distance + distanceXY * randomX)
  181. ;
  182. // Create the animation objects for the piece
  183. // These are separate anim objects so they can have different curves
  184. var pieceSlide = dojo.animateProperty({
  185. node: piece,
  186. duration: duration,
  187. delay: delay,
  188. easing: (args.easing || (args.unhide ? dojo.fx.easing.sinOut : dojo.fx.easing.circOut)),
  189. beforeBegin: (args.unhide ? function(){
  190. if(args.fade){
  191. dojo.style(piece, { opacity: "0"});
  192. }
  193. ps.top = endTop + "px";
  194. ps.left = endLeft + "px";
  195. } : undefined),
  196. properties: {
  197. top: (args.unhide ? { start: endTop, end: startTop } : { start: startTop, end: endTop }),
  198. left: (args.unhide ? { start: endLeft, end: startLeft } : { start: startLeft, end: endLeft })
  199. }
  200. });
  201. if(args.fade){
  202. var pieceFade = dojo.animateProperty({
  203. node: piece,
  204. duration: duration,
  205. delay: delay,
  206. easing: (args.fadeEasing || dojo.fx.easing.quadOut),
  207. properties: {
  208. opacity: (args.unhide ? { start: "0", end: "1" } : { start: "1", end: "0" })
  209. }
  210. });
  211. // return both animations as an array
  212. return (args.unhide ? [pieceFade, pieceSlide] : [pieceSlide, pieceFade]);
  213. }else{
  214. // Otherwise return only the slide animation
  215. return pieceSlide;
  216. }
  217. };
  218. var anim = dojox.fx._split(args);
  219. if(args.unhide){
  220. dojo.connect(anim, "onEnd", null, function(){
  221. dojo.style(node, {opacity: "1" });
  222. });
  223. }else{
  224. dojo.connect(anim, "onPlay", null, function(){
  225. dojo.style(node, { opacity: "0" });
  226. });
  227. }
  228. return anim; // dojo.Animation
  229. },
  230. converge: function(/*Object*/ args){
  231. args.unhide = true;
  232. return dojox.fx.explode(args);
  233. },
  234. disintegrate: function(/*Object*/ args){
  235. // summary: Split a node into rectangular pieces and let them fall
  236. //
  237. // description:
  238. // Returns an animation that will split the node into a grid
  239. // of pieces that drop.
  240. //
  241. // args:
  242. // args.rows: Integer - The number of horizontal pieces (default is 5)
  243. // args.columns: Integer - The number of vertical pieces (default is 5)
  244. // args.interval: Float - The number of milliseconds between each piece's animation
  245. // args.distance: Float - The number of the node's heights to drop (default is 1.5)
  246. // args.fade: Boolean - If true, pieces fade out while in motion (default is true)
  247. // args.random: Float - If set, pieces fall in random order. The value defines how much
  248. // randomness is introduced.
  249. // args.reverseOrder: Boolean - If true, pieces animate in reversed order
  250. // args.unhide: Boolean - If true, the peices fall from above and land in place
  251. var node = args.node = dojo.byId(args.node);
  252. args.rows = args.rows || 5;
  253. args.columns = args.columns || 5;
  254. args.duration = args.duration || 1500;
  255. args.interval = args.interval || args.duration / (args.rows + args.columns * 2);
  256. args.distance = args.distance || 1.5;
  257. args.random = args.random || 0;
  258. if(typeof args.fade == "undefined"){
  259. args.fade = true;
  260. }
  261. var random = Math.abs(args.random),
  262. duration = args.duration - (args.rows + args.columns) * args.interval;
  263. // Returns the animation object for each piece
  264. args.pieceAnimation = function(piece, x, y, coords){
  265. var randomDelay = Math.random() * (args.rows + args.columns) * args.interval,
  266. ps = piece.style,
  267. // If distance is negative, start from the top right instead of bottom left
  268. uniformDelay = (args.reverseOrder || args.distance < 0) ?
  269. ((x + y) * args.interval) :
  270. (((args.rows + args.columns) - (x + y)) * args.interval),
  271. delay = randomDelay * random + Math.max(1 - random, 0) * uniformDelay,
  272. // Create the animation object for the piece
  273. properties = {}
  274. ;
  275. if(args.unhide){
  276. properties.top = {
  277. start: (parseInt(ps.top) - coords.h * args.distance),
  278. end: parseInt(ps.top)
  279. };
  280. if(args.fade){
  281. properties.opacity = {start: "0", end: "1"};
  282. }
  283. }else{
  284. properties.top = {end: (parseInt(ps.top) + coords.h * args.distance)};
  285. if(args.fade){
  286. properties.opacity = {end: "0"};
  287. }
  288. }
  289. var pieceAnimation = dojo.animateProperty({
  290. node: piece,
  291. duration: duration,
  292. delay: delay,
  293. easing: (args.easing || (args.unhide ? dojo.fx.easing.sinIn : dojo.fx.easing.circIn)),
  294. properties: properties,
  295. beforeBegin: (args.unhide ? function(){
  296. if(args.fade){
  297. dojo.style(piece, { opacity: "0" });
  298. }
  299. ps.top = properties.top.start + "px";
  300. } : undefined)
  301. });
  302. return pieceAnimation;
  303. };
  304. var anim = dojox.fx._split(args);
  305. if(args.unhide){
  306. dojo.connect(anim, "onEnd", anim, function(){
  307. dojo.style(node, { opacity: "1" });
  308. });
  309. }else{
  310. dojo.connect(anim, "onPlay", anim, function(){
  311. dojo.style(node, { opacity: "0" });
  312. });
  313. }
  314. return anim; // dojo.Animation
  315. },
  316. build: function(/*Object*/ args){
  317. args.unhide = true;
  318. return dojox.fx.disintegrate(args);
  319. },
  320. shear: function(/*Object*/ args){
  321. // summary: Split a node into rectangular pieces and slide them in alternating directions
  322. //
  323. // description:
  324. // Returns an animation that will split the node into a grid
  325. // of pieces that slide in alternating directions.
  326. //
  327. // args:
  328. // args.rows: Integer - The number of horizontal pieces (default is 6)
  329. // args.columns: Integer - The number of vertical pieces (default is 6)
  330. // args.interval: Float - The number of milliseconds between each piece's animation (default is 0)
  331. // args.distance: Float - The multiple of the node's dimensions to slide (default is 1)
  332. // args.fade: Boolean - If true, pieces fade out while in motion (default is true)
  333. // args.random: Float - If true, pieces have a random delay. The value defines how much
  334. // randomness is introduced
  335. // args.reverseOrder: Boolean - If true, pieces animate in reversed order
  336. // args.unhide: Boolean - If true, the animation is reversed
  337. var node = args.node = dojo.byId(args.node);
  338. args.rows = args.rows || 6;
  339. args.columns = args.columns || 6;
  340. args.duration = args.duration || 1000;
  341. args.interval = args.interval || 0;
  342. args.distance = args.distance || 1;
  343. args.random = args.random || 0;
  344. if(typeof(args.fade) == "undefined"){
  345. args.fade = true;
  346. }
  347. var random = Math.abs(args.random),
  348. duration = (args.duration - (args.rows + args.columns) * Math.abs(args.interval))
  349. ;
  350. // Returns the animation object for each piece
  351. args.pieceAnimation = function(piece, x, y, coords){
  352. // Since x an y start at 0, the opposite is true...
  353. var colIsOdd = !(x % 2),
  354. rowIsOdd = !(y % 2),
  355. randomDelay = Math.random() * duration,
  356. uniformDelay = (args.reverseOrder) ?
  357. (((args.rows + args.columns) - (x + y)) * args.interval) :
  358. ((x + y) * args.interval),
  359. delay = randomDelay * random + Math.max(1 - random, 0) * uniformDelay,
  360. properties = {},
  361. ps = piece.style
  362. ;
  363. if(args.fade){
  364. properties.opacity = (args.unhide ? { start: "0", end: "1" } : { end: "0" });
  365. }
  366. // If we have only rows or columns, ignore the other dimension
  367. if(args.columns == 1){
  368. colIsOdd = rowIsOdd;
  369. }else if(args.rows == 1){
  370. rowIsOdd = !colIsOdd;
  371. }
  372. // Determine the piece's direction
  373. var left = parseInt(ps.left),
  374. top = parseInt(ps.top),
  375. distanceX = args.distance*coords.w,
  376. distanceY = args.distance*coords.h
  377. ;
  378. if(args.unhide){
  379. if(colIsOdd == rowIsOdd){
  380. properties.left = colIsOdd ? {start: (left - distanceX), end: left} : {start: (left + distanceX), end: left};
  381. }else{
  382. properties.top = colIsOdd ? {start: (top + distanceY), end: top} : {start: (top - distanceY), end: top};
  383. }
  384. }else{
  385. if(colIsOdd == rowIsOdd){
  386. properties.left = colIsOdd ? {end: (left - distanceX)} : {end: (left + distanceX)};
  387. }else{
  388. properties.top = colIsOdd ? {end: (top + distanceY)} : {end: (top - distanceY)};
  389. }
  390. }
  391. // Create the animation object for the piece
  392. var pieceAnimation = dojo.animateProperty({
  393. node: piece,
  394. duration: duration,
  395. delay: delay,
  396. easing: (args.easing || dojo.fx.easing.sinInOut),
  397. properties: properties,
  398. beforeBegin: (args.unhide ? function(){
  399. if(args.fade){
  400. ps.opacity = "0";
  401. }
  402. if(colIsOdd == rowIsOdd){
  403. ps.left = properties.left.start + "px";
  404. }else{
  405. ps.top = properties.top.start + "px";
  406. }
  407. } : undefined)
  408. });
  409. return pieceAnimation;
  410. };
  411. var anim = dojox.fx._split(args);
  412. if(args.unhide){
  413. dojo.connect(anim, "onEnd", anim, function(){
  414. dojo.style(node, { opacity: "1" });
  415. });
  416. }else{
  417. dojo.connect(anim, "onPlay", anim, function(){
  418. dojo.style(node, { opacity: "0" });
  419. });
  420. }
  421. return anim; // dojo.Animation
  422. },
  423. unShear: function(/*Object*/ args){
  424. args.unhide = true;
  425. return dojox.fx.shear(args);
  426. },
  427. pinwheel: function(/*Object*/ args){
  428. // summary: Split a node into rectangular pieces and wipe them in alternating directions
  429. //
  430. // description:
  431. // Returns an animation that will split the node into a grid
  432. // of pieces that wipe in alternating directions.
  433. //
  434. // args:
  435. // args.rows: Integer - The number of horizontal pieces (default is 4)
  436. // args.columns: Integer - The number of vertical pieces (default is 4)
  437. // args.interval: Float - The number of milliseconds between each piece's animation (default is 0)
  438. // args.distance: Float - The percentage of the piece's dimensions the piece should wipe
  439. // args.fade: Boolean - If true, pieces fade out while in motion (default is true)
  440. // args.random: Float - If true, pieces have a random delay. The value defines how much
  441. // randomness is introduced.
  442. // args.unhide: Boolean - If true, the animation is reversed
  443. var node = args.node = dojo.byId(args.node);
  444. args.rows = args.rows || 4;
  445. args.columns = args.columns || 4;
  446. args.duration = args.duration || 1000;
  447. args.interval = args.interval || 0;
  448. args.distance = args.distance || 1;
  449. args.random = args.random || 0;
  450. if(typeof args.fade == "undefined"){
  451. args.fade = true;
  452. }
  453. var duration = (args.duration - (args.rows + args.columns) * Math.abs(args.interval));
  454. // Returns the animation object for each piece
  455. args.pieceAnimation = function(piece, x, y, coords){
  456. var pieceHeight = coords.h / args.rows,
  457. pieceWidth = coords.w / args.columns,
  458. // because x an y start at 0, the opposite is true...
  459. colIsOdd = !(x % 2),
  460. rowIsOdd = !(y % 2),
  461. randomDelay = Math.random() * duration,
  462. uniformDelay = (args.interval < 0) ?
  463. (((args.rows + args.columns) - (x + y)) * args.interval * -1) :
  464. ((x + y) * args.interval),
  465. delay = randomDelay * args.random + Math.max(1 - args.random, 0) * uniformDelay,
  466. properties = {},
  467. ps = piece.style
  468. ;
  469. if(args.fade){
  470. properties.opacity = (args.unhide ? {start: 0, end: 1} : {end:0});
  471. }
  472. // If we have only rows or columns, ignore the other dimension
  473. if(args.columns == 1){
  474. colIsOdd = !rowIsOdd;
  475. }else if(args.rows == 1){
  476. rowIsOdd = colIsOdd;
  477. }
  478. // Determine the piece's direction
  479. var left = parseInt(ps.left),
  480. top = parseInt(ps.top)
  481. ;
  482. if(colIsOdd){
  483. if(rowIsOdd){
  484. properties.top = args.unhide ?
  485. { start: top + pieceHeight * args.distance, end: top} :
  486. { start: top, end: top + pieceHeight * args.distance} ;
  487. }else{
  488. properties.left = args.unhide ?
  489. { start: left + pieceWidth * args.distance, end: left } :
  490. { start: left, end: left + pieceWidth * args.distance } ;
  491. }
  492. }
  493. if(colIsOdd != rowIsOdd){
  494. properties.width = args.unhide ?
  495. { start: pieceWidth * (1 - args.distance), end: pieceWidth } :
  496. { start: pieceWidth, end: pieceWidth * (1 - args.distance) } ;
  497. }else{
  498. properties.height = args.unhide ?
  499. { start: pieceHeight * (1 - args.distance), end: pieceHeight } :
  500. { start: pieceHeight, end: pieceHeight * (1 - args.distance) } ;
  501. }
  502. // Create the animation object for the piece
  503. var pieceAnimation = dojo.animateProperty({
  504. node: piece,
  505. duration: duration,
  506. delay: delay,
  507. easing: (args.easing || dojo.fx.easing.sinInOut),
  508. properties: properties,
  509. beforeBegin: (args.unhide ? function(){
  510. if(args.fade){
  511. dojo.style(piece, "opacity", 0);
  512. }
  513. if(colIsOdd){
  514. if(rowIsOdd){
  515. ps.top = (top + pieceHeight * (1 - args.distance)) + "px";
  516. }else{
  517. ps.left = (left + pieceWidth * (1 - args.distance)) + "px";
  518. }
  519. }else{
  520. ps.left = left + "px";
  521. ps.top = top + "px";
  522. }
  523. if(colIsOdd != rowIsOdd){
  524. ps.width = (pieceWidth * (1 - args.distance)) + "px";
  525. }else{
  526. ps.height = (pieceHeight * (1 - args.distance)) + "px";
  527. }
  528. } : undefined)
  529. });
  530. return pieceAnimation;
  531. };
  532. var anim = dojox.fx._split(args);
  533. if(args.unhide){
  534. dojo.connect(anim, "onEnd", anim, function(){
  535. dojo.style(node, { opacity: "1" });
  536. });
  537. }else{
  538. dojo.connect(anim, "play", anim, function(){
  539. dojo.style(node, { opacity: "0" });
  540. });
  541. }
  542. return anim; // dojo.Animation
  543. },
  544. unPinwheel: function(/*Object*/ args){
  545. args.unhide = true;
  546. return dojox.fx.pinwheel(args); // dojo.Animation
  547. },
  548. blockFadeOut: function(/*Object*/ args){
  549. // summary: Split a node into rectangular pieces and fade them
  550. //
  551. // description:
  552. // Returns an animation that will split the node into a grid
  553. // of pieces that fade in or out.
  554. //
  555. // args:
  556. // args.rows: Integer - The number of horizontal pieces (default is 5)
  557. // args.columns: Integer - The number of vertical pieces (default is 5)
  558. // args.interval: Float - The number of milliseconds between each piece's animation (default is 0)
  559. // args.random: Float - If true, pieces have a random delay. The value defines how much
  560. // randomness is introduced
  561. // args.reverseOrder: Boolean - If true, pieces animate in reversed order
  562. // args.unhide: Boolean - If true, the animation is reversed
  563. var node = args.node = dojo.byId(args.node);
  564. args.rows = args.rows || 5;
  565. args.columns = args.columns || 5;
  566. args.duration = args.duration || 1000;
  567. args.interval = args.interval || args.duration / (args.rows + args.columns * 2);
  568. args.random = args.random || 0;
  569. var random = Math.abs(args.random),
  570. duration = args.duration - (args.rows + args.columns) * args.interval
  571. ;
  572. // Returns the animation object for each piece
  573. args.pieceAnimation = function(piece, x, y, coords){
  574. var randomDelay = Math.random() * args.duration,
  575. uniformDelay = (args.reverseOrder) ?
  576. (((args.rows + args.columns) - (x + y)) * Math.abs(args.interval)) :
  577. ((x + y) * args.interval),
  578. delay = randomDelay * random + Math.max(1 - random, 0) * uniformDelay,
  579. // Create the animation object for the piece
  580. pieceAnimation = dojo.animateProperty({
  581. node: piece,
  582. duration: duration,
  583. delay: delay,
  584. easing: (args.easing || dojo.fx.easing.sinInOut),
  585. properties: {
  586. opacity: (args.unhide ? {start: "0", end: "1"} : {start: "1", end: "0"})
  587. },
  588. beforeBegin: (args.unhide ? function(){ dojo.style(piece, { opacity: "0" });} : function(){ piece.style.filter = ""; })
  589. });
  590. return pieceAnimation;
  591. };
  592. var anim = dojox.fx._split(args);
  593. if(args.unhide){
  594. dojo.connect(anim, "onEnd", anim, function(){
  595. dojo.style(node, { opacity: "1" });
  596. });
  597. }else{
  598. dojo.connect(anim, "onPlay", anim, function(){
  599. dojo.style(node, { opacity: "0" });
  600. });
  601. }
  602. return anim; // dojo.Animation
  603. },
  604. blockFadeIn: function(/*Object*/ args){
  605. args.unhide = true;
  606. return dojox.fx.blockFadeOut(args); // dojo.Animation
  607. }
  608. });
  609. }