Badge.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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.image.Badge"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.image.Badge"] = true;
  8. dojo.provide("dojox.image.Badge");
  9. dojo.experimental("dojox.image.Badge");
  10. dojo.require("dijit._Widget");
  11. dojo.require("dijit._Templated");
  12. dojo.require("dojo.fx.easing");
  13. dojo.declare("dojox.image.Badge", [dijit._Widget, dijit._Templated], {
  14. // summary: A simple grid of Images that loops through thumbnails
  15. //
  16. baseClass: "dojoxBadge",
  17. templateString:'<div class="dojoxBadge" dojoAttachPoint="containerNode"></div>',
  18. // children: String
  19. // A CSS3 Selector that determines the node to become a child
  20. children: "div.dojoxBadgeImage",
  21. // rows: Integer
  22. // Number of Rows to display
  23. rows: 4,
  24. // cols: Integer
  25. // Number of Columns to display
  26. cols: 5,
  27. // cellSize: Integer
  28. // Size in PX of each thumbnail
  29. cellSize: 50,
  30. // cellMargin: Integer
  31. // Size in PX to adjust for cell margins
  32. cellMargin: 1,
  33. // delay: Integer
  34. // Time (in ms) to show the image before sizing down again
  35. delay: 2000,
  36. // threads: Integer
  37. // how many cycles will be going "simultaneously" (>2 not reccommended)
  38. threads: 1,
  39. // easing: Function|String
  40. // An easing function to use when showing the node (does not apply to shrinking)
  41. easing: "dojo.fx.easing.backOut",
  42. startup: function(){
  43. if(this._started){ return; }
  44. if(dojo.isString(this.easing)){
  45. this.easing = dojo.getObject(this.easing);
  46. }
  47. this.inherited(arguments);
  48. this._init();
  49. },
  50. _init: function(){
  51. // summary: Setup and layout the images
  52. var _row = 0,
  53. _w = this.cellSize;
  54. dojo.style(this.domNode, {
  55. width: _w * this.cols + "px",
  56. height: _w * this.rows + "px"
  57. });
  58. this._nl = dojo.query(this.children, this.containerNode)
  59. .forEach(function(n, _idx){
  60. var _col = _idx % this.cols,
  61. t = _row * _w,
  62. l = _col * _w,
  63. m = this.cellMargin * 2;
  64. dojo.style(n, {
  65. top: t + "px",
  66. left: l + "px",
  67. width: _w - m + "px",
  68. height: _w - m + "px"
  69. });
  70. if(_col == this.cols - 1){ _row++; }
  71. dojo.addClass(n, this.baseClass + "Image");
  72. }, this)
  73. ;
  74. var l = this._nl.length;
  75. while(this.threads--){
  76. var s = Math.floor(Math.random() * l);
  77. setTimeout(dojo.hitch(this, "_enbiggen", {
  78. target: this._nl[s]
  79. }), this.delay * this.threads);
  80. }
  81. },
  82. _getCell: function(/* DomNode */ n){
  83. // summary: Return information about the position for a given node
  84. var _pos = this._nl.indexOf(n);
  85. if(_pos >= 0){
  86. var _col = _pos % this.cols;
  87. var _row = Math.floor(_pos / this.cols);
  88. return { x: _col, y: _row, n: this._nl[_pos], io: _pos };
  89. }else{
  90. return undefined;
  91. }
  92. },
  93. _getImage: function(){
  94. // summary: Returns the next image in the list, or the first one if not available
  95. return "url('')";
  96. },
  97. _enbiggen: function(/* Event|DomNode */ e){
  98. // summary: Show the passed node in the picker
  99. var _pos = this._getCell(e.target || e);
  100. if (_pos){
  101. // we have a node, and know where it is
  102. var m = this.cellMargin,
  103. _cc = (this.cellSize * 2) - (m * 2),
  104. props = {
  105. height: _cc,
  106. width: _cc
  107. }
  108. ;
  109. var _tehDecider = function(){
  110. // if we have room, we'll want to decide which direction to go
  111. // let "teh decider" decide.
  112. return Math.round(Math.random());
  113. };
  114. if(_pos.x == this.cols - 1 || (_pos.x > 0 && _tehDecider() )){
  115. // we have to go left, at right edge (or we want to and not on left edge)
  116. props.left = this.cellSize * (_pos.x - m);
  117. }
  118. if(_pos.y == this.rows - 1 || (_pos.y > 0 && _tehDecider() )){
  119. // we have to go up, at bottom edge (or we want to and not at top)
  120. props.top = this.cellSize * (_pos.y - m);
  121. }
  122. var bc = this.baseClass;
  123. dojo.addClass(_pos.n, bc + "Top");
  124. dojo.addClass(_pos.n, bc + "Seen");
  125. dojo.animateProperty({ node: _pos.n, properties: props,
  126. onEnd: dojo.hitch(this, "_loadUnder", _pos, props),
  127. easing: this.easing
  128. }).play();
  129. }
  130. },
  131. _loadUnder: function(info, props){
  132. // summary: figure out which three images are being covered, and
  133. // determine if they need loaded or not
  134. var idx = info.io;
  135. var nodes = [];
  136. var isLeft = (props.left >= 0);
  137. var isUp = (props.top >= 0);
  138. var c = this.cols,
  139. // the three node index's we're allegedly over:
  140. e = idx + (isLeft ? -1 : 1),
  141. f = idx + (isUp ? -c : c),
  142. // don't ask:
  143. g = (isUp ? (isLeft ? e - c : f + 1) : (isLeft ? f - 1 : e + c)),
  144. bc = this.baseClass;
  145. dojo.forEach([e, f, g], function(x){
  146. var n = this._nl[x];
  147. if(n){
  148. if(dojo.hasClass(n, bc + "Seen")){
  149. // change the background image out?
  150. dojo.removeClass(n, bc + "Seen");
  151. }
  152. }
  153. },this);
  154. setTimeout(dojo.hitch(this, "_disenbiggen", info, props), this.delay * 1.25);
  155. },
  156. _disenbiggen: function(info, props){
  157. // summary: Hide the passed node (info.n), passing along properties
  158. // received.
  159. if(props.top >= 0){
  160. props.top += this.cellSize;
  161. }
  162. if(props.left >= 0){
  163. props.left += this.cellSize;
  164. }
  165. var _cc = this.cellSize - (this.cellMargin * 2);
  166. dojo.animateProperty({
  167. node: info.n,
  168. properties: dojo.mixin(props, {
  169. width:_cc,
  170. height:_cc
  171. }),
  172. onEnd: dojo.hitch(this, "_cycle", info, props)
  173. }).play(5);
  174. },
  175. _cycle: function(info, props){
  176. // summary: Select an un-viewed image from the list, and show it
  177. var bc = this.baseClass;
  178. dojo.removeClass(info.n, bc + "Top");
  179. var ns = this._nl.filter(function(n){
  180. return !dojo.hasClass(n, bc + "Seen")
  181. });
  182. var c = ns[Math.floor(Math.random() * ns.length)];
  183. setTimeout(dojo.hitch(this,"_enbiggen", { target: c }), this.delay / 2)
  184. }
  185. });
  186. }