split.js 22 KB

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