mxMarker.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /**
  2. * Copyright (c) 2006-2015, JGraph Ltd
  3. * Copyright (c) 2006-2015, Gaudenz Alder
  4. */
  5. var mxMarker =
  6. {
  7. /**
  8. * Class: mxMarker
  9. *
  10. * A static class that implements all markers for VML and SVG using a
  11. * registry. NOTE: The signatures in this class will change.
  12. *
  13. * Variable: markers
  14. *
  15. * Maps from markers names to functions to paint the markers.
  16. */
  17. markers: [],
  18. /**
  19. * Function: addMarker
  20. *
  21. * Adds a factory method that updates a given endpoint and returns a
  22. * function to paint the marker onto the given canvas.
  23. */
  24. addMarker: function(type, funct)
  25. {
  26. mxMarker.markers[type] = funct;
  27. },
  28. /**
  29. * Function: createMarker
  30. *
  31. * Returns a function to paint the given marker.
  32. */
  33. createMarker: function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
  34. {
  35. var funct = mxMarker.markers[type];
  36. return (funct != null) ? funct(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) : null;
  37. }
  38. };
  39. /**
  40. * Adds the classic and block marker factory method.
  41. */
  42. (function()
  43. {
  44. function createArrow(widthFactor)
  45. {
  46. widthFactor = (widthFactor != null) ? widthFactor : 2;
  47. return function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
  48. {
  49. // The angle of the forward facing arrow sides against the x axis is
  50. // 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for
  51. // only half the strokewidth is processed ).
  52. var endOffsetX = unitX * sw * 1.118;
  53. var endOffsetY = unitY * sw * 1.118;
  54. unitX = unitX * (size + sw);
  55. unitY = unitY * (size + sw);
  56. var pt = pe.clone();
  57. pt.x -= endOffsetX;
  58. pt.y -= endOffsetY;
  59. var f = (type != mxConstants.ARROW_CLASSIC && type != mxConstants.ARROW_CLASSIC_THIN) ? 1 : 3 / 4;
  60. pe.x += -unitX * f - endOffsetX;
  61. pe.y += -unitY * f - endOffsetY;
  62. return function()
  63. {
  64. canvas.begin();
  65. canvas.moveTo(pt.x, pt.y);
  66. canvas.lineTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor);
  67. if (type == mxConstants.ARROW_CLASSIC || type == mxConstants.ARROW_CLASSIC_THIN)
  68. {
  69. canvas.lineTo(pt.x - unitX * 3 / 4, pt.y - unitY * 3 / 4);
  70. }
  71. canvas.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor);
  72. canvas.close();
  73. if (filled)
  74. {
  75. canvas.fillAndStroke();
  76. }
  77. else
  78. {
  79. canvas.stroke();
  80. }
  81. };
  82. }
  83. };
  84. mxMarker.addMarker('classic', createArrow(2));
  85. mxMarker.addMarker('classicThin', createArrow(3));
  86. mxMarker.addMarker('block', createArrow(2));
  87. mxMarker.addMarker('blockThin', createArrow(3));
  88. function createOpenArrow(widthFactor)
  89. {
  90. widthFactor = (widthFactor != null) ? widthFactor : 2;
  91. return function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
  92. {
  93. // The angle of the forward facing arrow sides against the x axis is
  94. // 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for
  95. // only half the strokewidth is processed ).
  96. var endOffsetX = unitX * sw * 1.118;
  97. var endOffsetY = unitY * sw * 1.118;
  98. unitX = unitX * (size + sw);
  99. unitY = unitY * (size + sw);
  100. var pt = pe.clone();
  101. pt.x -= endOffsetX;
  102. pt.y -= endOffsetY;
  103. pe.x += -endOffsetX * 2;
  104. pe.y += -endOffsetY * 2;
  105. return function()
  106. {
  107. canvas.begin();
  108. canvas.moveTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor);
  109. canvas.lineTo(pt.x, pt.y);
  110. canvas.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor);
  111. canvas.stroke();
  112. };
  113. }
  114. };
  115. mxMarker.addMarker('open', createOpenArrow(2));
  116. mxMarker.addMarker('openThin', createOpenArrow(3));
  117. mxMarker.addMarker('oval', function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
  118. {
  119. var a = size / 2;
  120. var pt = pe.clone();
  121. pe.x -= unitX * a;
  122. pe.y -= unitY * a;
  123. return function()
  124. {
  125. canvas.ellipse(pt.x - a, pt.y - a, size, size);
  126. if (filled)
  127. {
  128. canvas.fillAndStroke();
  129. }
  130. else
  131. {
  132. canvas.stroke();
  133. }
  134. };
  135. });
  136. function diamond(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
  137. {
  138. // The angle of the forward facing arrow sides against the x axis is
  139. // 45 degrees, 1/sin(45) = 1.4142 / 2 = 0.7071 ( / 2 allows for
  140. // only half the strokewidth is processed ). Or 0.9862 for thin diamond.
  141. // Note these values and the tk variable below are dependent, update
  142. // both together (saves trig hard coding it).
  143. var swFactor = (type == mxConstants.ARROW_DIAMOND) ? 0.7071 : 0.9862;
  144. var endOffsetX = unitX * sw * swFactor;
  145. var endOffsetY = unitY * sw * swFactor;
  146. unitX = unitX * (size + sw);
  147. unitY = unitY * (size + sw);
  148. var pt = pe.clone();
  149. pt.x -= endOffsetX;
  150. pt.y -= endOffsetY;
  151. pe.x += -unitX - endOffsetX;
  152. pe.y += -unitY - endOffsetY;
  153. // thickness factor for diamond
  154. var tk = ((type == mxConstants.ARROW_DIAMOND) ? 2 : 3.4);
  155. return function()
  156. {
  157. canvas.begin();
  158. canvas.moveTo(pt.x, pt.y);
  159. canvas.lineTo(pt.x - unitX / 2 - unitY / tk, pt.y + unitX / tk - unitY / 2);
  160. canvas.lineTo(pt.x - unitX, pt.y - unitY);
  161. canvas.lineTo(pt.x - unitX / 2 + unitY / tk, pt.y - unitY / 2 - unitX / tk);
  162. canvas.close();
  163. if (filled)
  164. {
  165. canvas.fillAndStroke();
  166. }
  167. else
  168. {
  169. canvas.stroke();
  170. }
  171. };
  172. };
  173. mxMarker.addMarker('diamond', diamond);
  174. mxMarker.addMarker('diamondThin', diamond);
  175. })();
  176. __mxOutput.mxMarker = typeof mxMarker !== 'undefined' ? mxMarker : undefined;