Path.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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.stencil.Path"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.drawing.stencil.Path"] = true;
  8. dojo.provide("dojox.drawing.stencil.Path");
  9. dojox.drawing.stencil.Path = dojox.drawing.util.oo.declare(
  10. // summary:
  11. // Creates a dojox.gfx Path based on points provided.
  12. //
  13. dojox.drawing.stencil._Base,
  14. function(options){
  15. dojo.disconnect(this._postRenderCon);
  16. },
  17. {
  18. type:"dojox.drawing.stencil.Path",
  19. closePath: true,
  20. baseRender:true,
  21. closeRadius:10,
  22. closeColor:{r:255,g:255,b:0,a:.5},
  23. /*=====
  24. StencilData: {
  25. // NOT SUPPORTED FOR PATH
  26. },
  27. StencilPoints: [
  28. // summary:
  29. // An Array of StencilPoint objects that describe the Stencil
  30. // 0: Object
  31. // First point
  32. // [1, 2, 3...] more points
  33. ],
  34. =====*/
  35. _create: function(/*String*/shp, /*Object*/sty){
  36. // summary:
  37. // Creates a dojox.gfx.shape based on passed arguments.
  38. // Can be called many times by implementation to create
  39. // multiple shapes in one stencil.
  40. //
  41. this.remove(this[shp]);
  42. if(!this.points.length){ return; }
  43. if(dojox.gfx.renderer=="svg"){
  44. // NOTE:
  45. // In order to avoid the Safari d="" errors,
  46. // we'll need to build a string and set that.
  47. var strAr = [];
  48. dojo.forEach(this.points, function(o, i){
  49. if(!o.skip){
  50. if(i==0){
  51. strAr.push("M " + o.x +" "+ o.y);
  52. }else{
  53. var cmd = (o.t || "") + " ";
  54. if(o.x===undefined){// Z + undefined works here, but checking anyway
  55. strAr.push(cmd);
  56. }else{
  57. strAr.push(cmd + o.x +" "+ o.y);
  58. }
  59. }
  60. }
  61. }, this);
  62. if(this.closePath){
  63. strAr.push("Z");
  64. }
  65. this.stringPath = strAr.join(" ");
  66. this[shp] = this.container.createPath(strAr.join(" ")).setStroke(sty);
  67. this.closePath && this[shp].setFill(sty.fill);
  68. }else{
  69. // Leaving this code for VML. It seems slightly faster but times vary.
  70. this[shp] = this.container.createPath({}).setStroke(sty);
  71. this.closePath && this[shp].setFill(sty.fill);
  72. dojo.forEach(this.points, function(o, i){
  73. if(!o.skip){
  74. if(i==0 || o.t=="M"){
  75. this[shp].moveTo(o.x, o.y);
  76. }else if(o.t=="Z"){
  77. this.closePath && this[shp].closePath();
  78. }else{
  79. this[shp].lineTo(o.x, o.y);
  80. }
  81. }
  82. }, this);
  83. this.closePath && this[shp].closePath();
  84. }
  85. this._setNodeAtts(this[shp]);
  86. },
  87. render: function(){
  88. // summary:
  89. // Renders the 'hit' object (the shape used for an expanded
  90. // hit area and for highlighting) and the'shape' (the actual
  91. // display object).
  92. //
  93. this.onBeforeRender(this);
  94. this.renderHit && this._create("hit", this.style.currentHit);
  95. this._create("shape", this.style.current);
  96. //console.log("path render")
  97. //console.log("---------------------rend hit", this.renderHit, this.id)
  98. },
  99. getBounds: function(/* ? Boolean*/absolute){
  100. // summary:
  101. // Overwriting _Base.getBounds. Not sure how absolute should
  102. // work for a path.
  103. var minx = 10000, miny = 10000, maxx = 0, maxy = 0;
  104. dojo.forEach(this.points, function(p){
  105. if(p.x!==undefined && !isNaN(p.x)){
  106. minx = Math.min(minx, p.x);
  107. miny = Math.min(miny, p.y);
  108. maxx = Math.max(maxx, p.x);
  109. maxy = Math.max(maxy, p.y);
  110. }
  111. });
  112. return {
  113. x1:minx,
  114. y1:miny,
  115. x2:maxx,
  116. y2:maxy,
  117. x:minx,
  118. y:miny,
  119. w:maxx-minx,
  120. h:maxy-miny
  121. };
  122. },
  123. checkClosePoint: function(/*Object*/firstPt, /*Object*/currPt, /*Boolean*/remove){
  124. // summary:
  125. // Checks if points are close enough to indicate that
  126. // path should be close. Provides a visual cue.
  127. // description:
  128. // Not actually used in stencil.path - this is used for
  129. // drawable tools that extend it. Note that those tools
  130. // need to remove the shape created: this.closeGuide, or
  131. // add arg: remove
  132. //
  133. var dist = this.util.distance(firstPt.x, firstPt.y, currPt.x, currPt.y);
  134. if(this.points.length>1){
  135. if(dist<this.closeRadius && !this.closeGuide && !remove){
  136. var c = {
  137. cx:firstPt.x,
  138. cy:firstPt.y,
  139. rx:this.closeRadius,
  140. ry:this.closeRadius
  141. }
  142. this.closeGuide = this.container.createEllipse(c)
  143. .setFill(this.closeColor);
  144. }else if(remove || dist > this.closeRadius && this.closeGuide){
  145. this.remove(this.closeGuide);
  146. this.closeGuide = null;
  147. }
  148. }
  149. // return if we are within close distance
  150. return dist < this.closeRadius; // Boolean
  151. }
  152. }
  153. );
  154. dojox.drawing.register({
  155. name:"dojox.drawing.stencil.Path"
  156. }, "stencil");
  157. }