Spotlight.js 5.5 KB

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