Roller.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. define("dojox/widget/Roller", ["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
  2. dojo.declare("dojox.widget.Roller", dijit._Widget, {
  3. // summary: A simple widget to take an unordered-list of Text and roll through them
  4. //
  5. // description:
  6. // The Roller widget takes an unordered-list of items, and converts
  7. // them to a single-area (the size of one list-item, however you so choose
  8. // to style it) and loops continually, fading between items.
  9. //
  10. // In it's current state, it requires it be created from an unordered (or ordered)
  11. // list, though can contain complex markup.
  12. //
  13. // You can manipulate the `items` array at any point during the cycle with
  14. // standard array manipulation techniques.
  15. //
  16. // The class "dojoxRoller" is added to the UL element for styling purposes.
  17. //
  18. // example:
  19. // | // create a scroller from a unordered list with id="lister"
  20. // | var thinger = new dojox.widget.Roller.Roller({},"lister");
  21. //
  22. // example:
  23. // | // create a scroller from a fixed array, and place in the DOM:
  24. // | new dojox.widget.Roller({ items:["one","two","three"] }).placeAt(dojo.body());
  25. //
  26. // example:
  27. // | // add an item:
  28. // | dijit.byId("roller").items.push("I am a new Label");
  29. //
  30. // example:
  31. // | // stop a roller from rolling:
  32. // | dijit.byId("roller").stop();
  33. //
  34. // delay: Integer
  35. // Interval between rolls
  36. delay: 2000,
  37. // autoStart: Boolean
  38. // Toggle to control starup behavior. Call .start() manually
  39. // if set to `false`
  40. autoStart: true,
  41. // itemSelector: String
  42. // A CSS selector to be used by `dojo.query` to find the children
  43. // items in this widget. Defaults to "> li", finding only first-children
  44. // list-items in the list, allowing for embedded lists to occur.
  45. itemSelector: "> li",
  46. // durationIn: Integer
  47. // Speed (in ms) to apply to the "in" animation (show the node)
  48. durationIn: 400,
  49. // durationOut: Integer
  50. // Speed (in ms) to apply to the "out" animation (hide the showing node)
  51. durationOut: 275,
  52. /*=====
  53. // items: Array
  54. // If populated prior to instantiation, is used as the Items over the children
  55. items: [],
  56. =====*/
  57. // _idx: Integer
  58. // Index of the the currently visible item in the list of items[]
  59. _idx: -1,
  60. postCreate: function(){
  61. // add some instance vars:
  62. if(!this["items"]){
  63. this.items = [];
  64. }
  65. dojo.addClass(this.domNode,"dojoxRoller");
  66. // find all the items in this list, and popuplate
  67. dojo.query(this.itemSelector, this.domNode).forEach(function(item, i){
  68. this.items.push(item.innerHTML);
  69. // reuse the first match, destroy the rest
  70. if(i == 0){
  71. this._roller = item;
  72. this._idx = 0;
  73. }else{ dojo.destroy(item); }
  74. }, this);
  75. // handle the case where items[] were passed, and no srcNodeRef exists
  76. if(!this._roller){
  77. this._roller = dojo.create('li', null, this.domNode);
  78. }
  79. // stub out animation creation (for overloading maybe later)
  80. this.makeAnims();
  81. // and start, if true:
  82. if(this.autoStart){ this.start(); }
  83. },
  84. makeAnims: function(){
  85. // summary: Animation creator function. Need to create an 'in' and 'out'
  86. // Animation stored in _anim Object, which the rest of the widget
  87. // will reuse.
  88. var n = this.domNode;
  89. dojo.mixin(this, {
  90. _anim: {
  91. "in": dojo.fadeIn({ node:n, duration: this.durationIn }),
  92. "out": dojo.fadeOut({ node:n, duration: this.durationOut })
  93. }
  94. });
  95. this._setupConnects();
  96. },
  97. _setupConnects: function(){
  98. // summary: setup the loop connection logic
  99. var anim = this._anim;
  100. this.connect(anim["out"], "onEnd", function(){
  101. // onEnd of the `out` animation, select the next items and play `in` animation
  102. this._setIndex(this._idx + 1);
  103. anim["in"].play(15);
  104. });
  105. this.connect(anim["in"], "onEnd", function(){
  106. // onEnd of the `in` animation, call `start` again after some delay:
  107. this._timeout = setTimeout(dojo.hitch(this, "_run"), this.delay);
  108. });
  109. },
  110. start: function(){
  111. // summary: Starts to Roller looping
  112. if(!this.rolling){
  113. this.rolling = true;
  114. this._run();
  115. }
  116. },
  117. _run: function(){
  118. this._anim["out"].gotoPercent(0, true);
  119. },
  120. stop: function(){
  121. // summary: Stops the Roller from looping anymore.
  122. this.rolling = false;
  123. var m = this._anim,
  124. t = this._timeout;
  125. if(t){ clearTimeout(t); }
  126. m["in"].stop();
  127. m["out"].stop();
  128. },
  129. _setIndex: function(i){
  130. // summary: Set the Roller to some passed index. If beyond range, go to first.
  131. var l = this.items.length - 1;
  132. if(i < 0){ i = l; }
  133. if(i > l){ i = 0; }
  134. this._roller.innerHTML = this.items[i] || "error!";
  135. this._idx = i;
  136. }
  137. });
  138. dojo.declare("dojox.widget.RollerSlide", dojox.widget.Roller, {
  139. // summary: An add-on to the Roller to modify animations. This produces
  140. // a slide-from-bottom like effect. See `dojox.widget.Roller` for
  141. // full API information.
  142. durationOut: 175, // slightly faster than default
  143. makeAnims: function(){
  144. // summary: Animation creator function. Need to create an 'in' and 'out'
  145. // Animation stored in _anim Object, which the rest of the widget
  146. // will reuse.
  147. var n = this.domNode, pos = "position",
  148. props = {
  149. top: { end: 0, start: 25 },
  150. opacity: 1
  151. }
  152. ;
  153. dojo.style(n, pos, "relative");
  154. dojo.style(this._roller, pos, "absolute");
  155. dojo.mixin(this, {
  156. _anim: {
  157. "in": dojo.animateProperty({
  158. node: n,
  159. duration: this.durationIn,
  160. properties: props
  161. }),
  162. "out": dojo.fadeOut({ node: n, duration: this.durationOut })
  163. }
  164. });
  165. // don't forget to do this in the class. override if necessary.
  166. this._setupConnects();
  167. }
  168. });
  169. dojo.declare("dojox.widget._RollerHover", null, {
  170. // summary: A mixin class to provide a way to automate the "stop on hover" functionality.
  171. //
  172. // description:
  173. // A mixin class used to provide a way to automate a "stop on hover" behavior,
  174. // while still allowing for ambigious subclassing for custom animations.
  175. // Simply mix this class into a `dojox.widget.Roller` variant, and instantiate
  176. // as you would. The hover connection is done automatically.
  177. //
  178. // The "hover" functionality is as such: Stop rotation while the mouse is over the
  179. // instance, and resume again once leaving. Even if autoStart is disabled, the widget
  180. // will start if a mouse enters and leaves the node in this case.
  181. //
  182. // example:
  183. // | dojo.declare("my.Roller", [dojox.widget.RollerSlide, dojox.widget._RollerHover], {});
  184. // | new my.Roller({}, "myList");
  185. postCreate: function(){
  186. this.inherited(arguments);
  187. this.connect(this.domNode, "onmouseenter", "stop");
  188. this.connect(this.domNode, "onmouseleave", "start");
  189. }
  190. });
  191. return dojox.widget.Roller;
  192. });