modern-path2d 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1589,6 +1589,12 @@ class Curve {
1589
1589
  getControlPointRefs() {
1590
1590
  return [];
1591
1591
  }
1592
+ applyTransform(transform) {
1593
+ this.getControlPointRefs().forEach((p) => {
1594
+ p.applyMatrix3(transform);
1595
+ });
1596
+ return this;
1597
+ }
1592
1598
  getUnevenPointArray(count = 5, output = []) {
1593
1599
  const p = new Vector2();
1594
1600
  for (let i = 0, len = Math.max(1, count) - 1; i <= len; i++) {
@@ -1730,10 +1736,6 @@ class Curve {
1730
1736
  }
1731
1737
  return mid;
1732
1738
  }
1733
- matrix(matrix) {
1734
- this.getControlPointRefs().forEach((point) => point.applyMatrix3(matrix));
1735
- return this;
1736
- }
1737
1739
  getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
1738
1740
  const potins = this.getPoints();
1739
1741
  for (let i = 0, len = potins.length; i < len; i++) {
@@ -1807,18 +1809,53 @@ const tempTransform0$1 = new Matrix3();
1807
1809
  const tempTransform1$1 = new Matrix3();
1808
1810
  const tempTransform2$1 = new Matrix3();
1809
1811
  const tempV2 = new Vector2();
1810
- class EllipseCurve extends Curve {
1811
- constructor(cx = 0, cy = 0, rx = 1, ry = 1, rotation = 0, startAngle = 0, endAngle = Math.PI * 2, clockwise = false) {
1812
+ class RoundCurve extends Curve {
1813
+ constructor(_center, _radius, _diff, rotate = 0, startAngle = 0, endAngle = Math.PI * 2, clockwise = false) {
1812
1814
  super();
1813
- this.rotation = rotation;
1815
+ this._center = _center;
1816
+ this._radius = _radius;
1817
+ this._diff = _diff;
1818
+ this.rotate = rotate;
1814
1819
  this.startAngle = startAngle;
1815
1820
  this.endAngle = endAngle;
1816
1821
  this.clockwise = clockwise;
1817
- this.center = new Vector2(cx, cy);
1818
- this.radius = new Vector2(rx, ry);
1819
1822
  }
1820
- center;
1821
- radius;
1823
+ get cx() {
1824
+ return this._center.x;
1825
+ }
1826
+ set cx(val) {
1827
+ this._center.x = val;
1828
+ }
1829
+ get cy() {
1830
+ return this._center.y;
1831
+ }
1832
+ set cy(val) {
1833
+ this._center.y = val;
1834
+ }
1835
+ get rx() {
1836
+ return this._radius.x;
1837
+ }
1838
+ set rx(val) {
1839
+ this._radius.x = val;
1840
+ }
1841
+ get ry() {
1842
+ return this._radius.y;
1843
+ }
1844
+ set ry(val) {
1845
+ this._radius.y = val;
1846
+ }
1847
+ get dx() {
1848
+ return this._diff.x;
1849
+ }
1850
+ set dx(val) {
1851
+ this._diff.x = val;
1852
+ }
1853
+ get dy() {
1854
+ return this._diff.y;
1855
+ }
1856
+ set dy(val) {
1857
+ this._diff.y = val;
1858
+ }
1822
1859
  isClockwise() {
1823
1860
  return this.clockwise;
1824
1861
  }
@@ -1843,40 +1880,38 @@ class EllipseCurve extends Curve {
1843
1880
  }
1844
1881
  }
1845
1882
  const angle = this.startAngle + t * deltaAngle;
1846
- let _x = this.center.x + this.radius.x * Math.cos(angle);
1847
- let _y = this.center.y + this.radius.y * Math.sin(angle);
1848
- if (this.rotation !== 0) {
1849
- const cos = Math.cos(this.rotation);
1850
- const sin = Math.sin(this.rotation);
1851
- const tx = _x - this.center.x;
1852
- const ty = _y - this.center.y;
1853
- _x = tx * cos - ty * sin + this.center.x;
1854
- _y = tx * sin + ty * cos + this.center.y;
1883
+ let _x = this.cx + this.rx * Math.cos(angle);
1884
+ let _y = this.cy + this.ry * Math.sin(angle);
1885
+ if (this.rotate !== 0) {
1886
+ const cos = Math.cos(this.rotate);
1887
+ const sin = Math.sin(this.rotate);
1888
+ const tx = _x - this.cx;
1889
+ const ty = _y - this.cy;
1890
+ _x = tx * cos - ty * sin + this.cx;
1891
+ _y = tx * sin + ty * cos + this.cy;
1855
1892
  }
1856
1893
  return output.set(_x, _y);
1857
1894
  }
1858
1895
  toCommands() {
1859
- const { center, radius, startAngle, endAngle, clockwise, rotation } = this;
1860
- const { x: cx, y: cy } = center;
1861
- const { x: rx, y: ry } = radius;
1862
- const startX = cx + rx * Math.cos(startAngle) * Math.cos(rotation) - ry * Math.sin(startAngle) * Math.sin(rotation);
1863
- const startY = cy + rx * Math.cos(startAngle) * Math.sin(rotation) + ry * Math.sin(startAngle) * Math.cos(rotation);
1896
+ const { cx, cy, rx, ry, startAngle, endAngle, clockwise, rotate } = this;
1897
+ const startX = cx + rx * Math.cos(startAngle) * Math.cos(rotate) - ry * Math.sin(startAngle) * Math.sin(rotate);
1898
+ const startY = cy + rx * Math.cos(startAngle) * Math.sin(rotate) + ry * Math.sin(startAngle) * Math.cos(rotate);
1864
1899
  const angleDiff = Math.abs(startAngle - endAngle);
1865
1900
  const largeArcFlag = angleDiff > Math.PI ? 1 : 0;
1866
1901
  const sweepFlag = clockwise ? 1 : 0;
1867
- const angle = rotation * 180 / Math.PI;
1902
+ const angle = rotate * 180 / Math.PI;
1868
1903
  if (angleDiff >= 2 * Math.PI) {
1869
1904
  const midAngle = startAngle + Math.PI;
1870
- const midX = cx + rx * Math.cos(midAngle) * Math.cos(rotation) - ry * Math.sin(midAngle) * Math.sin(rotation);
1871
- const midY = cy + rx * Math.cos(midAngle) * Math.sin(rotation) + ry * Math.sin(midAngle) * Math.cos(rotation);
1905
+ const midX = cx + rx * Math.cos(midAngle) * Math.cos(rotate) - ry * Math.sin(midAngle) * Math.sin(rotate);
1906
+ const midY = cy + rx * Math.cos(midAngle) * Math.sin(rotate) + ry * Math.sin(midAngle) * Math.cos(rotate);
1872
1907
  return [
1873
1908
  { type: "M", x: startX, y: startY },
1874
1909
  { type: "A", rx, ry, angle, largeArcFlag: 0, sweepFlag, x: midX, y: midY },
1875
1910
  { type: "A", rx, ry, angle, largeArcFlag: 0, sweepFlag, x: startX, y: startY }
1876
1911
  ];
1877
1912
  } else {
1878
- const endX = cx + rx * Math.cos(endAngle) * Math.cos(rotation) - ry * Math.sin(endAngle) * Math.sin(rotation);
1879
- const endY = cy + rx * Math.cos(endAngle) * Math.sin(rotation) + ry * Math.sin(endAngle) * Math.cos(rotation);
1913
+ const endX = cx + rx * Math.cos(endAngle) * Math.cos(rotate) - ry * Math.sin(endAngle) * Math.sin(rotate);
1914
+ const endY = cy + rx * Math.cos(endAngle) * Math.sin(rotate) + ry * Math.sin(endAngle) * Math.cos(rotate);
1880
1915
  return [
1881
1916
  { type: "M", x: startX, y: startY },
1882
1917
  { type: "A", rx, ry, angle, largeArcFlag, sweepFlag, x: endX, y: endY }
@@ -1884,24 +1919,24 @@ class EllipseCurve extends Curve {
1884
1919
  }
1885
1920
  }
1886
1921
  drawTo(ctx) {
1887
- const { center, radius, rotation, startAngle, endAngle, clockwise } = this;
1922
+ const { cx, cy, rx, ry, rotate, startAngle, endAngle, clockwise } = this;
1888
1923
  ctx.ellipse(
1889
- center.x,
1890
- center.y,
1891
- radius.x,
1892
- radius.y,
1893
- rotation,
1924
+ cx,
1925
+ cy,
1926
+ rx,
1927
+ ry,
1928
+ rotate,
1894
1929
  startAngle,
1895
1930
  endAngle,
1896
1931
  !clockwise
1897
1932
  );
1898
1933
  return this;
1899
1934
  }
1900
- matrix(matrix) {
1901
- tempV2.set(this.center.x, this.center.y);
1935
+ applyTransform(matrix) {
1936
+ tempV2.set(this.cx, this.cy);
1902
1937
  tempV2.applyMatrix3(matrix);
1903
- this.center.x = tempV2.x;
1904
- this.center.y = tempV2.y;
1938
+ this.cx = tempV2.x;
1939
+ this.cy = tempV2.y;
1905
1940
  if (isTransformSkewed(matrix)) {
1906
1941
  transfEllipseGeneric(this, matrix);
1907
1942
  } else {
@@ -1910,71 +1945,80 @@ class EllipseCurve extends Curve {
1910
1945
  return this;
1911
1946
  }
1912
1947
  getControlPointRefs() {
1913
- return [this.center];
1948
+ return [this._center];
1914
1949
  }
1915
1950
  getAdaptivePointArray(output = []) {
1916
- const i = output.length - 1;
1917
- const x = this.center.x;
1918
- const y = this.center.y;
1919
- const rx = this.radius.x;
1920
- const ry = this.radius.y;
1921
- const dx = 0;
1922
- const dy = 0;
1951
+ const { cx, cy, rx, ry, dx, dy } = this;
1923
1952
  if (!(rx >= 0 && ry >= 0 && dx >= 0 && dy >= 0)) {
1924
1953
  return output;
1925
1954
  }
1926
1955
  const n = Math.ceil(2.3 * Math.sqrt(rx + ry));
1927
- const m = n * 8 + (0) + (0);
1956
+ const m = n * 8 + (dx ? 4 : 0) + (dy ? 4 : 0);
1928
1957
  if (m === 0) {
1929
1958
  return output;
1930
1959
  }
1960
+ const array = [];
1931
1961
  if (n === 0) {
1932
- output[i] = output[i + 6] = x + dx;
1933
- output[i + 1] = output[i + 3] = y + dy;
1934
- output[i + 2] = output[i + 4] = x - dx;
1935
- output[i + 5] = output[i + 7] = y - dy;
1936
- return output;
1962
+ array[0] = array[6] = cx + dx;
1963
+ array[1] = array[3] = cy + dy;
1964
+ array[2] = array[4] = cx - dx;
1965
+ array[5] = array[7] = cy - dy;
1966
+ } else {
1967
+ let j1 = 0;
1968
+ let j2 = n * 4 + (dx ? 2 : 0) + 2;
1969
+ let j3 = j2;
1970
+ let j4 = m;
1971
+ let x0 = dx + rx;
1972
+ let y0 = dy;
1973
+ let x1 = cx + x0;
1974
+ let x2 = cx - x0;
1975
+ let y1 = cy + y0;
1976
+ array[j1++] = x1;
1977
+ array[j1++] = y1;
1978
+ array[--j2] = y1;
1979
+ array[--j2] = x2;
1980
+ if (dy) {
1981
+ const y22 = cy - y0;
1982
+ array[j3++] = x2;
1983
+ array[j3++] = y22;
1984
+ array[--j4] = y22;
1985
+ array[--j4] = x1;
1986
+ }
1987
+ for (let i = 1; i < n; i++) {
1988
+ const a = Math.PI / 2 * (i / n);
1989
+ const x02 = dx + Math.cos(a) * rx;
1990
+ const y02 = dy + Math.sin(a) * ry;
1991
+ const x12 = cx + x02;
1992
+ const x22 = cx - x02;
1993
+ const y12 = cy + y02;
1994
+ const y22 = cy - y02;
1995
+ array[j1++] = x12;
1996
+ array[j1++] = y12;
1997
+ array[--j2] = y12;
1998
+ array[--j2] = x22;
1999
+ array[j3++] = x22;
2000
+ array[j3++] = y22;
2001
+ array[--j4] = y22;
2002
+ array[--j4] = x12;
2003
+ }
2004
+ x0 = dx;
2005
+ y0 = dy + ry;
2006
+ x1 = cx + x0;
2007
+ x2 = cx - x0;
2008
+ y1 = cy + y0;
2009
+ const y2 = cy - y0;
2010
+ array[j1++] = x1;
2011
+ array[j1++] = y1;
2012
+ array[--j4] = y2;
2013
+ array[--j4] = x1;
2014
+ if (dx) {
2015
+ array[j1++] = x2;
2016
+ array[j1++] = y1;
2017
+ array[--j4] = y2;
2018
+ array[--j4] = x2;
2019
+ }
1937
2020
  }
1938
- let j1 = i;
1939
- let j2 = n * 4 + (0) + 2 + i;
1940
- let j3 = j2;
1941
- let j4 = m + i;
1942
- let x0 = dx + rx;
1943
- let y0 = dy;
1944
- let x1 = x + x0;
1945
- let x2 = x - x0;
1946
- let y1 = y + y0;
1947
- output[j1++] = x1;
1948
- output[j1++] = y1;
1949
- output[--j2] = y1;
1950
- output[--j2] = x2;
1951
- for (let i2 = 1; i2 < n; i2++) {
1952
- const a = Math.PI / 2 * (i2 / n);
1953
- const x02 = dx + Math.cos(a) * rx;
1954
- const y02 = dy + Math.sin(a) * ry;
1955
- const x12 = x + x02;
1956
- const x22 = x - x02;
1957
- const y12 = y + y02;
1958
- const y22 = y - y02;
1959
- output[j1++] = x12;
1960
- output[j1++] = y12;
1961
- output[--j2] = y12;
1962
- output[--j2] = x22;
1963
- output[j3++] = x22;
1964
- output[j3++] = y22;
1965
- output[--j4] = y22;
1966
- output[--j4] = x12;
1967
- }
1968
- x0 = dx;
1969
- y0 = dy + ry;
1970
- x1 = x + x0;
1971
- x2 = x - x0;
1972
- y1 = y + y0;
1973
- const y2 = y - y0;
1974
- output[j1++] = x1;
1975
- output[j1++] = y1;
1976
- output[--j4] = y2;
1977
- output[--j4] = x1;
2021
+ Array.prototype.push.apply(output, array);
1978
2022
  return output;
1979
2023
  }
1980
2024
  fillTriangulate(options = {}) {
@@ -2020,11 +2064,9 @@ class EllipseCurve extends Curve {
2020
2064
  };
2021
2065
  }
2022
2066
  getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
2023
- const { center, radius, rotation: theta } = this;
2024
- const { x: rx, y: ry } = radius;
2025
- const { x: cx, y: cy } = center;
2026
- const cosTheta = Math.cos(theta);
2027
- const sinTheta = Math.sin(theta);
2067
+ const { cx, cy, rx, ry, rotate } = this;
2068
+ const cosTheta = Math.cos(rotate);
2069
+ const sinTheta = Math.sin(rotate);
2028
2070
  const halfWidth = Math.sqrt(
2029
2071
  rx * rx * cosTheta * cosTheta + ry * ry * sinTheta * sinTheta
2030
2072
  );
@@ -2039,22 +2081,22 @@ class EllipseCurve extends Curve {
2039
2081
  }
2040
2082
  copy(source) {
2041
2083
  super.copy(source);
2042
- this.center.x = source.center.x;
2043
- this.center.y = source.center.y;
2044
- this.radius.x = source.radius.x;
2045
- this.radius.y = source.radius.y;
2084
+ this.cx = source.cx;
2085
+ this.cy = source.cy;
2086
+ this.rx = source.rx;
2087
+ this.ry = source.ry;
2046
2088
  this.startAngle = source.startAngle;
2047
2089
  this.endAngle = source.endAngle;
2048
2090
  this.clockwise = source.clockwise;
2049
- this.rotation = source.rotation;
2091
+ this.rotate = source.rotate;
2050
2092
  return this;
2051
2093
  }
2052
2094
  }
2053
2095
  function transfEllipseGeneric(curve, m) {
2054
- const a = curve.radius.x;
2055
- const b = curve.radius.y;
2056
- const cosTheta = Math.cos(curve.rotation);
2057
- const sinTheta = Math.sin(curve.rotation);
2096
+ const a = curve.rx;
2097
+ const b = curve.ry;
2098
+ const cosTheta = Math.cos(curve.rotate);
2099
+ const sinTheta = Math.sin(curve.rotate);
2058
2100
  const v1 = new Vector2(a * cosTheta, a * sinTheta);
2059
2101
  const v2 = new Vector2(-b * sinTheta, b * cosTheta);
2060
2102
  const f1 = v1.applyMatrix3(m);
@@ -2077,9 +2119,9 @@ function transfEllipseGeneric(curve, m) {
2077
2119
  const ed = eigenDecomposition(mQe[0], mQe[1], mQe[4]);
2078
2120
  const rt1sqrt = Math.sqrt(ed.rt1);
2079
2121
  const rt2sqrt = Math.sqrt(ed.rt2);
2080
- curve.radius.x = 1 / rt1sqrt;
2081
- curve.radius.y = 1 / rt2sqrt;
2082
- curve.rotation = Math.atan2(ed.sn, ed.cs);
2122
+ curve.rx = 1 / rt1sqrt;
2123
+ curve.ry = 1 / rt2sqrt;
2124
+ curve.rotate = Math.atan2(ed.sn, ed.cs);
2083
2125
  const isFullEllipse = (curve.endAngle - curve.startAngle) % (2 * Math.PI) < Number.EPSILON;
2084
2126
  if (!isFullEllipse) {
2085
2127
  const mDsqrt = tempTransform1$1.set(
@@ -2119,10 +2161,10 @@ function transfEllipseGeneric(curve, m) {
2119
2161
  function transfEllipseNoSkew(curve, m) {
2120
2162
  const sx = getTransformScaleX(m);
2121
2163
  const sy = getTransformScaleY(m);
2122
- curve.radius.x *= sx;
2123
- curve.radius.y *= sy;
2164
+ curve.rx *= sx;
2165
+ curve.ry *= sy;
2124
2166
  const theta = sx > Number.EPSILON ? Math.atan2(m.elements[1], m.elements[0]) : Math.atan2(-m.elements[3], m.elements[4]);
2125
- curve.rotation += theta;
2167
+ curve.rotate += theta;
2126
2168
  if (isTransformFlipped(m)) {
2127
2169
  curve.startAngle *= -1;
2128
2170
  curve.endAngle *= -1;
@@ -2190,31 +2232,49 @@ function eigenDecomposition(A, B, C) {
2190
2232
  return { rt1, rt2, cs, sn };
2191
2233
  }
2192
2234
 
2193
- class ArcCurve extends EllipseCurve {
2235
+ class ArcCurve extends RoundCurve {
2194
2236
  constructor(cx = 0, cy = 0, radius = 1, startAngle = 0, endAngle = Math.PI * 2, clockwise = false) {
2195
- super(cx, cy, radius, radius, 0, startAngle, endAngle, clockwise);
2237
+ super(
2238
+ new Vector2(cx, cy),
2239
+ new Vector2(radius, radius),
2240
+ new Vector2(0, 0),
2241
+ 0,
2242
+ startAngle,
2243
+ endAngle,
2244
+ clockwise
2245
+ );
2246
+ this.radius = radius;
2247
+ }
2248
+ drawTo(ctx) {
2249
+ const { cx, cy, radius, startAngle, endAngle, clockwise } = this;
2250
+ ctx.arc(
2251
+ cx,
2252
+ cy,
2253
+ radius,
2254
+ startAngle,
2255
+ endAngle,
2256
+ !clockwise
2257
+ );
2258
+ return this;
2196
2259
  }
2197
2260
  getAdaptivePointArray(output = []) {
2198
- const start = 0;
2199
- const end = 1;
2200
- const x = this.center.x;
2201
- const y = this.center.y;
2202
- const clockwise = this.clockwise;
2203
- const radius = this.radius.x;
2204
- let dist = Math.abs(start - end);
2205
- if (clockwise && end > start) {
2261
+ const { cx, cy, radius, startAngle, endAngle, clockwise } = this;
2262
+ let dist = Math.abs(startAngle - endAngle);
2263
+ if (!clockwise && startAngle > endAngle) {
2264
+ dist = 2 * Math.PI - dist;
2265
+ } else if (clockwise && endAngle > startAngle) {
2206
2266
  dist = 2 * Math.PI - dist;
2207
2267
  }
2208
2268
  let steps = Math.max(6, Math.floor(6 * radius ** (1 / 3) * (dist / Math.PI)));
2209
2269
  steps = Math.max(steps, 3);
2210
2270
  let f = dist / steps;
2211
- let t = start;
2212
- f *= clockwise ? -1 : 1;
2271
+ let t = startAngle;
2272
+ f *= !clockwise ? -1 : 1;
2213
2273
  for (let i = 0; i < steps + 1; i++) {
2214
2274
  const cs = Math.cos(t);
2215
2275
  const sn = Math.sin(t);
2216
- const nx = x + cs * radius;
2217
- const ny = y + sn * radius;
2276
+ const nx = cx + cs * radius;
2277
+ const ny = cy + sn * radius;
2218
2278
  output.push(nx, ny);
2219
2279
  t += f;
2220
2280
  }
@@ -2295,29 +2355,21 @@ class CompositeCurve extends Curve {
2295
2355
  }
2296
2356
 
2297
2357
  class CubicBezierCurve extends Curve {
2298
- p1;
2299
- cp1;
2300
- cp2;
2301
- p2;
2302
- static from(p1, cp1, cp2, p2) {
2358
+ constructor(p1, cp1, cp2, p2) {
2359
+ super();
2360
+ this.p1 = p1;
2361
+ this.cp1 = cp1;
2362
+ this.cp2 = cp2;
2363
+ this.p2 = p2;
2364
+ }
2365
+ static from(p1x, p1y, cp1x, cp1y, cp2x, cp2y, p2x, p2y) {
2303
2366
  return new CubicBezierCurve(
2304
- p1.x,
2305
- p1.y,
2306
- cp1.x,
2307
- cp1.y,
2308
- cp2.x,
2309
- cp2.y,
2310
- p2.x,
2311
- p2.y
2367
+ new Vector2(p1x, p1y),
2368
+ new Vector2(cp1x, cp1y),
2369
+ new Vector2(cp2x, cp2y),
2370
+ new Vector2(p2x, p2y)
2312
2371
  );
2313
2372
  }
2314
- constructor(p1x, p1y, cp1x, cp1y, cp2x, cp2y, p2x, p2y) {
2315
- super();
2316
- this.p1 = new Vector2(p1x, p1y);
2317
- this.cp1 = new Vector2(cp1x, cp1y);
2318
- this.cp2 = new Vector2(cp2x, cp2y);
2319
- this.p2 = new Vector2(p2x, p2y);
2320
- }
2321
2373
  getPoint(t, output = new Vector2()) {
2322
2374
  const { p1, cp1, cp2, p2 } = this;
2323
2375
  return output.set(
@@ -2403,16 +2455,44 @@ class CubicBezierCurve extends Curve {
2403
2455
  }
2404
2456
  }
2405
2457
 
2406
- class LineCurve extends Curve {
2407
- p1;
2408
- p2;
2409
- static from(p1, p2) {
2410
- return new LineCurve(p1.x, p1.y, p2.x, p2.y);
2458
+ class EllipseCurve extends RoundCurve {
2459
+ constructor(cx = 0, cy = 0, rx = 1, ry = 1, rotate = 0, startAngle = 0, endAngle = Math.PI * 2, clockwise = false) {
2460
+ super(
2461
+ new Vector2(cx, cy),
2462
+ new Vector2(rx, ry),
2463
+ new Vector2(),
2464
+ rotate,
2465
+ startAngle,
2466
+ endAngle,
2467
+ clockwise
2468
+ );
2469
+ }
2470
+ drawTo(ctx) {
2471
+ ctx.ellipse(
2472
+ this.cx,
2473
+ this.cy,
2474
+ this.rx,
2475
+ this.ry,
2476
+ this.rotate,
2477
+ this.startAngle,
2478
+ this.endAngle,
2479
+ !this.clockwise
2480
+ );
2481
+ return this;
2411
2482
  }
2412
- constructor(p1x, p1y, p2x, p2y) {
2483
+ }
2484
+
2485
+ class LineCurve extends Curve {
2486
+ constructor(p1, p2) {
2413
2487
  super();
2414
- this.p1 = new Vector2(p1x, p1y);
2415
- this.p2 = new Vector2(p2x, p2y);
2488
+ this.p1 = p1;
2489
+ this.p2 = p2;
2490
+ }
2491
+ static from(p1x, p1y, p2x, p2y) {
2492
+ return new LineCurve(
2493
+ new Vector2(p1x, p1y),
2494
+ new Vector2(p2x, p2y)
2495
+ );
2416
2496
  }
2417
2497
  getPoint(t, output = new Vector2()) {
2418
2498
  if (t === 1) {
@@ -2473,8 +2553,11 @@ class LineCurve extends Curve {
2473
2553
  }
2474
2554
 
2475
2555
  class PloygonCurve extends CompositeCurve {
2476
- static equilateral(cx = 0, cy = 0, radius = 1, sideCount = 3) {
2477
- const ploygon = new PloygonCurve();
2556
+ //
2557
+ }
2558
+
2559
+ class EquilateralPloygonCurve extends PloygonCurve {
2560
+ constructor(cx = 0, cy = 0, radius = 1, sideCount = 3) {
2478
2561
  const points = [];
2479
2562
  for (let i = 0; i < sideCount; i++) {
2480
2563
  const radian = i * 2 * Math.PI / sideCount - 0.5 * Math.PI;
@@ -2485,35 +2568,37 @@ class PloygonCurve extends CompositeCurve {
2485
2568
  ).add({ x: cx, y: cy })
2486
2569
  );
2487
2570
  }
2571
+ const curves = [];
2488
2572
  for (let i = 0; i < sideCount; i++) {
2489
- ploygon.curves.push(
2490
- LineCurve.from(points[i], points[(i + 1) % sideCount])
2573
+ curves.push(
2574
+ new LineCurve(
2575
+ points[i],
2576
+ points[(i + 1) % sideCount]
2577
+ )
2491
2578
  );
2492
2579
  }
2493
- return ploygon;
2580
+ super(curves);
2581
+ this.cx = cx;
2582
+ this.cy = cy;
2583
+ this.radius = radius;
2584
+ this.sideCount = sideCount;
2494
2585
  }
2495
2586
  }
2496
2587
 
2497
2588
  class QuadraticBezierCurve extends Curve {
2498
- p1;
2499
- cp;
2500
- p2;
2501
- static from(p1, cp, p2) {
2589
+ constructor(p1, cp, p2) {
2590
+ super();
2591
+ this.p1 = p1;
2592
+ this.cp = cp;
2593
+ this.p2 = p2;
2594
+ }
2595
+ static from(p1x, p1y, cpx, cpy, p2x, p2y) {
2502
2596
  return new QuadraticBezierCurve(
2503
- p1.x,
2504
- p1.y,
2505
- cp.x,
2506
- cp.y,
2507
- p2.x,
2508
- p2.y
2597
+ new Vector2(p1x, p1y),
2598
+ new Vector2(cpx, cpy),
2599
+ new Vector2(p2x, p2y)
2509
2600
  );
2510
2601
  }
2511
- constructor(p1x, p1y, cpx, cpy, p2x, p2y) {
2512
- super();
2513
- this.p1 = new Vector2(p1x, p1y);
2514
- this.cp = new Vector2(cpx, cpy);
2515
- this.p2 = new Vector2(p2x, p2y);
2516
- }
2517
2602
  getPoint(t, output = new Vector2()) {
2518
2603
  const { p1, cp, p2 } = this;
2519
2604
  output.set(
@@ -2580,16 +2665,20 @@ class RectangleCurve extends PloygonCurve {
2580
2665
  new Vector2(x, y + height)
2581
2666
  ];
2582
2667
  super([
2583
- LineCurve.from(points[0], points[1]),
2584
- LineCurve.from(points[1], points[2]),
2585
- LineCurve.from(points[2], points[3]),
2586
- LineCurve.from(points[3], points[0])
2668
+ new LineCurve(points[0], points[1]),
2669
+ new LineCurve(points[1], points[2]),
2670
+ new LineCurve(points[2], points[3]),
2671
+ new LineCurve(points[3], points[0])
2587
2672
  ]);
2588
2673
  this.x = x;
2589
2674
  this.y = y;
2590
2675
  this.width = width;
2591
2676
  this.height = height;
2592
2677
  }
2678
+ drawTo(ctx) {
2679
+ ctx.rect(this.x, this.y, this.width, this.height);
2680
+ return this;
2681
+ }
2593
2682
  fillTriangulate(options = {}) {
2594
2683
  let {
2595
2684
  vertices = [],
@@ -2634,6 +2723,34 @@ class RectangleCurve extends PloygonCurve {
2634
2723
  }
2635
2724
  }
2636
2725
 
2726
+ class RoundRectangleCurve extends RoundCurve {
2727
+ constructor(x = 0, y = 0, width = 1, height = 1, radius = 1) {
2728
+ const halfWidth = width / 2;
2729
+ const halfHeight = height / 2;
2730
+ const cx = x + halfWidth;
2731
+ const cy = y + halfHeight;
2732
+ const rx = Math.max(0, Math.min(radius, Math.min(halfWidth, halfHeight)));
2733
+ const ry = rx;
2734
+ const dx = halfWidth - rx;
2735
+ const dy = halfHeight - ry;
2736
+ super(
2737
+ new Vector2(cx, cy),
2738
+ new Vector2(rx, ry),
2739
+ new Vector2(dx, dy)
2740
+ );
2741
+ this.x = x;
2742
+ this.y = y;
2743
+ this.width = width;
2744
+ this.height = height;
2745
+ this.radius = radius;
2746
+ }
2747
+ drawTo(ctx) {
2748
+ const { x, y, width, height, radius } = this;
2749
+ ctx.roundRect(x, y, width, height, radius);
2750
+ return this;
2751
+ }
2752
+ }
2753
+
2637
2754
  class SplineCurve extends Curve {
2638
2755
  constructor(points = []) {
2639
2756
  super();
@@ -2728,7 +2845,7 @@ class CurvePath extends CompositeCurve {
2728
2845
  if (start) {
2729
2846
  const end = this.currentPoint;
2730
2847
  if (end && !start.equals(end)) {
2731
- this.curves.push(LineCurve.from(end, start));
2848
+ this.curves.push(new LineCurve(end, start));
2732
2849
  end.copy(start);
2733
2850
  }
2734
2851
  this.startPoint = void 0;
@@ -2744,7 +2861,7 @@ class CurvePath extends CompositeCurve {
2744
2861
  const start = this.currentPoint;
2745
2862
  if (!start?.equals({ x, y })) {
2746
2863
  this.curves.push(
2747
- new LineCurve(
2864
+ LineCurve.from(
2748
2865
  start?.x ?? 0,
2749
2866
  start?.y ?? 0,
2750
2867
  x,
@@ -2759,7 +2876,7 @@ class CurvePath extends CompositeCurve {
2759
2876
  const start = this.currentPoint;
2760
2877
  if (!start?.equals({ x, y })) {
2761
2878
  this.curves.push(
2762
- new CubicBezierCurve(
2879
+ CubicBezierCurve.from(
2763
2880
  start?.x ?? 0,
2764
2881
  start?.y ?? 0,
2765
2882
  cp1x,
@@ -2778,7 +2895,7 @@ class CurvePath extends CompositeCurve {
2778
2895
  const start = this.currentPoint;
2779
2896
  if (!start?.equals({ x, y })) {
2780
2897
  this.curves.push(
2781
- new QuadraticBezierCurve(
2898
+ QuadraticBezierCurve.from(
2782
2899
  start?.x ?? 0,
2783
2900
  start?.y ?? 0,
2784
2901
  cpx,
@@ -2839,8 +2956,15 @@ class CurvePath extends CompositeCurve {
2839
2956
  this.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise);
2840
2957
  return this;
2841
2958
  }
2842
- rect(x, y, w, h) {
2843
- const curve = new RectangleCurve(x, y, w, h);
2959
+ rect(x, y, width, height) {
2960
+ const curve = new RectangleCurve(x, y, width, height);
2961
+ this._connetLineTo(curve);
2962
+ this.curves.push(curve);
2963
+ this._setCurrentPoint({ x, y });
2964
+ return this;
2965
+ }
2966
+ roundRect(x, y, width, height, radii) {
2967
+ const curve = new RoundRectangleCurve(x, y, width, height, radii);
2844
2968
  this._connetLineTo(curve);
2845
2969
  this.curves.push(curve);
2846
2970
  this._setCurrentPoint({ x, y });
@@ -2981,8 +3105,12 @@ class Path2D extends CompositeCurve {
2981
3105
  this.currentCurve.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise);
2982
3106
  return this;
2983
3107
  }
2984
- rect(x, y, w, h) {
2985
- this.currentCurve.rect(x, y, w, h);
3108
+ rect(x, y, width, height) {
3109
+ this.currentCurve.rect(x, y, width, height);
3110
+ return this;
3111
+ }
3112
+ roundRect(x, y, width, height, radii) {
3113
+ this.currentCurve.roundRect(x, y, width, height, radii);
2986
3114
  return this;
2987
3115
  }
2988
3116
  addCommands(commands) {
@@ -3076,8 +3204,8 @@ class Path2D extends CompositeCurve {
3076
3204
  });
3077
3205
  return this;
3078
3206
  }
3079
- matrix(matrix) {
3080
- this.curves.forEach((curve) => curve.matrix(matrix));
3207
+ applyTransform(transform) {
3208
+ this.curves.forEach((curve) => curve.applyTransform(transform));
3081
3209
  return this;
3082
3210
  }
3083
3211
  getMinMax(min = Vector2.MAX, max = Vector2.MIN, withStyle = true) {
@@ -3236,6 +3364,33 @@ class Path2DSet {
3236
3364
  }
3237
3365
  }
3238
3366
 
3367
+ const dataUri = "data:image/svg+xml;";
3368
+ const base64DataUri = `${dataUri}base64,`;
3369
+ const utf8DataUri = `${dataUri}charset=utf8,`;
3370
+ function svgToDOM(svg) {
3371
+ if (typeof svg === "string") {
3372
+ let xml;
3373
+ if (svg.startsWith(base64DataUri)) {
3374
+ svg = svg.substring(base64DataUri.length, svg.length);
3375
+ xml = atob(svg);
3376
+ } else if (svg.startsWith(utf8DataUri)) {
3377
+ svg = svg.substring(utf8DataUri.length, svg.length);
3378
+ xml = decodeURIComponent(svg);
3379
+ } else {
3380
+ xml = svg;
3381
+ }
3382
+ const doc = new DOMParser().parseFromString(xml, "text/xml");
3383
+ const error = doc.querySelector("parsererror");
3384
+ if (error) {
3385
+ throw new Error(`${error.textContent ?? "parser error"}
3386
+ ${xml}`);
3387
+ }
3388
+ return doc.documentElement;
3389
+ } else {
3390
+ return svg;
3391
+ }
3392
+ }
3393
+
3239
3394
  const defaultUnit = "px";
3240
3395
  const defaultDPI = 90;
3241
3396
  const units = ["mm", "cm", "in", "pt", "pc", "px"];
@@ -3713,7 +3868,7 @@ function parseNode(node, style, paths = [], stylesheets = {}) {
3713
3868
  const transformStack = [];
3714
3869
  const transform = getNodeTransform(node, currentTransform, transformStack);
3715
3870
  if (path) {
3716
- path.matrix(currentTransform);
3871
+ path.applyTransform(currentTransform);
3717
3872
  paths.push(path);
3718
3873
  path.style = style;
3719
3874
  }
@@ -3735,34 +3890,8 @@ function parseNode(node, style, paths = [], stylesheets = {}) {
3735
3890
  return paths;
3736
3891
  }
3737
3892
 
3738
- const dataUri = "data:image/svg+xml;";
3739
- const base64DataUri = `${dataUri}base64,`;
3740
- const utf8DataUri = `${dataUri}charset=utf8,`;
3741
- function parseSVGToDOM(svg) {
3742
- if (typeof svg === "string") {
3743
- let xml;
3744
- if (svg.startsWith(base64DataUri)) {
3745
- svg = svg.substring(base64DataUri.length, svg.length);
3746
- xml = atob(svg);
3747
- } else if (svg.startsWith(utf8DataUri)) {
3748
- svg = svg.substring(utf8DataUri.length, svg.length);
3749
- xml = decodeURIComponent(svg);
3750
- } else {
3751
- xml = svg;
3752
- }
3753
- const doc = new DOMParser().parseFromString(xml, "text/xml");
3754
- const error = doc.querySelector("parsererror");
3755
- if (error) {
3756
- throw new Error(`${error.textContent ?? "parser error"}
3757
- ${xml}`);
3758
- }
3759
- return doc.documentElement;
3760
- } else {
3761
- return svg;
3762
- }
3763
- }
3764
- function parseSVG(svg) {
3765
- return new Path2DSet(parseNode(parseSVGToDOM(svg), {}));
3893
+ function svgToPath2DSet(svg) {
3894
+ return new Path2DSet(parseNode(svgToDOM(svg), {}));
3766
3895
  }
3767
3896
 
3768
- export { ArcCurve, BoundingBox, CompositeCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, LineCurve, Matrix3, Path2D, Path2DSet, PloygonCurve, QuadraticBezierCurve, RectangleCurve, SplineCurve, Vector2, catmullRom, cubicBezier, drawPoint, fillTriangulate, getAdaptiveCubicBezierCurvePoints, getAdaptiveQuadraticBezierCurvePoints, parseArcCommand, parsePathDataArgs, parseSVG, parseSVGToDOM, quadraticBezier, setCanvasContext, strokeTriangulate, svgPathCommandsAddToPath2D, svgPathCommandsToData, svgPathDataToCommands };
3897
+ export { ArcCurve, BoundingBox, CompositeCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, EquilateralPloygonCurve, LineCurve, Matrix3, Path2D, Path2DSet, PloygonCurve, QuadraticBezierCurve, RectangleCurve, RoundRectangleCurve, SplineCurve, Vector2, catmullRom, cubicBezier, drawPoint, fillTriangulate, getAdaptiveCubicBezierCurvePoints, getAdaptiveQuadraticBezierCurvePoints, parseArcCommand, parsePathDataArgs, quadraticBezier, setCanvasContext, strokeTriangulate, svgPathCommandsAddToPath2D, svgPathCommandsToData, svgPathDataToCommands, svgToDOM, svgToPath2DSet };