Util.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. export var ModelType;
  2. (function (ModelType) {
  3. ModelType["NODE"] = "node";
  4. ModelType["CIRCLE_NODE"] = "circle-node";
  5. ModelType["POLYGON_NODE"] = "polygon-node";
  6. ModelType["RECT_NODE"] = "rect-node";
  7. ModelType["HTML_NODE"] = "html-node";
  8. ModelType["TEXT_NODE"] = "text-node";
  9. ModelType["ELLIPSE_NODE"] = "ellipse-node";
  10. ModelType["DIAMOND_NODE"] = "diamond-node";
  11. ModelType["EDGE"] = "edge";
  12. ModelType["LINE_EDGE"] = "line-edge";
  13. ModelType["POLYLINE_EDGE"] = "polyline-edge";
  14. ModelType["BEZIER_EDGE"] = "bezier-edge";
  15. ModelType["GRAPH"] = "graph";
  16. })(ModelType || (ModelType = {}));
  17. // 计算节点的box四角数据
  18. function getNodeBox(node) {
  19. var x = node.x, y = node.y, width = node.width, height = node.height;
  20. return {
  21. minX: x - width / 2,
  22. minY: y - height / 2,
  23. maxX: x + width / 2,
  24. maxY: y + height / 2,
  25. };
  26. }
  27. // 计算矩形radius设置后,四个圆角的圆心
  28. function getRadiusCenter(node) {
  29. var nodeBox = getNodeBox(node);
  30. var radius = node.radius;
  31. var minX = nodeBox.minX, minY = nodeBox.minY, maxX = nodeBox.maxX, maxY = nodeBox.maxY;
  32. return [
  33. {
  34. x: minX + radius,
  35. y: minY + radius,
  36. },
  37. {
  38. x: maxX - radius,
  39. y: minY + radius,
  40. },
  41. {
  42. x: maxX - radius,
  43. y: maxY - radius,
  44. },
  45. {
  46. x: minX + radius,
  47. y: maxY - radius,
  48. },
  49. ];
  50. }
  51. // 获取矩形resize之后,与矩形连接边的新端点
  52. export function getRectResizeEdgePoint(_a) {
  53. var point = _a.point, beforeNode = _a.beforeNode, afterNode = _a.afterNode;
  54. var x = point.x, y = point.y;
  55. var afterPoint = {
  56. x: x, y: y,
  57. };
  58. var radius = beforeNode.radius;
  59. var beforeNodeBox = getNodeBox(beforeNode);
  60. var afterNodeBox = getNodeBox(afterNode);
  61. if (x === beforeNodeBox.minX) {
  62. // 左边
  63. afterPoint.x = afterNodeBox.minX;
  64. var pct = (y - beforeNode.y) / (beforeNode.height / 2 - radius);
  65. if (pct) {
  66. afterPoint.y = afterNode.y + (afterNode.height / 2 - radius) * pct;
  67. }
  68. else {
  69. afterPoint.y = afterNode.y;
  70. }
  71. }
  72. else if (x === beforeNodeBox.maxX) {
  73. // 右边
  74. afterPoint.x = afterNodeBox.maxX;
  75. var pct = (y - beforeNode.y) / (beforeNode.height / 2 - radius);
  76. if (pct) {
  77. afterPoint.y = afterNode.y + (afterNode.height / 2 - radius) * pct;
  78. }
  79. else {
  80. afterPoint.y = afterNode.y;
  81. }
  82. }
  83. else if (y === beforeNodeBox.minY) {
  84. // 上边
  85. afterPoint.y = afterNodeBox.minY;
  86. var pct = (x - beforeNode.x) / (beforeNode.width / 2 - radius);
  87. if (pct) {
  88. afterPoint.x = afterNode.x + (afterNode.width / 2 - radius) * pct;
  89. }
  90. else {
  91. afterPoint.x = afterNode.x;
  92. }
  93. }
  94. else if (y === beforeNodeBox.maxY) {
  95. // 下边
  96. afterPoint.y = afterNodeBox.maxY;
  97. var pct = (x - beforeNode.x) / (beforeNode.width / 2 - radius);
  98. if (pct) {
  99. afterPoint.x = afterNode.x + (afterNode.width / 2 - radius) * pct;
  100. }
  101. else {
  102. afterPoint.x = afterNode.x;
  103. }
  104. }
  105. else {
  106. // 在圆角部分
  107. var beforeCoc = getRadiusCenter(beforeNode);
  108. var afterCoc = getRadiusCenter(afterNode);
  109. var nodeBox = getNodeBox(beforeNode);
  110. var minX = nodeBox.minX, minY = nodeBox.minY, maxX = nodeBox.maxX, maxY = nodeBox.maxY;
  111. var index = -1;
  112. if (x - minX < radius && y - minY < radius) {
  113. // 左上角
  114. index = 0;
  115. }
  116. else if (maxX - x < radius && y - minY < radius) {
  117. // 右上角
  118. index = 1;
  119. }
  120. else if (maxX - x < radius && maxY - y < radius) {
  121. // 右下角
  122. index = 2;
  123. }
  124. else if (x - minX < radius && minY - y < radius) {
  125. // 左下角
  126. index = 3;
  127. }
  128. if (index > -1) {
  129. // 根据夹角角度计算位置
  130. var angle = Math.atan2((y - beforeCoc[index].y), (x - beforeCoc[index].x));
  131. afterPoint.x = afterCoc[index].x + radius * Math.cos(angle);
  132. afterPoint.y = afterCoc[index].y + radius * Math.sin(angle);
  133. }
  134. }
  135. return afterPoint;
  136. }
  137. // 获取椭圆resize之后,与椭圆连接边的新端点
  138. export function getEllipseResizeEdgePoint(_a) {
  139. var point = _a.point, beforeNode = _a.beforeNode, afterNode = _a.afterNode;
  140. var rx = afterNode.rx, ry = afterNode.ry;
  141. var afterPoint = point;
  142. // 将椭圆中心当做中心点(0,0),放大缩小前点与X周夹角
  143. var tan = (point.y - beforeNode.y) / (point.x - beforeNode.x);
  144. // 方便与公式对照,将rx命名为a,ry命名为b
  145. var a = rx;
  146. var b = ry;
  147. var x;
  148. var y;
  149. // 将椭圆中心当做中心点(0,0),计算放大缩小后,同一夹角下,点相对位置
  150. if (tan >= Infinity) {
  151. // θ = PI / 2
  152. x = 0;
  153. y = b;
  154. }
  155. else if (tan <= -Infinity) {
  156. // θ = 3 * PI / 2
  157. x = 0;
  158. y = -b;
  159. }
  160. else if (point.x - beforeNode.x > 0) {
  161. // 0 < θ = PI / 2 或者 3 * PI / 2 < θ = 2 * PI
  162. // 一四象限
  163. x = (a * b) / (Math.sqrt((b * b) + a * a * tan * tan));
  164. y = (a * b * tan) / (Math.sqrt((b * b) + a * a * tan * tan));
  165. }
  166. else {
  167. // PI / 2 < θ 3 * PI / 2
  168. // 二三象限
  169. x = -(a * b) / (Math.sqrt((b * b) + a * a * tan * tan));
  170. y = -(a * b * tan) / (Math.sqrt((b * b) + a * a * tan * tan));
  171. }
  172. afterPoint = { x: x + afterNode.x, y: y + afterNode.y };
  173. return afterPoint;
  174. }
  175. // 获取菱形resize之后,与菱形连接边的新端点
  176. export function getDiamondResizeEdgePoint(_a) {
  177. var point = _a.point, beforeNode = _a.beforeNode, afterNode = _a.afterNode;
  178. var afterPoint = point;
  179. var x;
  180. var y;
  181. var px = point.x - beforeNode.x;
  182. var py = point.y - beforeNode.y;
  183. var rxBefore = beforeNode.rx;
  184. var ryBefore = beforeNode.ry;
  185. // eslint-disable-next-line max-len
  186. var pct = Math.sqrt((rxBefore - Math.abs(px)) * (rxBefore - Math.abs(px)) + py * py) / Math.sqrt(rxBefore * rxBefore + ryBefore * ryBefore);
  187. var rxAfter = afterNode.rx;
  188. var ryAfter = afterNode.ry;
  189. // eslint-disable-next-line max-len
  190. var a = Math.sqrt((rxAfter * rxAfter + ryAfter * ryAfter) * pct * pct * ((rxAfter * rxAfter) / (rxAfter * rxAfter + ryAfter * ryAfter)));
  191. var b = a * (ryAfter / rxAfter);
  192. if (px >= 0) {
  193. // eslint-disable-next-line max-len
  194. x = rxAfter - a;
  195. }
  196. else {
  197. x = a - rxAfter;
  198. }
  199. if (py > 0) {
  200. y = b;
  201. }
  202. else {
  203. y = -b;
  204. }
  205. afterPoint = {
  206. x: x + afterNode.x,
  207. y: y + afterNode.y,
  208. };
  209. return afterPoint;
  210. }