svg-path-bbox-umd

A UMD build of svg-path-bbox

目前為 2025-01-27 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/525015/1527480/svg-path-bbox-umd.js

  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('svgpath')) :
  3. typeof define === 'function' && define.amd ? define(['svgpath'], factory) :
  4. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.svgPathBbox = factory(global.SvgPath));
  5. })(this, (SvgPath => {
  6. const CBEZIER_MINMAX_EPSILON = 0.00000001;
  7. const minmaxQ = A => {
  8. const min = Math.min(A[0], A[2]);
  9. const max = Math.max(A[0], A[2]);
  10. if (A[1] >= A[0] ? A[2] >= A[1] : A[2] <= A[1]) return [min, max];
  11. const E = (A[0] * A[2] - A[1] * A[1]) / (A[0] - 2 * A[1] + A[2]);
  12. return E < min ? [E, max] : [min, E];
  13. };
  14. const minmaxC = A => {
  15. const K = A[0] - 3 * A[1] + 3 * A[2] - A[3];
  16. if (Math.abs(K) < CBEZIER_MINMAX_EPSILON) {
  17. if (A[0] === A[3] && A[0] === A[1]) return [A[0], A[3]];
  18. return minmaxQ([
  19. A[0],
  20. -0.5 * A[0] + 1.5 * A[1],
  21. A[0] - 3 * A[1] + 3 * A[2],
  22. ]);
  23. }
  24. const T = -A[0] * A[2] + A[0] * A[3] - A[1] * A[2] - A[1] * A[3] + A[1] * A[1] + A[2] * A[2];
  25. if (T <= 0) return [Math.min(A[0], A[3]), Math.max(A[0], A[3])];
  26.  
  27. const S = Math.sqrt(T)
  28. let min = Math.min(A[0], A[3]);
  29. let max = Math.max(A[0], A[3]);
  30. const L = A[0] - 2 * A[1] + A[2];
  31. for (let R = (L + S) / K, i = 1; i <= 2; R = (L - S) / K, i++) {
  32. if (R > 0 && R < 1) {
  33. const Q = A[0] * (1 - R) * (1 - R) * (1 - R) + A[1] * 3 * (1 - R) * (1 - R) * R + A[2] * 3 * (1 - R) * R * R + A[3] * R * R * R;
  34. if (Q < min) {
  35. min = Q;
  36. }
  37. if (Q > max) {
  38. max = Q;
  39. }
  40. }
  41. }
  42. return [min, max];
  43. };
  44. /**
  45. * Compute bounding boxes of SVG paths.
  46. * @param {String | typeof SvgPath} d SVG path for which their bounding box will be computed.
  47. * @returns {BBox}
  48. */
  49. const svgPathBbox = d => {
  50. const min = [Infinity, Infinity];
  51. const max = [-Infinity, -Infinity];
  52. SvgPath.from(d)
  53. .abs()
  54. .unarc()
  55. .unshort()
  56. .iterate((seg, _, x, y) => {
  57. switch (seg[0]) {
  58. case "M": {
  59. if (min[0] > seg[1]) {
  60. min[0] = seg[1];
  61. }
  62. if (min[1] > seg[2]) {
  63. min[1] = seg[2];
  64. }
  65. if (max[0] < seg[1]) {
  66. max[0] = seg[1];
  67. }
  68. if (max[1] < seg[2]) {
  69. max[1] = seg[2];
  70. }
  71. break;
  72. }
  73. case "H": {
  74. if (min[0] > seg[1]) {
  75. min[0] = seg[1];
  76. }
  77. if (max[0] < seg[1]) {
  78. max[0] = seg[1];
  79. }
  80. break;
  81. }
  82. case "V": {
  83. if (min[1] > seg[1]) {
  84. min[1] = seg[1];
  85. }
  86. if (max[1] < seg[1]) {
  87. max[1] = seg[1];
  88. }
  89. break;
  90. }
  91. case "L": {
  92. if (min[0] > seg[1]) {
  93. min[0] = seg[1];
  94. }
  95. if (min[1] > seg[2]) {
  96. min[1] = seg[2];
  97. }
  98. if (max[0] < seg[1]) {
  99. max[0] = seg[1];
  100. }
  101. if (max[1] < seg[2]) {
  102. max[1] = seg[2];
  103. }
  104. break;
  105. }
  106. case "C": {
  107. const cxMinMax = minmaxC([x, seg[1], seg[3], seg[5]]);
  108. if (min[0] > cxMinMax[0]) {
  109. min[0] = cxMinMax[0];
  110. }
  111. if (max[0] < cxMinMax[1]) {
  112. max[0] = cxMinMax[1];
  113. }
  114. const cyMinMax = minmaxC([y, seg[2], seg[4], seg[6]]);
  115. if (min[1] > cyMinMax[0]) {
  116. min[1] = cyMinMax[0];
  117. }
  118. if (max[1] < cyMinMax[1]) {
  119. max[1] = cyMinMax[1];
  120. }
  121. break;
  122. }
  123. case "Q": {
  124. const qxMinMax = minmaxQ([x, seg[1], seg[3]]);
  125. if (min[0] > qxMinMax[0]) {
  126. min[0] = qxMinMax[0];
  127. }
  128. if (max[0] < qxMinMax[1]) {
  129. max[0] = qxMinMax[1];
  130. }
  131. const qyMinMax = minmaxQ([y, seg[2], seg[4]]);
  132. if (min[1] > qyMinMax[0]) {
  133. min[1] = qyMinMax[0];
  134. }
  135. if (max[1] < qyMinMax[1]) {
  136. max[1] = qyMinMax[1];
  137. }
  138. break;
  139. }
  140. }
  141. }, true);
  142. return [min[0], min[1], max[0], max[1]];
  143. };
  144. return svgPathBbox;
  145. }));

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址