ResizeTracker.html 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-resizer-ResizeTracker'>/**
  19. </span> * Private utility class for Ext.resizer.Resizer.
  20. * @private
  21. */
  22. Ext.define('Ext.resizer.ResizeTracker', {
  23. extend: 'Ext.dd.DragTracker',
  24. dynamic: true,
  25. preserveRatio: false,
  26. // Default to no constraint
  27. constrainTo: null,
  28. proxyCls: Ext.baseCSSPrefix + 'resizable-proxy',
  29. constructor: function(config) {
  30. var me = this,
  31. widthRatio, heightRatio,
  32. throttledResizeFn;
  33. if (!config.el) {
  34. if (config.target.isComponent) {
  35. me.el = config.target.getEl();
  36. } else {
  37. me.el = config.target;
  38. }
  39. }
  40. this.callParent(arguments);
  41. // Ensure that if we are preserving aspect ratio, the largest minimum is honoured
  42. if (me.preserveRatio &amp;&amp; me.minWidth &amp;&amp; me.minHeight) {
  43. widthRatio = me.minWidth / me.el.getWidth();
  44. heightRatio = me.minHeight / me.el.getHeight();
  45. // largest ratio of minimum:size must be preserved.
  46. // So if a 400x200 pixel image has
  47. // minWidth: 50, maxWidth: 50, the maxWidth will be 400 * (50/200)... that is 100
  48. if (heightRatio &gt; widthRatio) {
  49. me.minWidth = me.el.getWidth() * heightRatio;
  50. } else {
  51. me.minHeight = me.el.getHeight() * widthRatio;
  52. }
  53. }
  54. // If configured as throttled, create an instance version of resize which calls
  55. // a throttled function to perform the resize operation.
  56. if (me.throttle) {
  57. throttledResizeFn = Ext.Function.createThrottled(function() {
  58. Ext.resizer.ResizeTracker.prototype.resize.apply(me, arguments);
  59. }, me.throttle);
  60. me.resize = function(box, direction, atEnd) {
  61. if (atEnd) {
  62. Ext.resizer.ResizeTracker.prototype.resize.apply(me, arguments);
  63. } else {
  64. throttledResizeFn.apply(null, arguments);
  65. }
  66. };
  67. }
  68. },
  69. onBeforeStart: function(e) {
  70. // record the startBox
  71. this.startBox = this.el.getBox();
  72. },
  73. <span id='Ext-resizer-ResizeTracker-method-getDynamicTarget'> /**
  74. </span> * @private
  75. * Returns the object that will be resized on every mousemove event.
  76. * If dynamic is false, this will be a proxy, otherwise it will be our actual target.
  77. */
  78. getDynamicTarget: function() {
  79. var me = this,
  80. target = me.target;
  81. if (me.dynamic) {
  82. return target;
  83. } else if (!me.proxy) {
  84. me.proxy = me.createProxy(target);
  85. }
  86. me.proxy.show();
  87. return me.proxy;
  88. },
  89. <span id='Ext-resizer-ResizeTracker-method-createProxy'> /**
  90. </span> * Create a proxy for this resizer
  91. * @param {Ext.Component/Ext.Element} target The target
  92. * @return {Ext.Element} A proxy element
  93. */
  94. createProxy: function(target){
  95. var proxy,
  96. cls = this.proxyCls,
  97. renderTo;
  98. if (target.isComponent) {
  99. proxy = target.getProxy().addCls(cls);
  100. } else {
  101. renderTo = Ext.getBody();
  102. if (Ext.scopeResetCSS) {
  103. renderTo = Ext.getBody().createChild({
  104. cls: Ext.resetCls
  105. });
  106. }
  107. proxy = target.createProxy({
  108. tag: 'div',
  109. cls: cls,
  110. id: target.id + '-rzproxy'
  111. }, renderTo);
  112. }
  113. proxy.removeCls(Ext.baseCSSPrefix + 'proxy-el');
  114. return proxy;
  115. },
  116. onStart: function(e) {
  117. // returns the Ext.ResizeHandle that the user started dragging
  118. this.activeResizeHandle = Ext.get(this.getDragTarget().id);
  119. // If we are using a proxy, ensure it is sized.
  120. if (!this.dynamic) {
  121. this.resize(this.startBox, {
  122. horizontal: 'none',
  123. vertical: 'none'
  124. });
  125. }
  126. },
  127. onDrag: function(e) {
  128. // dynamic resizing, update dimensions during resize
  129. if (this.dynamic || this.proxy) {
  130. this.updateDimensions(e);
  131. }
  132. },
  133. updateDimensions: function(e, atEnd) {
  134. var me = this,
  135. region = me.activeResizeHandle.region,
  136. offset = me.getOffset(me.constrainTo ? 'dragTarget' : null),
  137. box = me.startBox,
  138. ratio,
  139. widthAdjust = 0,
  140. heightAdjust = 0,
  141. snappedWidth,
  142. snappedHeight,
  143. adjustX = 0,
  144. adjustY = 0,
  145. dragRatio,
  146. horizDir = offset[0] &lt; 0 ? 'right' : 'left',
  147. vertDir = offset[1] &lt; 0 ? 'down' : 'up',
  148. oppositeCorner,
  149. axis, // 1 = x, 2 = y, 3 = x and y.
  150. newBox,
  151. newHeight, newWidth;
  152. switch (region) {
  153. case 'south':
  154. heightAdjust = offset[1];
  155. axis = 2;
  156. break;
  157. case 'north':
  158. heightAdjust = -offset[1];
  159. adjustY = -heightAdjust;
  160. axis = 2;
  161. break;
  162. case 'east':
  163. widthAdjust = offset[0];
  164. axis = 1;
  165. break;
  166. case 'west':
  167. widthAdjust = -offset[0];
  168. adjustX = -widthAdjust;
  169. axis = 1;
  170. break;
  171. case 'northeast':
  172. heightAdjust = -offset[1];
  173. adjustY = -heightAdjust;
  174. widthAdjust = offset[0];
  175. oppositeCorner = [box.x, box.y + box.height];
  176. axis = 3;
  177. break;
  178. case 'southeast':
  179. heightAdjust = offset[1];
  180. widthAdjust = offset[0];
  181. oppositeCorner = [box.x, box.y];
  182. axis = 3;
  183. break;
  184. case 'southwest':
  185. widthAdjust = -offset[0];
  186. adjustX = -widthAdjust;
  187. heightAdjust = offset[1];
  188. oppositeCorner = [box.x + box.width, box.y];
  189. axis = 3;
  190. break;
  191. case 'northwest':
  192. heightAdjust = -offset[1];
  193. adjustY = -heightAdjust;
  194. widthAdjust = -offset[0];
  195. adjustX = -widthAdjust;
  196. oppositeCorner = [box.x + box.width, box.y + box.height];
  197. axis = 3;
  198. break;
  199. }
  200. newBox = {
  201. width: box.width + widthAdjust,
  202. height: box.height + heightAdjust,
  203. x: box.x + adjustX,
  204. y: box.y + adjustY
  205. };
  206. // Snap value between stops according to configured increments
  207. snappedWidth = Ext.Number.snap(newBox.width, me.widthIncrement);
  208. snappedHeight = Ext.Number.snap(newBox.height, me.heightIncrement);
  209. if (snappedWidth != newBox.width || snappedHeight != newBox.height){
  210. switch (region) {
  211. case 'northeast':
  212. newBox.y -= snappedHeight - newBox.height;
  213. break;
  214. case 'north':
  215. newBox.y -= snappedHeight - newBox.height;
  216. break;
  217. case 'southwest':
  218. newBox.x -= snappedWidth - newBox.width;
  219. break;
  220. case 'west':
  221. newBox.x -= snappedWidth - newBox.width;
  222. break;
  223. case 'northwest':
  224. newBox.x -= snappedWidth - newBox.width;
  225. newBox.y -= snappedHeight - newBox.height;
  226. }
  227. newBox.width = snappedWidth;
  228. newBox.height = snappedHeight;
  229. }
  230. // out of bounds
  231. if (newBox.width &lt; me.minWidth || newBox.width &gt; me.maxWidth) {
  232. newBox.width = Ext.Number.constrain(newBox.width, me.minWidth, me.maxWidth);
  233. // Re-adjust the X position if we were dragging the west side
  234. if (adjustX) {
  235. newBox.x = box.x + (box.width - newBox.width);
  236. }
  237. } else {
  238. me.lastX = newBox.x;
  239. }
  240. if (newBox.height &lt; me.minHeight || newBox.height &gt; me.maxHeight) {
  241. newBox.height = Ext.Number.constrain(newBox.height, me.minHeight, me.maxHeight);
  242. // Re-adjust the Y position if we were dragging the north side
  243. if (adjustY) {
  244. newBox.y = box.y + (box.height - newBox.height);
  245. }
  246. } else {
  247. me.lastY = newBox.y;
  248. }
  249. // If this is configured to preserve the aspect ratio, or they are dragging using the shift key
  250. if (me.preserveRatio || e.shiftKey) {
  251. ratio = me.startBox.width / me.startBox.height;
  252. // Calculate aspect ratio constrained values.
  253. newHeight = Math.min(Math.max(me.minHeight, newBox.width / ratio), me.maxHeight);
  254. newWidth = Math.min(Math.max(me.minWidth, newBox.height * ratio), me.maxWidth);
  255. // X axis: width-only change, height must obey
  256. if (axis == 1) {
  257. newBox.height = newHeight;
  258. }
  259. // Y axis: height-only change, width must obey
  260. else if (axis == 2) {
  261. newBox.width = newWidth;
  262. }
  263. // Corner drag.
  264. else {
  265. // Drag ratio is the ratio of the mouse point from the opposite corner.
  266. // Basically what edge we are dragging, a horizontal edge or a vertical edge.
  267. dragRatio = Math.abs(oppositeCorner[0] - this.lastXY[0]) / Math.abs(oppositeCorner[1] - this.lastXY[1]);
  268. // If drag ratio &gt; aspect ratio then width is dominant and height must obey
  269. if (dragRatio &gt; ratio) {
  270. newBox.height = newHeight;
  271. } else {
  272. newBox.width = newWidth;
  273. }
  274. // Handle dragging start coordinates
  275. if (region == 'northeast') {
  276. newBox.y = box.y - (newBox.height - box.height);
  277. } else if (region == 'northwest') {
  278. newBox.y = box.y - (newBox.height - box.height);
  279. newBox.x = box.x - (newBox.width - box.width);
  280. } else if (region == 'southwest') {
  281. newBox.x = box.x - (newBox.width - box.width);
  282. }
  283. }
  284. }
  285. if (heightAdjust === 0) {
  286. vertDir = 'none';
  287. }
  288. if (widthAdjust === 0) {
  289. horizDir = 'none';
  290. }
  291. me.resize(newBox, {
  292. horizontal: horizDir,
  293. vertical: vertDir
  294. }, atEnd);
  295. },
  296. getResizeTarget: function(atEnd) {
  297. return atEnd ? this.target : this.getDynamicTarget();
  298. },
  299. resize: function(box, direction, atEnd) {
  300. var target = this.getResizeTarget(atEnd);
  301. if (target.isComponent) {
  302. target.setSize(box.width, box.height);
  303. if (target.floating) {
  304. target.setPagePosition(box.x, box.y);
  305. }
  306. } else {
  307. target.setBox(box);
  308. }
  309. // update the originalTarget if it was wrapped, and the target passed in was the wrap el.
  310. target = this.originalTarget;
  311. if (target &amp;&amp; (this.dynamic || atEnd)) {
  312. if (target.isComponent) {
  313. target.setSize(box.width, box.height);
  314. if (target.floating) {
  315. target.setPagePosition(box.x, box.y);
  316. }
  317. } else {
  318. target.setBox(box);
  319. }
  320. }
  321. },
  322. onEnd: function(e) {
  323. this.updateDimensions(e, true);
  324. if (this.proxy) {
  325. this.proxy.hide();
  326. }
  327. }
  328. });
  329. </pre>
  330. </body>
  331. </html>