Path.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.drawing.tools.Path"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.drawing.tools.Path"] = true;
  8. dojo.provide("dojox.drawing.tools.Path");
  9. dojox.drawing.tools.Path = dojox.drawing.util.oo.declare(
  10. // summary:
  11. // Class for a drawable Path
  12. //
  13. dojox.drawing.stencil.Path,
  14. function(){
  15. // summary: constructor
  16. this.pathMode = "";
  17. this.currentPathMode = "";
  18. this._started = false;
  19. this.oddEvenClicks = 0;
  20. },
  21. {
  22. draws:true,
  23. onDown: function(obj){
  24. if(!this._started){
  25. this.onStartPath(obj);
  26. }
  27. },
  28. makeSubPath: function(_closePath){
  29. if(_closePath){
  30. if(this.currentPathMode=="Q"){
  31. this.points.push({
  32. x:this.points[0].x,
  33. y:this.points[0].y
  34. });
  35. }
  36. this.points.push({t:"Z"});
  37. this.render();
  38. }
  39. this.currentPathMode = "";
  40. this.pathMode = "M";
  41. },
  42. onStartPath: function(obj){
  43. this._started = true;
  44. this.revertRenderHit = this.renderHit;
  45. this.renderHit = false;
  46. this.closePath = false;
  47. this.mouse.setEventMode("PathEdit");
  48. this.closePoint = {x:obj.x, y:obj.y};
  49. this._kc1 = this.connect(this.keys, "onEsc", this, function(){
  50. this.onCompletePath(false);
  51. });
  52. this._kc2 = this.connect(this.keys, "onKeyUp", this, function(evt){
  53. switch(evt.letter){
  54. case "c":
  55. this.onCompletePath(true); break;
  56. case "l": this.pathMode = "L"; break;
  57. case "m": this.makeSubPath(false); break;
  58. case "q": this.pathMode = "Q"; break;
  59. case "s": this.pathMode = "S"; break;
  60. case "z": this.makeSubPath(true); break;
  61. }
  62. //console.log("KEY:", evt.letter);
  63. });
  64. },
  65. onCompletePath:function(_closePath){
  66. this.remove(this.closeGuide, this.guide);
  67. var box = this.getBounds();
  68. if(box.w<this.minimumSize && box.h<this.minimumSize){
  69. this.remove(this.hit, this.shape, this.closeGuide);
  70. this._started = false;
  71. this.mouse.setEventMode("");
  72. this.setPoints([]);
  73. return;
  74. }
  75. if(_closePath){
  76. if(this.currentPathMode=="Q"){
  77. this.points.push({
  78. x:this.points[0].x,
  79. y:this.points[0].y
  80. });
  81. }
  82. this.closePath = true;
  83. }
  84. this.renderHit = this.revertRenderHit;
  85. this.renderedOnce = true;
  86. this.onRender(this);
  87. this.disconnect([this._kc1, this._kc2]);
  88. this.mouse.setEventMode("");
  89. this.render();
  90. //console.log(this.stringPath);
  91. },
  92. onUp: function(/*EventObject*/obj){
  93. //console.log(" Path UP", obj.mid, "within:", obj.withinCanvas)
  94. if(!this._started || !obj.withinCanvas){ return; }
  95. if(this.points.length>2 && this.closeRadius>this.util.distance(obj.x, obj.y, this.closePoint.x, this.closePoint.y)){
  96. this.onCompletePath(true);
  97. }else {
  98. var p = {
  99. x:obj.x,
  100. y:obj.y
  101. };
  102. this.oddEvenClicks++;
  103. if(this.currentPathMode != this.pathMode){
  104. if(this.pathMode=="Q"){
  105. p.t = "Q";
  106. this.oddEvenClicks = 0;
  107. }else if(this.pathMode=="L"){
  108. p.t = "L";
  109. }else if(this.pathMode=="M"){
  110. p.t = "M";
  111. this.closePoint = {x:obj.x, y:obj.y};
  112. }
  113. this.currentPathMode = this.pathMode;
  114. }
  115. this.points.push(p);
  116. if(this.points.length>1){
  117. this.remove(this.guide);
  118. this.render();
  119. }
  120. }
  121. //console.log(this.stringPath);
  122. },
  123. createGuide: function(obj){
  124. if(!this.points.length){ return; }
  125. var realPoints = [].concat(this.points);
  126. var pt = {
  127. x:obj.x,
  128. y:obj.y
  129. };
  130. if(this.currentPathMode=="Q" && this.oddEvenClicks % 2){
  131. // On a Q curve, every other click needs to be a
  132. // straight line - the inbetween Q coords don't render
  133. pt.t = "L"; // this is not permanent
  134. }
  135. this.points.push(pt);
  136. this.render();
  137. this.points = realPoints;
  138. var dist = this.util.distance(obj.x, obj.y, this.closePoint.x, this.closePoint.y);
  139. if(this.points.length>1){
  140. if(dist<this.closeRadius && !this.closeGuide){
  141. var c = {
  142. cx:this.closePoint.x,
  143. cy:this.closePoint.y,
  144. rx:this.closeRadius,
  145. ry:this.closeRadius
  146. }
  147. this.closeGuide = this.container.createEllipse(c)
  148. .setFill(this.closeColor);
  149. }else if(dist>this.closeRadius && this.closeGuide){
  150. this.remove(this.closeGuide);
  151. this.closeGuide = null;
  152. }
  153. }
  154. },
  155. onMove: function(obj){
  156. if(!this._started){ return; }
  157. this.createGuide(obj);
  158. },
  159. onDrag: function(obj){
  160. if(!this._started){ return; }
  161. this.createGuide(obj);
  162. }
  163. }
  164. );
  165. dojox.drawing.tools.Path.setup = {
  166. // summary: See Base ToolsSetup
  167. //
  168. name:"dojox.drawing.tools.Path",
  169. tooltip:"Path Tool",
  170. iconClass:"iconLine"
  171. };
  172. dojox.drawing.register(dojox.drawing.tools.Path.setup, "tool");
  173. }