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/README.md +27 -15
- package/dist/index.cjs +353 -222
- package/dist/index.d.cts +67 -26
- package/dist/index.d.mts +67 -26
- package/dist/index.d.ts +67 -26
- package/dist/index.js +2 -2
- package/dist/index.mjs +350 -221
- package/package.json +1 -1
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
|
|
1811
|
-
constructor(
|
|
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.
|
|
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
|
-
|
|
1821
|
-
|
|
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.
|
|
1847
|
-
let _y = this.
|
|
1848
|
-
if (this.
|
|
1849
|
-
const cos = Math.cos(this.
|
|
1850
|
-
const sin = Math.sin(this.
|
|
1851
|
-
const tx = _x - this.
|
|
1852
|
-
const ty = _y - this.
|
|
1853
|
-
_x = tx * cos - ty * sin + this.
|
|
1854
|
-
_y = tx * sin + ty * cos + this.
|
|
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 {
|
|
1860
|
-
const
|
|
1861
|
-
const
|
|
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 =
|
|
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(
|
|
1871
|
-
const midY = cy + rx * Math.cos(midAngle) * Math.sin(
|
|
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(
|
|
1879
|
-
const endY = cy + rx * Math.cos(endAngle) * Math.sin(
|
|
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 {
|
|
1922
|
+
const { cx, cy, rx, ry, rotate, startAngle, endAngle, clockwise } = this;
|
|
1888
1923
|
ctx.ellipse(
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
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
|
-
|
|
1901
|
-
tempV2.set(this.
|
|
1935
|
+
applyTransform(matrix) {
|
|
1936
|
+
tempV2.set(this.cx, this.cy);
|
|
1902
1937
|
tempV2.applyMatrix3(matrix);
|
|
1903
|
-
this.
|
|
1904
|
-
this.
|
|
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.
|
|
1948
|
+
return [this._center];
|
|
1914
1949
|
}
|
|
1915
1950
|
getAdaptivePointArray(output = []) {
|
|
1916
|
-
const
|
|
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
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
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
|
-
|
|
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 {
|
|
2024
|
-
const
|
|
2025
|
-
const
|
|
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.
|
|
2043
|
-
this.
|
|
2044
|
-
this.
|
|
2045
|
-
this.
|
|
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.
|
|
2091
|
+
this.rotate = source.rotate;
|
|
2050
2092
|
return this;
|
|
2051
2093
|
}
|
|
2052
2094
|
}
|
|
2053
2095
|
function transfEllipseGeneric(curve, m) {
|
|
2054
|
-
const a = curve.
|
|
2055
|
-
const b = curve.
|
|
2056
|
-
const cosTheta = Math.cos(curve.
|
|
2057
|
-
const sinTheta = Math.sin(curve.
|
|
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.
|
|
2081
|
-
curve.
|
|
2082
|
-
curve.
|
|
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.
|
|
2123
|
-
curve.
|
|
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.
|
|
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
|
|
2235
|
+
class ArcCurve extends RoundCurve {
|
|
2194
2236
|
constructor(cx = 0, cy = 0, radius = 1, startAngle = 0, endAngle = Math.PI * 2, clockwise = false) {
|
|
2195
|
-
super(
|
|
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
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
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 =
|
|
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 =
|
|
2217
|
-
const ny =
|
|
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
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
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
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
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
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
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
|
-
|
|
2483
|
+
}
|
|
2484
|
+
|
|
2485
|
+
class LineCurve extends Curve {
|
|
2486
|
+
constructor(p1, p2) {
|
|
2413
2487
|
super();
|
|
2414
|
-
this.p1 =
|
|
2415
|
-
this.p2 =
|
|
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
|
-
|
|
2477
|
-
|
|
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
|
-
|
|
2490
|
-
LineCurve
|
|
2573
|
+
curves.push(
|
|
2574
|
+
new LineCurve(
|
|
2575
|
+
points[i],
|
|
2576
|
+
points[(i + 1) % sideCount]
|
|
2577
|
+
)
|
|
2491
2578
|
);
|
|
2492
2579
|
}
|
|
2493
|
-
|
|
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
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
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
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
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
|
|
2584
|
-
LineCurve
|
|
2585
|
-
LineCurve
|
|
2586
|
-
LineCurve
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
2843
|
-
const curve = new RectangleCurve(x, y,
|
|
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,
|
|
2985
|
-
this.currentCurve.rect(x, y,
|
|
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
|
-
|
|
3080
|
-
this.curves.forEach((curve) => curve.
|
|
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.
|
|
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
|
-
|
|
3739
|
-
|
|
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,
|
|
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 };
|