Spotlight.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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. constructor: function(config){
  33. Ext.apply(this, config);
  34. },
  35. /**
  36. * Create all the elements for the spotlight
  37. */
  38. createElements: function() {
  39. var me = this,
  40. baseCls = me.baseCls,
  41. body = Ext.getBody();
  42. me.right = body.createChild({
  43. cls: baseCls
  44. });
  45. me.left = body.createChild({
  46. cls: baseCls
  47. });
  48. me.top = body.createChild({
  49. cls: baseCls
  50. });
  51. me.bottom = body.createChild({
  52. cls: baseCls
  53. });
  54. me.all = Ext.create('Ext.CompositeElement', [me.right, me.left, me.top, me.bottom]);
  55. },
  56. /**
  57. * Show the spotlight
  58. */
  59. show: function(el, callback, scope) {
  60. var me = this;
  61. //get the target element
  62. me.el = Ext.get(el);
  63. //create the elements if they don't already exist
  64. if (!me.right) {
  65. me.createElements();
  66. }
  67. if (!me.active) {
  68. //if the spotlight is not active, show it
  69. me.all.setDisplayed('');
  70. me.active = true;
  71. Ext.EventManager.onWindowResize(me.syncSize, me);
  72. me.applyBounds(me.animate, false);
  73. } else {
  74. //if the spotlight is currently active, just move it
  75. me.applyBounds(false, false);
  76. }
  77. },
  78. /**
  79. * Hide the spotlight
  80. */
  81. hide: function(callback, scope) {
  82. var me = this;
  83. Ext.EventManager.removeResizeListener(me.syncSize, me);
  84. me.applyBounds(me.animate, true);
  85. },
  86. /**
  87. * Resizes the spotlight with the window size.
  88. */
  89. syncSize: function() {
  90. this.applyBounds(false, false);
  91. },
  92. /**
  93. * Resizes the spotlight depending on the arguments
  94. * @param {Boolean} animate True to animate the changing of the bounds
  95. * @param {Boolean} reverse True to reverse the animation
  96. */
  97. applyBounds: function(animate, reverse) {
  98. var me = this,
  99. box = me.el.getBox(),
  100. //get the current view width and height
  101. viewWidth = Ext.Element.getViewWidth(true),
  102. viewHeight = Ext.Element.getViewHeight(true),
  103. i = 0,
  104. config = false,
  105. from, to, clone;
  106. //where the element should start (if animation)
  107. from = {
  108. right: {
  109. x: box.right,
  110. y: viewHeight,
  111. width: (viewWidth - box.right),
  112. height: 0
  113. },
  114. left: {
  115. x: 0,
  116. y: 0,
  117. width: box.x,
  118. height: 0
  119. },
  120. top: {
  121. x: viewWidth,
  122. y: 0,
  123. width: 0,
  124. height: box.y
  125. },
  126. bottom: {
  127. x: 0,
  128. y: (box.y + box.height),
  129. width: 0,
  130. height: (viewHeight - (box.y + box.height)) + 'px'
  131. }
  132. };
  133. //where the element needs to finish
  134. to = {
  135. right: {
  136. x: box.right,
  137. y: box.y,
  138. width: (viewWidth - box.right) + 'px',
  139. height: (viewHeight - box.y) + 'px'
  140. },
  141. left: {
  142. x: 0,
  143. y: 0,
  144. width: box.x + 'px',
  145. height: (box.y + box.height) + 'px'
  146. },
  147. top: {
  148. x: box.x,
  149. y: 0,
  150. width: (viewWidth - box.x) + 'px',
  151. height: box.y + 'px'
  152. },
  153. bottom: {
  154. x: 0,
  155. y: (box.y + box.height),
  156. width: (box.x + box.width) + 'px',
  157. height: (viewHeight - (box.y + box.height)) + 'px'
  158. }
  159. };
  160. //reverse the objects
  161. if (reverse) {
  162. clone = Ext.clone(from);
  163. from = to;
  164. to = clone;
  165. }
  166. if (animate) {
  167. Ext.Array.forEach(['right', 'left', 'top', 'bottom'], function(side) {
  168. me[side].setBox(from[side]);
  169. me[side].animate({
  170. duration: me.duration,
  171. easing: me.easing,
  172. to: to[side]
  173. });
  174. },
  175. this);
  176. } else {
  177. Ext.Array.forEach(['right', 'left', 'top', 'bottom'], function(side) {
  178. me[side].setBox(Ext.apply(from[side], to[side]));
  179. me[side].repaint();
  180. },
  181. this);
  182. }
  183. },
  184. /**
  185. * Removes all the elements for the spotlight
  186. */
  187. destroy: function() {
  188. var me = this;
  189. Ext.destroy(me.right, me.left, me.top, me.bottom);
  190. delete me.el;
  191. delete me.all;
  192. }
  193. });