Spotlight.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /**
  2. * @class Ext.ux.Spotlight
  3. * UX used to provide a spotlight around a specified component/element.
  4. */
  5. Ext.define('Ext.ux.Spotlight', {
  6. extend: 'Object',
  7. /**
  8. * @private
  9. * The baseCls for the spotlight elements
  10. */
  11. baseCls: 'x-spotlight',
  12. /**
  13. * @cfg animate {Boolean} True to animate the spotlight change
  14. * (defaults to true)
  15. */
  16. animate: true,
  17. /**
  18. * @cfg duration {Integer} The duration of the animation, in milliseconds
  19. * (defaults to 250)
  20. */
  21. duration: 250,
  22. /**
  23. * @cfg easing {String} The type of easing for the spotlight animatation
  24. * (defaults to null)
  25. */
  26. easing: null,
  27. /**
  28. * @private
  29. * True if the spotlight is active on the element
  30. */
  31. active: false,
  32. /**
  33. * Create all the elements for the spotlight
  34. */
  35. createElements: function() {
  36. var body = Ext.getBody();
  37. this.right = body.createChild({
  38. cls: this.baseCls
  39. });
  40. this.left = body.createChild({
  41. cls: this.baseCls
  42. });
  43. this.top = body.createChild({
  44. cls: this.baseCls
  45. });
  46. this.bottom = body.createChild({
  47. cls: this.baseCls
  48. });
  49. this.all = Ext.create('Ext.CompositeElement', [this.right, this.left, this.top, this.bottom]);
  50. },
  51. /**
  52. * Show the spotlight
  53. */
  54. show: function(el, callback, scope) {
  55. //get the target element
  56. this.el = Ext.get(el);
  57. //create the elements if they don't already exist
  58. if (!this.right) {
  59. this.createElements();
  60. }
  61. if (!this.active) {
  62. //if the spotlight is not active, show it
  63. this.all.setDisplayed('');
  64. this.active = true;
  65. Ext.EventManager.onWindowResize(this.syncSize, this);
  66. this.applyBounds(this.animate, false);
  67. } else {
  68. //if the spotlight is currently active, just move it
  69. this.applyBounds(false, false);
  70. }
  71. },
  72. /**
  73. * Hide the spotlight
  74. */
  75. hide: function(callback, scope) {
  76. Ext.EventManager.removeResizeListener(this.syncSize, this);
  77. this.applyBounds(this.animate, true);
  78. },
  79. /**
  80. * Resizes the spotlight with the window size.
  81. */
  82. syncSize: function() {
  83. this.applyBounds(false, false);
  84. },
  85. /**
  86. * Resizes the spotlight depending on the arguments
  87. * @param {Boolean} animate True to animate the changing of the bounds
  88. * @param {Boolean} animate True to reverse the animation
  89. */
  90. applyBounds: function(animate, reverse) {
  91. var me = this,
  92. box = me.el.getBox();
  93. //get the current view width and height
  94. var viewWidth = Ext.core.Element.getViewWidth(true);
  95. var viewHeight = Ext.core.Element.getViewHeight(true);
  96. var i = 0,
  97. config = false,
  98. from, to;
  99. //where the element should start (if animation)
  100. from = {
  101. right: {
  102. x: box.right,
  103. y: viewHeight,
  104. width: (viewWidth - box.right),
  105. height: 0
  106. },
  107. left: {
  108. x: 0,
  109. y: 0,
  110. width: box.x,
  111. height: 0
  112. },
  113. top: {
  114. x: viewWidth,
  115. y: 0,
  116. width: 0,
  117. height: box.y
  118. },
  119. bottom: {
  120. x: 0,
  121. y: (box.y + box.height),
  122. width: 0,
  123. height: (viewHeight - (box.y + box.height)) + 'px'
  124. }
  125. };
  126. //where the element needs to finish
  127. to = {
  128. right: {
  129. x: box.right,
  130. y: box.y,
  131. width: (viewWidth - box.right) + 'px',
  132. height: (viewHeight - box.y) + 'px'
  133. },
  134. left: {
  135. x: 0,
  136. y: 0,
  137. width: box.x + 'px',
  138. height: (box.y + box.height) + 'px'
  139. },
  140. top: {
  141. x: box.x,
  142. y: 0,
  143. width: (viewWidth - box.x) + 'px',
  144. height: box.y + 'px'
  145. },
  146. bottom: {
  147. x: 0,
  148. y: (box.y + box.height),
  149. width: (box.x + box.width) + 'px',
  150. height: (viewHeight - (box.y + box.height)) + 'px'
  151. }
  152. };
  153. //reverse the objects
  154. if (reverse) {
  155. var clone = Ext.clone(from);
  156. from = to;
  157. to = clone;
  158. delete clone;
  159. }
  160. if (animate) {
  161. Ext.each(['right', 'left', 'top', 'bottom'], function(side) {
  162. me[side].setBox(from[side]);
  163. me[side].animate({
  164. duration: me.duration,
  165. easing: me.easing,
  166. to: to[side]
  167. });
  168. },
  169. this);
  170. } else {
  171. Ext.each(['right', 'left', 'top', 'bottom'], function(side) {
  172. me[side].setBox(Ext.apply(from[side], to[side]));
  173. },
  174. this);
  175. }
  176. },
  177. /**
  178. * Removes all the elements for the spotlight
  179. */
  180. destroy: function() {
  181. Ext.destroy(this.right, this.left, this.top, this.bottom);
  182. delete this.el;
  183. delete this.all;
  184. }
  185. });