path.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import { vec2 } from '@antv/matrix-util';
  2. export function points2Path(points, isInCircle) {
  3. var path = [];
  4. if (points.length) {
  5. path.push(['M', points[0].x, points[0].y]);
  6. for (var i = 1, length_1 = points.length; i < length_1; i += 1) {
  7. var item = points[i];
  8. path.push(['L', item.x, item.y]);
  9. }
  10. if (isInCircle) {
  11. path.push(['Z']);
  12. }
  13. }
  14. return path;
  15. }
  16. /**
  17. * @ignore
  18. * 计算光滑的贝塞尔曲线
  19. */
  20. export var smoothBezier = function (points, smooth, isLoop, constraint) {
  21. var cps = [];
  22. var prevPoint;
  23. var nextPoint;
  24. var hasConstraint = !!constraint;
  25. var min;
  26. var max;
  27. if (hasConstraint) {
  28. min = [Infinity, Infinity];
  29. max = [-Infinity, -Infinity];
  30. for (var i = 0, l = points.length; i < l; i++) {
  31. var point = points[i];
  32. min = vec2.min([0, 0], min, point);
  33. max = vec2.max([0, 0], max, point);
  34. }
  35. min = vec2.min([0, 0], min, constraint[0]);
  36. max = vec2.max([0, 0], max, constraint[1]);
  37. }
  38. for (var i = 0, len = points.length; i < len; i++) {
  39. var point = points[i];
  40. if (isLoop) {
  41. prevPoint = points[i ? i - 1 : len - 1];
  42. nextPoint = points[(i + 1) % len];
  43. }
  44. else {
  45. if (i === 0 || i === len - 1) {
  46. cps.push(point);
  47. continue;
  48. }
  49. else {
  50. prevPoint = points[i - 1];
  51. nextPoint = points[i + 1];
  52. }
  53. }
  54. var v = [0, 0];
  55. v = vec2.sub(v, nextPoint, prevPoint);
  56. v = vec2.scale(v, v, smooth);
  57. var d0 = vec2.distance(point, prevPoint);
  58. var d1 = vec2.distance(point, nextPoint);
  59. var sum = d0 + d1;
  60. if (sum !== 0) {
  61. d0 /= sum;
  62. d1 /= sum;
  63. }
  64. var v1 = vec2.scale([0, 0], v, -d0);
  65. var v2 = vec2.scale([0, 0], v, d1);
  66. var cp0 = vec2.add([0, 0], point, v1);
  67. var cp1 = vec2.add([0, 0], point, v2);
  68. if (hasConstraint) {
  69. cp0 = vec2.max([0, 0], cp0, min);
  70. cp0 = vec2.min([0, 0], cp0, max);
  71. cp1 = vec2.max([0, 0], cp1, min);
  72. cp1 = vec2.min([0, 0], cp1, max);
  73. }
  74. cps.push(cp0);
  75. cps.push(cp1);
  76. }
  77. if (isLoop) {
  78. cps.push(cps.shift());
  79. }
  80. return cps;
  81. };
  82. /**
  83. * @ignore
  84. * 贝塞尔曲线
  85. */
  86. export function catmullRom2bezier(crp, z, constraint) {
  87. var isLoop = !!z;
  88. var pointList = [];
  89. for (var i = 0, l = crp.length; i < l; i += 2) {
  90. pointList.push([crp[i], crp[i + 1]]);
  91. }
  92. var controlPointList = smoothBezier(pointList, 0.4, isLoop, constraint);
  93. var len = pointList.length;
  94. var d1 = [];
  95. var cp1;
  96. var cp2;
  97. var p;
  98. for (var i = 0; i < len - 1; i++) {
  99. cp1 = controlPointList[i * 2];
  100. cp2 = controlPointList[i * 2 + 1];
  101. p = pointList[i + 1];
  102. d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]]);
  103. }
  104. if (isLoop) {
  105. cp1 = controlPointList[len];
  106. cp2 = controlPointList[len + 1];
  107. p = pointList[0];
  108. d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]]);
  109. }
  110. return d1;
  111. }
  112. /**
  113. * @ignore
  114. * 根据关键点获取限定了范围的平滑线
  115. */
  116. export function getSplinePath(points, isInCircle, constaint) {
  117. var data = [];
  118. var first = points[0];
  119. var prePoint = null;
  120. if (points.length <= 2) {
  121. // 两点以内直接绘制成路径
  122. return points2Path(points, isInCircle);
  123. }
  124. for (var i = 0, len = points.length; i < len; i++) {
  125. var point = points[i];
  126. if (!prePoint || !(prePoint.x === point.x && prePoint.y === point.y)) {
  127. data.push(point.x);
  128. data.push(point.y);
  129. prePoint = point;
  130. }
  131. }
  132. var constraint = constaint || [
  133. // 范围
  134. [0, 0],
  135. [1, 1],
  136. ];
  137. var splinePath = catmullRom2bezier(data, isInCircle, constraint);
  138. splinePath.unshift(['M', first.x, first.y]);
  139. return splinePath;
  140. }
  141. //# sourceMappingURL=path.js.map