path.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import { __read } from "tslib";
  2. import { add, sub, min as _min, max as _max, scale, distance } from './matrix';
  3. function smoothBezier(points, smooth, isLoop, constraint) {
  4. var _a;
  5. var cps = [];
  6. var hasConstraint = !!constraint;
  7. var prevPoint;
  8. var nextPoint;
  9. var min = [Infinity, Infinity];
  10. var max = [-Infinity, -Infinity];
  11. var nextCp0;
  12. var cp1;
  13. var cp0;
  14. if (hasConstraint) {
  15. _a = __read(constraint, 2), min = _a[0], max = _a[1];
  16. for (var i = 0, l = points.length; i < l; i += 1) {
  17. var point = points[i];
  18. min = _min(min, point);
  19. max = _max(max, point);
  20. }
  21. }
  22. for (var i = 0, len = points.length; i < len; i += 1) {
  23. var point = points[i];
  24. if (i === 0 && !isLoop) {
  25. cp0 = point;
  26. }
  27. else if (i === len - 1 && !isLoop) {
  28. cp1 = point;
  29. cps.push(cp0);
  30. cps.push(cp1);
  31. }
  32. else {
  33. var prevIdx = [i ? i - 1 : len - 1, i - 1][isLoop ? 0 : 1];
  34. prevPoint = points[prevIdx];
  35. nextPoint = points[isLoop ? (i + 1) % len : i + 1];
  36. var v = [0, 0];
  37. v = sub(nextPoint, prevPoint);
  38. v = scale(v, smooth);
  39. var d0 = distance(point, prevPoint);
  40. var d1 = distance(point, nextPoint);
  41. var sum = d0 + d1;
  42. if (sum !== 0) {
  43. d0 /= sum;
  44. d1 /= sum;
  45. }
  46. var v1 = scale(v, -d0);
  47. var v2 = scale(v, d1);
  48. cp1 = add(point, v1);
  49. nextCp0 = add(point, v2);
  50. // 下一个控制点必须在这个点和下一个点之间
  51. nextCp0 = _min(nextCp0, _max(nextPoint, point));
  52. nextCp0 = _max(nextCp0, _min(nextPoint, point));
  53. // 重新计算 cp1 的值
  54. v1 = sub(nextCp0, point);
  55. v1 = scale(v1, -d0 / d1);
  56. cp1 = add(point, v1);
  57. // 上一个控制点必须要在上一个点和这一个点之间
  58. cp1 = _min(cp1, _max(prevPoint, point));
  59. cp1 = _max(cp1, _min(prevPoint, point));
  60. // 重新计算 nextCp0 的值
  61. v2 = sub(point, cp1);
  62. v2 = scale(v2, d1 / d0);
  63. nextCp0 = add(point, v2);
  64. if (hasConstraint) {
  65. cp1 = _max(cp1, min);
  66. cp1 = _min(cp1, max);
  67. nextCp0 = _max(nextCp0, min);
  68. nextCp0 = _min(nextCp0, max);
  69. }
  70. cps.push(cp0);
  71. cps.push(cp1);
  72. cp0 = nextCp0;
  73. }
  74. }
  75. if (isLoop) {
  76. cps.push(cps.shift());
  77. }
  78. return cps;
  79. }
  80. /**
  81. * create bezier spline from catmull rom spline
  82. * @param {Array} crp Catmull Rom Points
  83. * @param {boolean} z Spline is loop
  84. * @param {Array} constraint Constraint
  85. */
  86. export function catmullRom2Bezier(crp, z, constraint) {
  87. var _a;
  88. if (z === void 0) { z = false; }
  89. if (constraint === void 0) { constraint = [
  90. [0, 0],
  91. [1, 1],
  92. ]; }
  93. var isLoop = !!z;
  94. var pointList = [];
  95. for (var i = 0, l = crp.length; i < l; i += 2) {
  96. pointList.push([crp[i], crp[i + 1]]);
  97. }
  98. var controlPointList = smoothBezier(pointList, 0.4, isLoop, constraint);
  99. var len = pointList.length;
  100. var d1 = [];
  101. var cp1;
  102. var cp2;
  103. var p;
  104. for (var i = 0; i < len - 1; i += 1) {
  105. cp1 = controlPointList[i * 2];
  106. cp2 = controlPointList[i * 2 + 1];
  107. p = pointList[i + 1];
  108. d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]]);
  109. }
  110. if (isLoop) {
  111. cp1 = controlPointList[len];
  112. cp2 = controlPointList[len + 1];
  113. _a = __read(pointList, 1), p = _a[0];
  114. d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]]);
  115. }
  116. return d1;
  117. }
  118. //# sourceMappingURL=path.js.map