mxPanningManager.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /**
  2. * Copyright (c) 2006-2015, JGraph Ltd
  3. * Copyright (c) 2006-2015, Gaudenz Alder
  4. */
  5. /**
  6. * Class: mxPanningManager
  7. *
  8. * Implements a handler for panning.
  9. */
  10. function mxPanningManager(graph)
  11. {
  12. this.thread = null;
  13. this.active = false;
  14. this.tdx = 0;
  15. this.tdy = 0;
  16. this.t0x = 0;
  17. this.t0y = 0;
  18. this.dx = 0;
  19. this.dy = 0;
  20. this.scrollbars = false;
  21. this.scrollLeft = 0;
  22. this.scrollTop = 0;
  23. this.mouseListener =
  24. {
  25. mouseDown: function(sender, me) { },
  26. mouseMove: function(sender, me) { },
  27. mouseUp: mxUtils.bind(this, function(sender, me)
  28. {
  29. if (this.active)
  30. {
  31. this.stop();
  32. }
  33. })
  34. };
  35. graph.addMouseListener(this.mouseListener);
  36. this.mouseUpListener = mxUtils.bind(this, function()
  37. {
  38. if (this.active)
  39. {
  40. this.stop();
  41. }
  42. });
  43. // Stops scrolling on every mouseup anywhere in the document
  44. mxEvent.addListener(document, 'mouseup', this.mouseUpListener);
  45. var createThread = mxUtils.bind(this, function()
  46. {
  47. this.scrollbars = mxUtils.hasScrollbars(graph.container);
  48. this.scrollLeft = graph.container.scrollLeft;
  49. this.scrollTop = graph.container.scrollTop;
  50. return window.setInterval(mxUtils.bind(this, function()
  51. {
  52. this.tdx -= this.dx;
  53. this.tdy -= this.dy;
  54. if (this.scrollbars)
  55. {
  56. var left = -graph.container.scrollLeft - Math.ceil(this.dx);
  57. var top = -graph.container.scrollTop - Math.ceil(this.dy);
  58. graph.panGraph(left, top);
  59. graph.panDx = this.scrollLeft - graph.container.scrollLeft;
  60. graph.panDy = this.scrollTop - graph.container.scrollTop;
  61. graph.fireEvent(new mxEventObject(mxEvent.PAN));
  62. // TODO: Implement graph.autoExtend
  63. }
  64. else
  65. {
  66. graph.panGraph(this.getDx(), this.getDy());
  67. }
  68. }), this.delay);
  69. });
  70. this.isActive = function()
  71. {
  72. return active;
  73. };
  74. this.getDx = function()
  75. {
  76. return Math.round(this.tdx);
  77. };
  78. this.getDy = function()
  79. {
  80. return Math.round(this.tdy);
  81. };
  82. this.start = function()
  83. {
  84. this.t0x = graph.view.translate.x;
  85. this.t0y = graph.view.translate.y;
  86. this.active = true;
  87. };
  88. this.panTo = function(x, y, w, h)
  89. {
  90. if (!this.active)
  91. {
  92. this.start();
  93. }
  94. this.scrollLeft = graph.container.scrollLeft;
  95. this.scrollTop = graph.container.scrollTop;
  96. w = (w != null) ? w : 0;
  97. h = (h != null) ? h : 0;
  98. var c = graph.container;
  99. this.dx = x + w - c.scrollLeft - c.clientWidth;
  100. if (this.dx < 0 && Math.abs(this.dx) < this.border)
  101. {
  102. this.dx = this.border + this.dx;
  103. }
  104. else if (this.handleMouseOut)
  105. {
  106. this.dx = Math.max(this.dx, 0);
  107. }
  108. else
  109. {
  110. this.dx = 0;
  111. }
  112. if (this.dx == 0)
  113. {
  114. this.dx = x - c.scrollLeft;
  115. if (this.dx > 0 && this.dx < this.border)
  116. {
  117. this.dx = this.dx - this.border;
  118. }
  119. else if (this.handleMouseOut)
  120. {
  121. this.dx = Math.min(0, this.dx);
  122. }
  123. else
  124. {
  125. this.dx = 0;
  126. }
  127. }
  128. this.dy = y + h - c.scrollTop - c.clientHeight;
  129. if (this.dy < 0 && Math.abs(this.dy) < this.border)
  130. {
  131. this.dy = this.border + this.dy;
  132. }
  133. else if (this.handleMouseOut)
  134. {
  135. this.dy = Math.max(this.dy, 0);
  136. }
  137. else
  138. {
  139. this.dy = 0;
  140. }
  141. if (this.dy == 0)
  142. {
  143. this.dy = y - c.scrollTop;
  144. if (this.dy > 0 && this.dy < this.border)
  145. {
  146. this.dy = this.dy - this.border;
  147. }
  148. else if (this.handleMouseOut)
  149. {
  150. this.dy = Math.min(0, this.dy);
  151. }
  152. else
  153. {
  154. this.dy = 0;
  155. }
  156. }
  157. if (this.dx != 0 || this.dy != 0)
  158. {
  159. this.dx *= this.damper;
  160. this.dy *= this.damper;
  161. if (this.thread == null)
  162. {
  163. this.thread = createThread();
  164. }
  165. }
  166. else if (this.thread != null)
  167. {
  168. window.clearInterval(this.thread);
  169. this.thread = null;
  170. }
  171. };
  172. this.stop = function()
  173. {
  174. if (this.active)
  175. {
  176. this.active = false;
  177. if (this.thread != null)
  178. {
  179. window.clearInterval(this.thread);
  180. this.thread = null;
  181. }
  182. this.tdx = 0;
  183. this.tdy = 0;
  184. if (!this.scrollbars)
  185. {
  186. var px = graph.panDx;
  187. var py = graph.panDy;
  188. if (px != 0 || py != 0)
  189. {
  190. graph.panGraph(0, 0);
  191. graph.view.setTranslate(this.t0x + px / graph.view.scale, this.t0y + py / graph.view.scale);
  192. }
  193. }
  194. else
  195. {
  196. graph.panDx = 0;
  197. graph.panDy = 0;
  198. graph.fireEvent(new mxEventObject(mxEvent.PAN));
  199. }
  200. }
  201. };
  202. this.destroy = function()
  203. {
  204. graph.removeMouseListener(this.mouseListener);
  205. mxEvent.removeListener(document, 'mouseup', this.mouseUpListener);
  206. };
  207. };
  208. /**
  209. * Variable: damper
  210. *
  211. * Damper value for the panning. Default is 1/6.
  212. */
  213. mxPanningManager.prototype.damper = 1/6;
  214. /**
  215. * Variable: delay
  216. *
  217. * Delay in milliseconds for the panning. Default is 10.
  218. */
  219. mxPanningManager.prototype.delay = 10;
  220. /**
  221. * Variable: handleMouseOut
  222. *
  223. * Specifies if mouse events outside of the component should be handled. Default is true.
  224. */
  225. mxPanningManager.prototype.handleMouseOut = true;
  226. /**
  227. * Variable: border
  228. *
  229. * Border to handle automatic panning inside the component. Default is 0 (disabled).
  230. */
  231. mxPanningManager.prototype.border = 0;
  232. __mxOutput.mxPanningManager = typeof mxPanningManager !== 'undefined' ? mxPanningManager : undefined;