path2absolute.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. var parsePathString = require('./parse-path-string');
  2. var catmullRom2bezier = require('./catmull-rom2bezier');
  3. function ellipsePath(x, y, rx, ry, a) {
  4. var res = [];
  5. if (a === null && ry === null) {
  6. ry = rx;
  7. }
  8. x = +x;
  9. y = +y;
  10. rx = +rx;
  11. ry = +ry;
  12. if (a !== null) {
  13. var rad = Math.PI / 180;
  14. var x1 = x + rx * Math.cos(-ry * rad);
  15. var x2 = x + rx * Math.cos(-a * rad);
  16. var y1 = y + rx * Math.sin(-ry * rad);
  17. var y2 = y + rx * Math.sin(-a * rad);
  18. res = [['M', x1, y1], ['A', rx, rx, 0, +(a - ry > 180), 0, x2, y2]];
  19. } else {
  20. res = [['M', x, y], ['m', 0, -ry], ['a', rx, ry, 0, 1, 1, 0, 2 * ry], ['a', rx, ry, 0, 1, 1, 0, -2 * ry], ['z']];
  21. }
  22. return res;
  23. }
  24. module.exports = function pathToAbsolute(pathArray) {
  25. pathArray = parsePathString(pathArray);
  26. if (!pathArray || !pathArray.length) {
  27. return [['M', 0, 0]];
  28. }
  29. var res = [];
  30. var x = 0;
  31. var y = 0;
  32. var mx = 0;
  33. var my = 0;
  34. var start = 0;
  35. var pa0 = void 0;
  36. var dots = void 0;
  37. if (pathArray[0][0] === 'M') {
  38. x = +pathArray[0][1];
  39. y = +pathArray[0][2];
  40. mx = x;
  41. my = y;
  42. start++;
  43. res[0] = ['M', x, y];
  44. }
  45. var crz = pathArray.length === 3 && pathArray[0][0] === 'M' && pathArray[1][0].toUpperCase() === 'R' && pathArray[2][0].toUpperCase() === 'Z';
  46. for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) {
  47. res.push(r = []);
  48. pa = pathArray[i];
  49. pa0 = pa[0];
  50. if (pa0 !== pa0.toUpperCase()) {
  51. r[0] = pa0.toUpperCase();
  52. switch (r[0]) {
  53. case 'A':
  54. r[1] = pa[1];
  55. r[2] = pa[2];
  56. r[3] = pa[3];
  57. r[4] = pa[4];
  58. r[5] = pa[5];
  59. r[6] = +pa[6] + x;
  60. r[7] = +pa[7] + y;
  61. break;
  62. case 'V':
  63. r[1] = +pa[1] + y;
  64. break;
  65. case 'H':
  66. r[1] = +pa[1] + x;
  67. break;
  68. case 'R':
  69. dots = [x, y].concat(pa.slice(1));
  70. for (var j = 2, jj = dots.length; j < jj; j++) {
  71. dots[j] = +dots[j] + x;
  72. dots[++j] = +dots[j] + y;
  73. }
  74. res.pop();
  75. res = res.concat(catmullRom2bezier(dots, crz));
  76. break;
  77. case 'O':
  78. res.pop();
  79. dots = ellipsePath(x, y, pa[1], pa[2]);
  80. dots.push(dots[0]);
  81. res = res.concat(dots);
  82. break;
  83. case 'U':
  84. res.pop();
  85. res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3]));
  86. r = ['U'].concat(res[res.length - 1].slice(-2));
  87. break;
  88. case 'M':
  89. mx = +pa[1] + x;
  90. my = +pa[2] + y;
  91. break; // for lint
  92. default:
  93. for (var _j = 1, _jj = pa.length; _j < _jj; _j++) {
  94. r[_j] = +pa[_j] + (_j % 2 ? x : y);
  95. }
  96. }
  97. } else if (pa0 === 'R') {
  98. dots = [x, y].concat(pa.slice(1));
  99. res.pop();
  100. res = res.concat(catmullRom2bezier(dots, crz));
  101. r = ['R'].concat(pa.slice(-2));
  102. } else if (pa0 === 'O') {
  103. res.pop();
  104. dots = ellipsePath(x, y, pa[1], pa[2]);
  105. dots.push(dots[0]);
  106. res = res.concat(dots);
  107. } else if (pa0 === 'U') {
  108. res.pop();
  109. res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3]));
  110. r = ['U'].concat(res[res.length - 1].slice(-2));
  111. } else {
  112. for (var k = 0, kk = pa.length; k < kk; k++) {
  113. r[k] = pa[k];
  114. }
  115. }
  116. pa0 = pa0.toUpperCase();
  117. if (pa0 !== 'O') {
  118. switch (r[0]) {
  119. case 'Z':
  120. x = +mx;
  121. y = +my;
  122. break;
  123. case 'H':
  124. x = r[1];
  125. break;
  126. case 'V':
  127. y = r[1];
  128. break;
  129. case 'M':
  130. mx = r[r.length - 2];
  131. my = r[r.length - 1];
  132. break; // for lint
  133. default:
  134. x = r[r.length - 2];
  135. y = r[r.length - 1];
  136. }
  137. }
  138. }
  139. return res;
  140. };