path-2-absolute.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var parse_path_string_1 = require("./parse-path-string");
  4. var REGEX_MD = /[a-z]/;
  5. function toSymmetry(p, c) {
  6. return [
  7. c[0] + (c[0] - p[0]),
  8. c[1] + (c[1] - p[1]),
  9. ];
  10. }
  11. function pathToAbsolute(pathString) {
  12. var pathArray = parse_path_string_1.default(pathString);
  13. if (!pathArray || !pathArray.length) {
  14. return [
  15. ['M', 0, 0],
  16. ];
  17. }
  18. var needProcess = false; // 如果存在小写的命令或者 V,H,T,S 则需要处理
  19. for (var i = 0; i < pathArray.length; i++) {
  20. var cmd = pathArray[i][0];
  21. // 如果存在相对位置的命令,则中断返回
  22. if (REGEX_MD.test(cmd) || ['V', 'H', 'T', 'S'].indexOf(cmd) >= 0) {
  23. needProcess = true;
  24. break;
  25. }
  26. }
  27. // 如果不存在相对命令,则直接返回
  28. // 如果在业务上都写绝对路径,这种方式最快,仅做了一次检测
  29. if (!needProcess) {
  30. return pathArray;
  31. }
  32. var res = [];
  33. var x = 0;
  34. var y = 0;
  35. var mx = 0;
  36. var my = 0;
  37. var start = 0;
  38. var pa0;
  39. var dots;
  40. var first = pathArray[0];
  41. if (first[0] === 'M' || first[0] === 'm') {
  42. x = +first[1];
  43. y = +first[2];
  44. mx = x;
  45. my = y;
  46. start++;
  47. res[0] = ['M', x, y];
  48. }
  49. for (var i = start, ii = pathArray.length; i < ii; i++) {
  50. var pa = pathArray[i];
  51. var preParams = res[i - 1]; // 取前一个已经处理后的节点,否则会出现问题
  52. var r = [];
  53. var cmd = pa[0];
  54. var upCmd = cmd.toUpperCase();
  55. if (cmd !== upCmd) {
  56. r[0] = upCmd;
  57. switch (upCmd) {
  58. case 'A':
  59. r[1] = pa[1];
  60. r[2] = pa[2];
  61. r[3] = pa[3];
  62. r[4] = pa[4];
  63. r[5] = pa[5];
  64. r[6] = +pa[6] + x;
  65. r[7] = +pa[7] + y;
  66. break;
  67. case 'V':
  68. r[1] = +pa[1] + y;
  69. break;
  70. case 'H':
  71. r[1] = +pa[1] + x;
  72. break;
  73. case 'M':
  74. mx = +pa[1] + x;
  75. my = +pa[2] + y;
  76. r[1] = mx;
  77. r[2] = my;
  78. break; // for lint
  79. default:
  80. for (var j = 1, jj = pa.length; j < jj; j++) {
  81. r[j] = +pa[j] + ((j % 2) ? x : y);
  82. }
  83. }
  84. }
  85. else { // 如果本来已经大写,则不处理
  86. r = pathArray[i];
  87. }
  88. // 需要在外面统一做,同时处理 V,H,S,T 等特殊指令
  89. switch (upCmd) {
  90. case 'Z':
  91. x = +mx;
  92. y = +my;
  93. break;
  94. case 'H':
  95. x = r[1];
  96. r = ['L', x, y];
  97. break;
  98. case 'V':
  99. y = r[1];
  100. r = ['L', x, y];
  101. break;
  102. case 'T':
  103. x = r[1];
  104. y = r[2];
  105. // 以 x, y 为中心的,上一个控制点的对称点
  106. // 需要假设上一个节点的命令为 Q
  107. var symetricT = toSymmetry([preParams[1], preParams[2]], [preParams[3], preParams[4]]);
  108. r = ['Q', symetricT[0], symetricT[1], x, y];
  109. break;
  110. case 'S':
  111. x = r[r.length - 2];
  112. y = r[r.length - 1];
  113. // 以 x,y 为中心,取上一个控制点,
  114. // 需要假设上一个线段为 C 或者 S
  115. var length_1 = preParams.length;
  116. var symetricS = toSymmetry([preParams[length_1 - 4], preParams[length_1 - 3]], [preParams[length_1 - 2], preParams[length_1 - 1]]);
  117. r = ['C', symetricS[0], symetricS[1], r[1], r[2], x, y];
  118. break;
  119. case 'M':
  120. mx = r[r.length - 2];
  121. my = r[r.length - 1];
  122. break; // for lint
  123. default:
  124. x = r[r.length - 2];
  125. y = r[r.length - 1];
  126. }
  127. res.push(r);
  128. }
  129. return res;
  130. }
  131. exports.default = pathToAbsolute;
  132. //# sourceMappingURL=path-2-absolute.js.map