Roller.js 6.8 KB

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