Pan.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. // wrapped by build app
  2. define("dojox/drawing/plugins/tools/Pan", ["dijit","dojo","dojox","dojo/require!dojox/drawing/plugins/_Plugin"], function(dijit,dojo,dojox){
  3. dojo.provide("dojox.drawing.plugins.tools.Pan");
  4. dojo.require("dojox.drawing.plugins._Plugin");
  5. dojox.drawing.plugins.tools.Pan = dojox.drawing.util.oo.declare(
  6. // summary:
  7. // A plugin that allows for a scrolling canvas. An action
  8. // tool is added to the toolbar that allows for panning. Holding
  9. // the space bar is a shortcut to that action. The canvas will
  10. // only pan and scroll if there are objects out of the viewable
  11. // area.
  12. // example:
  13. // | <div dojoType="dojox.drawing.Toolbar" drawingId="drawingNode" class="drawingToolbar vertical">
  14. // | <div tool="dojox.drawing.tools.Line" selected="true">Line</div>
  15. // | <div plugin="dojox.drawing.plugins.tools.Pan" options="{}">Pan</div>
  16. // | </div>
  17. //
  18. dojox.drawing.plugins._Plugin,
  19. function(options){
  20. this.domNode = options.node;
  21. var _scrollTimeout;
  22. this.toolbar = options.scope;
  23. this.connect(this.toolbar, "onToolClick", this, function(){
  24. this.onSetPan(false)
  25. });
  26. this.connect(this.keys, "onKeyUp", this, "onKeyUp");
  27. this.connect(this.keys, "onKeyDown", this, "onKeyDown");
  28. this.connect(this.keys, "onArrow", this, "onArrow");
  29. this.connect(this.anchors, "onAnchorUp", this, "checkBounds");
  30. this.connect(this.stencils, "register", this, "checkBounds");
  31. this.connect(this.canvas, "resize", this, "checkBounds");
  32. this.connect(this.canvas, "setZoom", this, "checkBounds");
  33. this.connect(this.canvas, "onScroll", this, function(){
  34. if(this._blockScroll){
  35. this._blockScroll = false;
  36. return;
  37. }
  38. _scrollTimeout && clearTimeout(_scrollTimeout);
  39. _scrollTimeout = setTimeout(dojo.hitch(this, "checkBounds"), 200);
  40. });
  41. this._mouseHandle = this.mouse.register(this);
  42. // This HAS to be called after setting initial objects or things get screwy.
  43. //this.checkBounds();
  44. },{
  45. selected:false,
  46. keyScroll:false,
  47. type:"dojox.drawing.plugins.tools.Pan",
  48. onPanUp: function(obj){
  49. if(obj.id == this.button.id){
  50. this.onSetPan(false);
  51. }
  52. },
  53. onKeyUp: function(evt){
  54. switch(evt.keyCode){
  55. case 32:
  56. this.onSetPan(false);
  57. break;
  58. case 39: case 37: case 38: case 40:
  59. clearInterval(this._timer);
  60. break;
  61. }
  62. },
  63. onKeyDown: function(evt){
  64. if(evt.keyCode == 32){
  65. this.onSetPan(true);
  66. }
  67. },
  68. interval: 20,
  69. onArrow: function(evt){
  70. if(this._timer){ clearInterval(this._timer); }
  71. this._timer = setInterval(dojo.hitch(this,function(evt){
  72. this.canvas.domNode.parentNode.scrollLeft += evt.x*10;
  73. this.canvas.domNode.parentNode.scrollTop += evt.y*10;
  74. },evt), this.interval);
  75. },
  76. onSetPan: function(/*Boolean | Event*/ bool){
  77. if(bool === true || bool === false){
  78. this.selected = !bool;
  79. }
  80. console.log('ON SET PAN:', this.selected)
  81. if(this.selected){
  82. this.selected = false;
  83. this.button.deselect();
  84. }else{
  85. this.selected = true;
  86. this.button.select();
  87. }
  88. this.mouse.setEventMode(this.selected ? "pan" : "");
  89. },
  90. onPanDrag: function(obj){
  91. var x = obj.x - obj.last.x;
  92. var y = obj.y - obj.last.y;
  93. this.canvas.domNode.parentNode.scrollTop -= obj.move.y;
  94. this.canvas.domNode.parentNode.scrollLeft -= obj.move.x;
  95. this.canvas.onScroll();
  96. },
  97. onUp: function(obj){
  98. if(obj.withinCanvas){
  99. this.keyScroll = true;
  100. }else{
  101. this.keyScroll = false;
  102. }
  103. },
  104. onStencilUp: function(obj){
  105. // this gets called even on click-off because of the
  106. // issues with TextBlock deselection
  107. this.checkBounds();
  108. },
  109. onStencilDrag: function(obj){
  110. // this gets called even on click-off because of the
  111. // issues with TextBlock deselection
  112. //this.checkBounds();
  113. },
  114. checkBounds: function(){
  115. //watch("CHECK BOUNDS DISABLED", true); return;
  116. // summary:
  117. // Scans all items on the canvas and checks if they are out of
  118. // bounds. If so, a scroll bar (in Canvas) is shown. If the position
  119. // is left or top, the canvas is scrolled all items are relocated
  120. // the distance of the scroll. Ideally, it should look as if the
  121. // items do not move.
  122. // logging stuff here so it can be turned on and off. This method is
  123. // very high maintenance.
  124. var log = function(){
  125. //console.log.apply(console, arguments);
  126. }
  127. var warn = function(){
  128. //console.warn.apply(console, arguments);
  129. }
  130. //console.clear();
  131. //console.time("check bounds");
  132. // initialize a shot-tin of vars
  133. var t=Infinity, r=-Infinity, b=-10000, l=10000,
  134. sx=0, sy=0, dy=0, dx=0,
  135. mx = this.stencils.group ? this.stencils.group.getTransform() : {dx:0, dy:0},
  136. sc = this.mouse.scrollOffset(),
  137. // scY, scX: the scrollbar creates the need for extra dimension
  138. scY = sc.left ? 10 : 0,
  139. scX = sc.top ? 10 : 0,
  140. // ch, cw: the current size of the canvas
  141. ch = this.canvas.height,
  142. cw = this.canvas.width,
  143. z = this.canvas.zoom,
  144. // pch, pcw: the normal size of the canvas (not scrolled)
  145. // these could change if the container resizes.
  146. pch = this.canvas.parentHeight,
  147. pcw = this.canvas.parentWidth;
  148. this.stencils.withSelected(function(m){
  149. var o = m.getBounds();
  150. warn("SEL BOUNDS:", o);
  151. t = Math.min(o.y1 + mx.dy, t);
  152. r = Math.max(o.x2 + mx.dx, r);
  153. b = Math.max(o.y2 + mx.dy, b);
  154. l = Math.min(o.x1 + mx.dx, l);
  155. });
  156. this.stencils.withUnselected(function(m){
  157. var o = m.getBounds();
  158. warn("UN BOUNDS:", o);
  159. t = Math.min(o.y1, t);
  160. r = Math.max(o.x2, r);
  161. b = Math.max(o.y2, b);
  162. l = Math.min(o.x1, l);
  163. log("----------- B:", b, o.y2)
  164. });
  165. b *= z;
  166. var xscroll = 0, yscroll = 0;
  167. log("Bottom test", "b:", b, "z:", z, "ch:", ch, "pch:", pch, "top:", sc.top, "sy:", sy, "mx.dy:", mx.dy);
  168. if(b > pch || sc.top ){
  169. log("*bottom scroll*");
  170. // item off bottom
  171. ch = Math.max(b, pch + sc.top);
  172. sy = sc.top;
  173. xscroll += this.canvas.getScrollWidth();
  174. }else if(!sy && ch>pch){
  175. log("*bottom remove*");
  176. // item moved from bottom
  177. ch = pch;
  178. }
  179. r *= z;
  180. if(r > pcw || sc.left){
  181. //log("*right scroll*");
  182. // item off right
  183. cw = Math.max(r, pcw + sc.left);
  184. sx = sc.left;
  185. yscroll += this.canvas.getScrollWidth();
  186. }else if(!sx && cw>pcw){
  187. //log("*right remove*");
  188. // item moved from right
  189. cw = pcw;
  190. }
  191. // add extra space for scrollbars
  192. // double it to give some breathing room
  193. cw += xscroll*2;
  194. ch += yscroll*2;
  195. this._blockScroll = true;
  196. // selected items are not transformed. The selection itself is
  197. // and the items are on de-select
  198. this.stencils.group && this.stencils.group.applyTransform({dx:dx, dy:dy});
  199. // non-selected items are transformed
  200. this.stencils.withUnselected(function(m){
  201. m.transformPoints({dx:dx, dy:dy});
  202. });
  203. this.canvas.setDimensions(cw, ch, sx, sy);
  204. //console.timeEnd("check bounds");
  205. }
  206. }
  207. );
  208. dojox.drawing.plugins.tools.Pan.setup = {
  209. name:"dojox.drawing.plugins.tools.Pan",
  210. tooltip:"Pan Tool",
  211. iconClass:"iconPan",
  212. button:false
  213. };
  214. dojox.drawing.register(dojox.drawing.plugins.tools.Pan.setup, "plugin");
  215. });