@leafer/path 1.0.0-beta.12 → 1.0.0-beta.15
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/package.json +7 -5
- package/types/index.d.ts +100 -0
- package/src/BezierHelper.ts +0 -195
- package/src/EllipseHelper.ts +0 -70
- package/src/PathBounds.ts +0 -138
- package/src/PathCommandDataHelper.ts +0 -98
- package/src/PathCommandMap.ts +0 -126
- package/src/PathConvert.ts +0 -325
- package/src/PathCorner.ts +0 -10
- package/src/PathCreator.ts +0 -91
- package/src/PathDrawer.ts +0 -85
- package/src/PathHelper.ts +0 -8
- package/src/RectHelper.ts +0 -22
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafer/path",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.15",
|
|
4
4
|
"description": "@leafer/path",
|
|
5
5
|
"author": "Chao (Leafer) Wan",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "src/index.ts",
|
|
8
|
+
"types": "types/index.d.ts",
|
|
8
9
|
"files": [
|
|
9
|
-
"
|
|
10
|
+
"types",
|
|
11
|
+
"dist"
|
|
10
12
|
],
|
|
11
13
|
"repository": {
|
|
12
14
|
"type": "git",
|
|
@@ -19,10 +21,10 @@
|
|
|
19
21
|
"leaferjs"
|
|
20
22
|
],
|
|
21
23
|
"dependencies": {
|
|
22
|
-
"@leafer/math": "1.0.0-beta.
|
|
23
|
-
"@leafer/debug": "1.0.0-beta.
|
|
24
|
+
"@leafer/math": "1.0.0-beta.15",
|
|
25
|
+
"@leafer/debug": "1.0.0-beta.15"
|
|
24
26
|
},
|
|
25
27
|
"devDependencies": {
|
|
26
|
-
"@leafer/interface": "1.0.0-beta.
|
|
28
|
+
"@leafer/interface": "1.0.0-beta.15"
|
|
27
29
|
}
|
|
28
30
|
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { IPathCreator, IPathCommandData, IPathDrawer, IPathString, IBoundsData, ITwoPointBoundsData, IPointData, INumberMap, IStringMap } from '@leafer/interface';
|
|
2
|
+
|
|
3
|
+
declare const PathHelper: {
|
|
4
|
+
creator: IPathCreator;
|
|
5
|
+
parse(_pathString: string, _curveMode?: boolean): IPathCommandData;
|
|
6
|
+
convertToCanvasData(_old: IPathCommandData, _curveMode?: boolean): IPathCommandData;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
interface ICurrentCommand {
|
|
10
|
+
name?: number;
|
|
11
|
+
length?: number;
|
|
12
|
+
index?: number;
|
|
13
|
+
dot?: number;
|
|
14
|
+
}
|
|
15
|
+
declare const PathConvert: {
|
|
16
|
+
current: ICurrentCommand;
|
|
17
|
+
stringify(data: IPathCommandData): string;
|
|
18
|
+
parse(pathString: string, curveMode?: boolean): IPathCommandData;
|
|
19
|
+
toCanvasData(old: IPathCommandData, curveMode?: boolean): IPathCommandData;
|
|
20
|
+
copyData(data: IPathCommandData, old: IPathCommandData, index: number, count: number): void;
|
|
21
|
+
pushData(data: IPathCommandData, strNum: string | number): void;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
declare class PathCreator implements IPathDrawer {
|
|
25
|
+
path: IPathCommandData;
|
|
26
|
+
constructor(path?: IPathCommandData | IPathString);
|
|
27
|
+
beginPath(): PathCreator;
|
|
28
|
+
moveTo(x: number, y: number): PathCreator;
|
|
29
|
+
lineTo(x: number, y: number): PathCreator;
|
|
30
|
+
bezierCurveTo(x1: number, y1: number, x2: number, y2: number, x: number, y: number): PathCreator;
|
|
31
|
+
quadraticCurveTo(x1: number, y1: number, x: number, y: number): PathCreator;
|
|
32
|
+
closePath(): PathCreator;
|
|
33
|
+
rect(x: number, y: number, width: number, height: number): PathCreator;
|
|
34
|
+
roundRect(x: number, y: number, width: number, height: number, cornerRadius: number | number[]): PathCreator;
|
|
35
|
+
ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): PathCreator;
|
|
36
|
+
arc(x: number, y: number, radius: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): PathCreator;
|
|
37
|
+
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): PathCreator;
|
|
38
|
+
drawEllipse(x: number, y: number, radiusX: number, radiusY: number, rotation?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): PathCreator;
|
|
39
|
+
drawArc(x: number, y: number, radius: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): PathCreator;
|
|
40
|
+
drawPoints(points: number[], curve?: boolean | number, close?: boolean): PathCreator;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
declare const PathCommandDataHelper: {
|
|
44
|
+
beginPath(data: IPathCommandData): void;
|
|
45
|
+
moveTo(data: IPathCommandData, x: number, y: number): void;
|
|
46
|
+
lineTo(data: IPathCommandData, x: number, y: number): void;
|
|
47
|
+
bezierCurveTo(data: IPathCommandData, x1: number, y1: number, x2: number, y2: number, x: number, y: number): void;
|
|
48
|
+
quadraticCurveTo(data: IPathCommandData, x1: number, y1: number, x: number, y: number): void;
|
|
49
|
+
closePath(data: IPathCommandData): void;
|
|
50
|
+
rect(data: IPathCommandData, x: number, y: number, width: number, height: number): void;
|
|
51
|
+
roundRect(data: IPathCommandData, x: number, y: number, width: number, height: number, cornerRadius: number | number[]): void;
|
|
52
|
+
ellipse(data: IPathCommandData, x: number, y: number, radiusX: number, radiusY: number, rotation?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void;
|
|
53
|
+
arc(data: IPathCommandData, x: number, y: number, radius: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void;
|
|
54
|
+
arcTo(data: IPathCommandData, x1: number, y1: number, x2: number, y2: number, radius: number): void;
|
|
55
|
+
drawEllipse(data: IPathCommandData, x: number, y: number, radiusX: number, radiusY: number, rotation?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void;
|
|
56
|
+
drawArc(data: IPathCommandData, x: number, y: number, radius: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void;
|
|
57
|
+
drawPoints(data: IPathCommandData, points: number[], curve?: boolean | number, close?: boolean): void;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
declare const PathDrawer: {
|
|
61
|
+
drawPathByData(drawer: IPathDrawer, data: IPathCommandData): void;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
declare const PathBounds: {
|
|
65
|
+
toBounds(data: IPathCommandData, setBounds: IBoundsData): void;
|
|
66
|
+
toTwoPointBounds(data: IPathCommandData, setPointBounds: ITwoPointBoundsData): void;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
declare const PathCorner: {
|
|
70
|
+
smooth(data: IPathCommandData, _cornerRadius: number, _cornerSmoothing?: number): IPathCommandData;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
declare const BezierHelper: {
|
|
74
|
+
points(data: IPathCommandData, points: number[], curve?: boolean | number, close?: boolean): void;
|
|
75
|
+
rect(data: IPathCommandData, x: number, y: number, width: number, height: number): void;
|
|
76
|
+
roundRect(data: IPathCommandData, x: number, y: number, width: number, height: number, radius: number | number[]): void;
|
|
77
|
+
arcTo(data: IPathCommandData | null | void, fromX: number, fromY: number, x1: number, y1: number, toX: number, toY: number, radius: number, setPointBounds?: ITwoPointBoundsData, setEndPoint?: IPointData, setStartPoint?: IPointData): void;
|
|
78
|
+
arc(data: IPathCommandData | null | void, x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean, setPointBounds?: ITwoPointBoundsData, setEndPoint?: IPointData, setStartPoint?: IPointData): void;
|
|
79
|
+
ellipse(data: IPathCommandData | null | void, cx: number, cy: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, anticlockwise?: boolean, setPointBounds?: ITwoPointBoundsData, setEndPoint?: IPointData, setStartPoint?: IPointData): void;
|
|
80
|
+
quadraticCurveTo(data: IPathCommandData, fromX: number, fromY: number, x1: number, y1: number, toX: number, toY: number): void;
|
|
81
|
+
toTwoPointBoundsByQuadraticCurve(fromX: number, fromY: number, x1: number, y1: number, toX: number, toY: number, pointBounds: ITwoPointBoundsData, addMode?: boolean): void;
|
|
82
|
+
toTwoPointBounds(fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number, pointBounds: ITwoPointBoundsData, addMode?: boolean): void;
|
|
83
|
+
getPointAndSet(t: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number, setPoint: IPointData): void;
|
|
84
|
+
getPoint(t: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number): IPointData;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
declare const EllipseHelper: {
|
|
88
|
+
ellipticalArc(data: IPathCommandData, fromX: number, fromY: number, radiusX: number, radiusY: number, rotation: number, largeFlag: number, sweepFlag: number, toX: number, toY: number, curveMode?: boolean): void;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
declare const RectHelper: {
|
|
92
|
+
drawRoundRect(drawer: IPathDrawer, x: number, y: number, width: number, height: number, cornerRadius: number | number[]): void;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
declare const PathCommandMap: INumberMap;
|
|
96
|
+
declare const NeedConvertToCanvasCommandMap: INumberMap;
|
|
97
|
+
declare const PathNumberCommandMap: IStringMap;
|
|
98
|
+
declare const PathNumberCommandLengthMap: INumberMap;
|
|
99
|
+
|
|
100
|
+
export { BezierHelper, EllipseHelper, NeedConvertToCanvasCommandMap, PathBounds, PathCommandDataHelper, PathCommandMap, PathConvert, PathCorner, PathCreator, PathDrawer, PathHelper, PathNumberCommandLengthMap, PathNumberCommandMap, RectHelper };
|
package/src/BezierHelper.ts
DELETED
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import { IPointData, ITwoPointBoundsData, IPathCommandData } from '@leafer/interface'
|
|
2
|
-
import { OneRadian, PI2, PI_2, PointHelper, TwoPointBoundsHelper } from '@leafer/math'
|
|
3
|
-
|
|
4
|
-
import { PathCommandMap } from './PathCommandMap'
|
|
5
|
-
import { RectHelper } from './RectHelper'
|
|
6
|
-
import { PathHelper } from './PathHelper'
|
|
7
|
-
|
|
8
|
-
const { sin, cos, atan2, ceil, abs, PI } = Math
|
|
9
|
-
const { setPoint, addPoint } = TwoPointBoundsHelper
|
|
10
|
-
const { set } = PointHelper
|
|
11
|
-
const tempPoint = {} as IPointData
|
|
12
|
-
|
|
13
|
-
export const BezierHelper = {
|
|
14
|
-
|
|
15
|
-
rect(data: IPathCommandData, x: number, y: number, width: number, height: number) {
|
|
16
|
-
PathHelper.creator.path = data
|
|
17
|
-
PathHelper.creator.moveTo(x, y).lineTo(x + width, y).lineTo(x + width, y + height).lineTo(x, y + height).lineTo(x, y)
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
roundRect(data: IPathCommandData, x: number, y: number, width: number, height: number, radius: number | number[]): void {
|
|
21
|
-
PathHelper.creator.path = []
|
|
22
|
-
RectHelper.drawRoundRect(PathHelper.creator, x, y, width, height, radius)
|
|
23
|
-
data.push(...PathHelper.convertToCanvasData(PathHelper.creator.path, true))
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
arcTo(data: IPathCommandData | null | void, fromX: number, fromY: number, x1: number, y1: number, toX: number, toY: number, radius: number, setPointBounds?: ITwoPointBoundsData, setEndPoint?: IPointData, setStartPoint?: IPointData): void {
|
|
27
|
-
const BAx = x1 - fromX
|
|
28
|
-
const BAy = y1 - fromY
|
|
29
|
-
const CBx = toX - x1
|
|
30
|
-
const CBy = toY - y1
|
|
31
|
-
|
|
32
|
-
let startRadian = atan2(BAy, BAx)
|
|
33
|
-
let endRadian = atan2(CBy, CBx)
|
|
34
|
-
let totalRadian = endRadian - startRadian
|
|
35
|
-
if (totalRadian < 0) totalRadian += PI2
|
|
36
|
-
|
|
37
|
-
if (totalRadian === PI || (abs(BAx + BAy) < 1.e-12) || (abs(CBx + CBy) < 1.e-12)) { // invalid
|
|
38
|
-
if (data) data.push(PathCommandMap.L, x1, y1)
|
|
39
|
-
if (setPointBounds) {
|
|
40
|
-
setPoint(setPointBounds, fromX, fromY)
|
|
41
|
-
addPoint(setPointBounds, x1, y1)
|
|
42
|
-
}
|
|
43
|
-
if (setStartPoint) set(setStartPoint, fromX, fromY)
|
|
44
|
-
if (setEndPoint) set(setEndPoint, x1, y1)
|
|
45
|
-
return
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const anticlockwise = BAx * CBy - CBx * BAy < 0
|
|
49
|
-
const sign = anticlockwise ? -1 : 1
|
|
50
|
-
const c = radius / cos(totalRadian / 2)
|
|
51
|
-
|
|
52
|
-
const centerX = x1 + c * cos(startRadian + totalRadian / 2 + PI_2 * sign)
|
|
53
|
-
const centerY = y1 + c * sin(startRadian + totalRadian / 2 + PI_2 * sign)
|
|
54
|
-
startRadian -= PI_2 * sign
|
|
55
|
-
endRadian -= PI_2 * sign
|
|
56
|
-
|
|
57
|
-
return ellipse(data, centerX, centerY, radius, radius, 0, startRadian / OneRadian, endRadian / OneRadian, anticlockwise, setPointBounds, setEndPoint, setStartPoint)
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
arc(data: IPathCommandData | null | void, x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean, setPointBounds?: ITwoPointBoundsData, setEndPoint?: IPointData, setStartPoint?: IPointData): void {
|
|
61
|
-
return ellipse(data, x, y, radius, radius, 0, startAngle, endAngle, anticlockwise, setPointBounds, setEndPoint, setStartPoint)
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
ellipse(data: IPathCommandData | null | void, cx: number, cy: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, anticlockwise?: boolean, setPointBounds?: ITwoPointBoundsData, setEndPoint?: IPointData, setStartPoint?: IPointData): void {
|
|
65
|
-
const rotationRadian = rotation * OneRadian
|
|
66
|
-
const rotationSin = sin(rotationRadian)
|
|
67
|
-
const rotationCos = cos(rotationRadian)
|
|
68
|
-
|
|
69
|
-
let startRadian = startAngle * OneRadian
|
|
70
|
-
let endRadian = endAngle * OneRadian
|
|
71
|
-
|
|
72
|
-
if (startRadian > PI) startRadian -= PI2
|
|
73
|
-
if (endRadian < 0) endRadian += PI2
|
|
74
|
-
|
|
75
|
-
let totalRadian = endRadian - startRadian
|
|
76
|
-
if (totalRadian < 0) totalRadian += PI2
|
|
77
|
-
else if (totalRadian > PI2) totalRadian -= PI2
|
|
78
|
-
|
|
79
|
-
if (anticlockwise) totalRadian -= PI2
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const parts = ceil(abs(totalRadian / PI_2))
|
|
83
|
-
const partRadian = totalRadian / parts
|
|
84
|
-
const partRadian4Sin = sin(partRadian / 4)
|
|
85
|
-
const control = 8 / 3 * partRadian4Sin * partRadian4Sin / sin(partRadian / 2)
|
|
86
|
-
|
|
87
|
-
endRadian = startRadian + partRadian
|
|
88
|
-
|
|
89
|
-
let startCos = cos(startRadian)
|
|
90
|
-
let startSin = sin(startRadian)
|
|
91
|
-
let endCos: number, endSin: number
|
|
92
|
-
|
|
93
|
-
let x: number, y: number, x1: number, y1: number, x2: number, y2: number
|
|
94
|
-
|
|
95
|
-
let startX = x = rotationCos * radiusX * startCos - rotationSin * radiusY * startSin
|
|
96
|
-
let startY = y = rotationSin * radiusX * startCos + rotationCos * radiusY * startSin
|
|
97
|
-
|
|
98
|
-
let fromX = cx + x, fromY = cy + y
|
|
99
|
-
|
|
100
|
-
if (data) data.push(PathCommandMap.L, fromX, fromY)
|
|
101
|
-
if (setPointBounds) setPoint(setPointBounds, fromX, fromY)
|
|
102
|
-
if (setStartPoint) set(setStartPoint, fromX, fromY)
|
|
103
|
-
|
|
104
|
-
for (let i = 0; i < parts; i++) {
|
|
105
|
-
|
|
106
|
-
endCos = cos(endRadian)
|
|
107
|
-
endSin = sin(endRadian)
|
|
108
|
-
|
|
109
|
-
x = rotationCos * radiusX * endCos - rotationSin * radiusY * endSin
|
|
110
|
-
y = rotationSin * radiusX * endCos + rotationCos * radiusY * endSin
|
|
111
|
-
x1 = cx + startX - control * (rotationCos * radiusX * startSin + rotationSin * radiusY * startCos)
|
|
112
|
-
y1 = cy + startY - control * (rotationSin * radiusX * startSin - rotationCos * radiusY * startCos)
|
|
113
|
-
x2 = cx + x + control * (rotationCos * radiusX * endSin + rotationSin * radiusY * endCos)
|
|
114
|
-
y2 = cy + y + control * (rotationSin * radiusX * endSin - rotationCos * radiusY * endCos)
|
|
115
|
-
|
|
116
|
-
if (data) data.push(PathCommandMap.C, x1, y1, x2, y2, cx + x, cy + y)
|
|
117
|
-
if (setPointBounds) toTwoPointBounds(cx + startX, cy + startY, x1, y1, x2, y2, cx + x, cy + y, setPointBounds, true)
|
|
118
|
-
|
|
119
|
-
startX = x
|
|
120
|
-
startY = y
|
|
121
|
-
startCos = endCos
|
|
122
|
-
startSin = endSin
|
|
123
|
-
startRadian = endRadian
|
|
124
|
-
endRadian += partRadian
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (setEndPoint) set(setEndPoint, cx + x, cy + y)
|
|
128
|
-
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
quadraticCurveTo(data: IPathCommandData, fromX: number, fromY: number, x1: number, y1: number, toX: number, toY: number): void {
|
|
132
|
-
data.push(PathCommandMap.C, (fromX + 2 * x1) / 3, (fromY + 2 * y1) / 3, (toX + 2 * x1) / 3, (toY + 2 * y1) / 3, toX, toY)
|
|
133
|
-
},
|
|
134
|
-
|
|
135
|
-
toTwoPointBoundsByQuadraticCurve(fromX: number, fromY: number, x1: number, y1: number, toX: number, toY: number, pointBounds: ITwoPointBoundsData, addMode?: boolean): void {
|
|
136
|
-
toTwoPointBounds(fromX, fromY, (fromX + 2 * x1) / 3, (fromY + 2 * y1) / 3, (toX + 2 * x1) / 3, (toY + 2 * y1) / 3, toX, toY, pointBounds, addMode)
|
|
137
|
-
},
|
|
138
|
-
|
|
139
|
-
toTwoPointBounds(fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number, pointBounds: ITwoPointBoundsData, addMode?: boolean): void {
|
|
140
|
-
|
|
141
|
-
const tList = []
|
|
142
|
-
let a, b, c, t, t1, t2, v, sqrtV
|
|
143
|
-
let f = fromX, z1 = x1, z2 = x2, o = toX
|
|
144
|
-
|
|
145
|
-
for (let i = 0; i < 2; ++i) {
|
|
146
|
-
|
|
147
|
-
if (i == 1) {
|
|
148
|
-
f = fromY, z1 = y1, z2 = y2, o = toY
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
a = -3 * f + 9 * z1 - 9 * z2 + 3 * o
|
|
152
|
-
b = 6 * f - 12 * z1 + 6 * z2
|
|
153
|
-
c = 3 * z1 - 3 * f
|
|
154
|
-
|
|
155
|
-
if (Math.abs(a) < 1e-12) {
|
|
156
|
-
if (Math.abs(b) < 1e-12) continue
|
|
157
|
-
t = -c / b
|
|
158
|
-
if (0 < t && t < 1) tList.push(t)
|
|
159
|
-
continue
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
v = b * b - 4 * c * a
|
|
163
|
-
sqrtV = Math.sqrt(v)
|
|
164
|
-
if (v < 0) continue
|
|
165
|
-
|
|
166
|
-
t1 = (-b + sqrtV) / (2 * a)
|
|
167
|
-
if (0 < t1 && t1 < 1) tList.push(t1)
|
|
168
|
-
t2 = (-b - sqrtV) / (2 * a)
|
|
169
|
-
if (0 < t2 && t2 < 1) tList.push(t2)
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
addMode ? addPoint(pointBounds, fromX, fromY) : setPoint(pointBounds, fromX, fromY)
|
|
173
|
-
addPoint(pointBounds, toX, toY)
|
|
174
|
-
|
|
175
|
-
for (let i = 0, len = tList.length; i < len; i++) {
|
|
176
|
-
getPointAndSet(tList[i], fromX, fromY, x1, y1, x2, y2, toX, toY, tempPoint)
|
|
177
|
-
addPoint(pointBounds, tempPoint.x, tempPoint.y)
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
},
|
|
181
|
-
|
|
182
|
-
getPointAndSet(t: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number, setPoint: IPointData): void {
|
|
183
|
-
const o = 1 - t, a = o * o * o, b = 3 * o * o * t, c = 3 * o * t * t, d = t * t * t
|
|
184
|
-
setPoint.x = a * fromX + b * x1 + c * x2 + d * toX
|
|
185
|
-
setPoint.y = a * fromY + b * y1 + c * y2 + d * toY
|
|
186
|
-
},
|
|
187
|
-
|
|
188
|
-
getPoint(t: number, fromX: number, fromY: number, x1: number, y1: number, x2: number, y2: number, toX: number, toY: number): IPointData {
|
|
189
|
-
const point = {} as IPointData
|
|
190
|
-
getPointAndSet(t, fromX, fromY, x1, y1, x2, y2, toX, toY, point)
|
|
191
|
-
return point
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const { getPointAndSet, toTwoPointBounds, ellipse } = BezierHelper
|
package/src/EllipseHelper.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { IPathCommandData } from '@leafer/interface'
|
|
2
|
-
import { OneRadian, PI2 } from '@leafer/math'
|
|
3
|
-
|
|
4
|
-
import { PathCommandMap } from './PathCommandMap'
|
|
5
|
-
import { BezierHelper } from './BezierHelper'
|
|
6
|
-
|
|
7
|
-
const { sin, cos, sqrt, atan2 } = Math
|
|
8
|
-
const { ellipse } = BezierHelper
|
|
9
|
-
|
|
10
|
-
export const EllipseHelper = {
|
|
11
|
-
|
|
12
|
-
// svg
|
|
13
|
-
ellipticalArc(data: IPathCommandData, fromX: number, fromY: number, radiusX: number, radiusY: number, rotation: number, largeFlag: number, sweepFlag: number, toX: number, toY: number, curveMode?: boolean): void {
|
|
14
|
-
|
|
15
|
-
const halfX = (toX - fromX) / 2
|
|
16
|
-
const halfY = (toY - fromY) / 2
|
|
17
|
-
|
|
18
|
-
const rotationRadian = rotation * OneRadian
|
|
19
|
-
const rotationSin = sin(rotationRadian)
|
|
20
|
-
const rotationCos = cos(rotationRadian)
|
|
21
|
-
|
|
22
|
-
const px = -rotationCos * halfX - rotationSin * halfY
|
|
23
|
-
const py = -rotationCos * halfY + rotationSin * halfX
|
|
24
|
-
const rxSquare = radiusX * radiusX
|
|
25
|
-
const rySquare = radiusY * radiusY
|
|
26
|
-
const pySquare = py * py
|
|
27
|
-
const pxSquare = px * px
|
|
28
|
-
|
|
29
|
-
const a = rxSquare * rySquare - rxSquare * pySquare - rySquare * pxSquare
|
|
30
|
-
let s = 0
|
|
31
|
-
|
|
32
|
-
if (a < 0) {
|
|
33
|
-
const t = sqrt(1 - a / (rxSquare * rySquare))
|
|
34
|
-
radiusX *= t
|
|
35
|
-
radiusY *= t
|
|
36
|
-
} else {
|
|
37
|
-
s = (largeFlag === sweepFlag ? -1 : 1) * sqrt(a / (rxSquare * pySquare + rySquare * pxSquare))
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const cx = s * radiusX * py / radiusY
|
|
41
|
-
const cy = -s * radiusY * px / radiusX
|
|
42
|
-
|
|
43
|
-
const startRadian = atan2((py - cy) / radiusY, (px - cx) / radiusX)
|
|
44
|
-
const endRadian = atan2((-py - cy) / radiusY, (-px - cx) / radiusX)
|
|
45
|
-
|
|
46
|
-
let totalRadian = endRadian - startRadian
|
|
47
|
-
|
|
48
|
-
if (sweepFlag === 0 && totalRadian > 0) {
|
|
49
|
-
totalRadian -= PI2
|
|
50
|
-
} else if (sweepFlag === 1 && totalRadian < 0) {
|
|
51
|
-
totalRadian += PI2
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const centerX = fromX + halfX + rotationCos * cx - rotationSin * cy
|
|
55
|
-
const centerY = fromY + halfY + rotationSin * cx + rotationCos * cy
|
|
56
|
-
|
|
57
|
-
const anticlockwise = totalRadian < 0 ? 1 : 0
|
|
58
|
-
|
|
59
|
-
if (curveMode) {
|
|
60
|
-
ellipse(data, centerX, centerY, radiusX, radiusY, rotation, startRadian / OneRadian, endRadian / OneRadian, anticlockwise as unknown as boolean)
|
|
61
|
-
} else {
|
|
62
|
-
if (radiusX === radiusY && !rotation) {
|
|
63
|
-
data.push(PathCommandMap.O, centerX, centerY, radiusX, startRadian / OneRadian, endRadian / OneRadian, anticlockwise)
|
|
64
|
-
} else {
|
|
65
|
-
data.push(PathCommandMap.G, centerX, centerY, radiusX, radiusY, rotation, startRadian / OneRadian, endRadian / OneRadian, anticlockwise)
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
}
|
package/src/PathBounds.ts
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { ITwoPointBoundsData, IPathCommandData, IBoundsData, IPointData } from '@leafer/interface'
|
|
2
|
-
import { TwoPointBoundsHelper } from '@leafer/math'
|
|
3
|
-
import { Debug } from '@leafer/debug'
|
|
4
|
-
|
|
5
|
-
import { BezierHelper } from './BezierHelper'
|
|
6
|
-
import { PathCommandMap as Command } from './PathCommandMap'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const { M, L, C, Q, Z, N, D, X, G, F, O, P, U } = Command
|
|
10
|
-
const { toTwoPointBounds, toTwoPointBoundsByQuadraticCurve, arcTo, arc, ellipse } = BezierHelper
|
|
11
|
-
const { add, copy, addPoint, setPoint, addBounds, toBounds } = TwoPointBoundsHelper
|
|
12
|
-
const debug = Debug.get('PathBounds')
|
|
13
|
-
|
|
14
|
-
let radius: number, radiusX: number, radiusY: number
|
|
15
|
-
const tempPointBounds = {} as ITwoPointBoundsData
|
|
16
|
-
const setPointBounds = {} as ITwoPointBoundsData
|
|
17
|
-
const setEndPoint = {} as IPointData
|
|
18
|
-
|
|
19
|
-
export const PathBounds = {
|
|
20
|
-
|
|
21
|
-
toBounds(data: IPathCommandData, setBounds: IBoundsData): void {
|
|
22
|
-
PathBounds.toTwoPointBounds(data, setPointBounds)
|
|
23
|
-
toBounds(setPointBounds, setBounds)
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
toTwoPointBounds(data: IPathCommandData, setPointBounds: ITwoPointBoundsData): void {
|
|
27
|
-
if (!data || !data.length) return setPoint(setPointBounds, 0, 0)
|
|
28
|
-
|
|
29
|
-
let command: number
|
|
30
|
-
let i: number = 0, x: number = 0, y: number = 0, x1: number, y1: number, toX: number, toY: number
|
|
31
|
-
|
|
32
|
-
const len = data.length
|
|
33
|
-
|
|
34
|
-
while (i < len) {
|
|
35
|
-
command = data[i]
|
|
36
|
-
|
|
37
|
-
if (i === 0) {
|
|
38
|
-
if (command === Z || command === C || command === Q) {
|
|
39
|
-
setPoint(setPointBounds, x, y)
|
|
40
|
-
} else {
|
|
41
|
-
setPoint(setPointBounds, data[i + 1], data[i + 2])
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
switch (command) {
|
|
46
|
-
case M: //moveto(x, y)
|
|
47
|
-
case L: //lineto(x, y)
|
|
48
|
-
x = data[i + 1]
|
|
49
|
-
y = data[i + 2]
|
|
50
|
-
addPoint(setPointBounds, x, y)
|
|
51
|
-
i += 3
|
|
52
|
-
break
|
|
53
|
-
case C: //bezierCurveTo(x1, y1, x2, y2, x,y)
|
|
54
|
-
toX = data[i + 5]
|
|
55
|
-
toY = data[i + 6]
|
|
56
|
-
toTwoPointBounds(x, y, data[i + 1], data[i + 2], data[i + 3], data[i + 4], toX, toY, tempPointBounds)
|
|
57
|
-
add(setPointBounds, tempPointBounds)
|
|
58
|
-
x = toX
|
|
59
|
-
y = toY
|
|
60
|
-
i += 7
|
|
61
|
-
break
|
|
62
|
-
case Q: //quadraticCurveTo(x1, y1, x, y)
|
|
63
|
-
x1 = data[i + 1]
|
|
64
|
-
y1 = data[i + 2]
|
|
65
|
-
toX = data[i + 3]
|
|
66
|
-
toY = data[i + 4]
|
|
67
|
-
toTwoPointBoundsByQuadraticCurve(x, y, x1, y1, toX, toY, tempPointBounds)
|
|
68
|
-
add(setPointBounds, tempPointBounds)
|
|
69
|
-
x = toX
|
|
70
|
-
y = toY
|
|
71
|
-
i += 5
|
|
72
|
-
break
|
|
73
|
-
case Z: //closepath()
|
|
74
|
-
i += 1
|
|
75
|
-
break
|
|
76
|
-
|
|
77
|
-
// canvas command
|
|
78
|
-
|
|
79
|
-
case N: // rect(x, y, width, height)
|
|
80
|
-
x = data[i + 1]
|
|
81
|
-
y = data[i + 2]
|
|
82
|
-
addBounds(setPointBounds, x, y, data[i + 3], data[i + 4])
|
|
83
|
-
i += 5
|
|
84
|
-
break
|
|
85
|
-
case D: // roundRect(x, y, width, height, radius1, radius2, radius3, radius4)
|
|
86
|
-
case X: // simple roundRect(x, y, width, height, radius)
|
|
87
|
-
x = data[i + 1]
|
|
88
|
-
y = data[i + 2]
|
|
89
|
-
addBounds(setPointBounds, x, y, data[i + 3], data[i + 4])
|
|
90
|
-
i += (command === D ? 9 : 6)
|
|
91
|
-
break
|
|
92
|
-
case G: // ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)
|
|
93
|
-
ellipse(null, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6], data[i + 7], data[i + 8] as unknown as boolean, tempPointBounds, setEndPoint)
|
|
94
|
-
i === 0 ? copy(setPointBounds, tempPointBounds) : add(setPointBounds, tempPointBounds)
|
|
95
|
-
x = setEndPoint.x
|
|
96
|
-
y = setEndPoint.y
|
|
97
|
-
i += 9
|
|
98
|
-
break
|
|
99
|
-
case F: // simple ellipse(x, y, radiusX, radiusY)
|
|
100
|
-
x = data[i + 1]
|
|
101
|
-
y = data[i + 2]
|
|
102
|
-
radiusX = data[i + 3]
|
|
103
|
-
radiusY = data[i + 4]
|
|
104
|
-
addBounds(setPointBounds, x - radiusX, y - radiusY, radiusX * 2, radiusY * 2)
|
|
105
|
-
x += radiusX
|
|
106
|
-
i += 5
|
|
107
|
-
break
|
|
108
|
-
case O: // arc(x, y, radius, startAngle, endAngle, anticlockwise)
|
|
109
|
-
arc(null, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6] as unknown as boolean, tempPointBounds, setEndPoint)
|
|
110
|
-
i === 0 ? copy(setPointBounds, tempPointBounds) : add(setPointBounds, tempPointBounds)
|
|
111
|
-
x = setEndPoint.x
|
|
112
|
-
y = setEndPoint.y
|
|
113
|
-
i += 7
|
|
114
|
-
break
|
|
115
|
-
case P: // simple arc(x, y, radius)
|
|
116
|
-
x = data[i + 1]
|
|
117
|
-
y = data[i + 2]
|
|
118
|
-
radius = data[i + 3]
|
|
119
|
-
addBounds(setPointBounds, x - radius, y - radius, radius * 2, radius * 2)
|
|
120
|
-
x += radius
|
|
121
|
-
i += 4
|
|
122
|
-
break
|
|
123
|
-
case U: // arcTo(x1, y1, x2, y2, radius)
|
|
124
|
-
arcTo(null, x, y, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], tempPointBounds, setEndPoint)
|
|
125
|
-
i === 0 ? copy(setPointBounds, tempPointBounds) : add(setPointBounds, tempPointBounds)
|
|
126
|
-
x = setEndPoint.x
|
|
127
|
-
y = setEndPoint.y
|
|
128
|
-
i += 6
|
|
129
|
-
break
|
|
130
|
-
default:
|
|
131
|
-
debug.error(`command: ${command} [index:${i}]`, data)
|
|
132
|
-
return
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { IPathCommandData, IPointData } from '@leafer/interface'
|
|
2
|
-
import { PathCommandMap } from './PathCommandMap'
|
|
3
|
-
import { BezierHelper } from './BezierHelper'
|
|
4
|
-
import { MathHelper } from '@leafer/math'
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const { M, L, C, Q, Z, N, D, X, G, F, O, P, U } = PathCommandMap
|
|
8
|
-
const startPoint = {} as IPointData
|
|
9
|
-
|
|
10
|
-
export const PathCommandDataHelper = {
|
|
11
|
-
|
|
12
|
-
beginPath(data: IPathCommandData): void {
|
|
13
|
-
data.length = 0
|
|
14
|
-
},
|
|
15
|
-
|
|
16
|
-
// svg and canvas
|
|
17
|
-
|
|
18
|
-
moveTo(data: IPathCommandData, x: number, y: number): void {
|
|
19
|
-
data.push(M, x, y)
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
lineTo(data: IPathCommandData, x: number, y: number): void {
|
|
23
|
-
data.push(L, x, y)
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
bezierCurveTo(data: IPathCommandData, x1: number, y1: number, x2: number, y2: number, x: number, y: number): void {
|
|
27
|
-
data.push(C, x1, y1, x2, y2, x, y)
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
quadraticCurveTo(data: IPathCommandData, x1: number, y1: number, x: number, y: number): void {
|
|
31
|
-
data.push(Q, x1, y1, x, y)
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
closePath(data: IPathCommandData): void {
|
|
35
|
-
data.push(Z)
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
// canvas
|
|
39
|
-
|
|
40
|
-
rect(data: IPathCommandData, x: number, y: number, width: number, height: number): void {
|
|
41
|
-
data.push(N, x, y, width, height)
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
roundRect(data: IPathCommandData, x: number, y: number, width: number, height: number, cornerRadius: number | number[]): void {
|
|
45
|
-
if (typeof cornerRadius === 'number') {
|
|
46
|
-
data.push(X, x, y, width, height, cornerRadius)
|
|
47
|
-
} else {
|
|
48
|
-
const fourCorners = MathHelper.fourNumber(cornerRadius)
|
|
49
|
-
if (fourCorners) {
|
|
50
|
-
data.push(D, x, y, width, height, ...fourCorners)
|
|
51
|
-
} else {
|
|
52
|
-
data.push(N, x, y, width, height)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
ellipse(data: IPathCommandData, x: number, y: number, radiusX: number, radiusY: number, rotation?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void {
|
|
58
|
-
if (rotation === undefined) {
|
|
59
|
-
data.push(F, x, y, radiusX, radiusY)
|
|
60
|
-
} else {
|
|
61
|
-
if (startAngle === undefined) startAngle = 0
|
|
62
|
-
if (endAngle === undefined) endAngle = 360
|
|
63
|
-
data.push(G, x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise ? 1 : 0)
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
|
|
67
|
-
arc(data: IPathCommandData, x: number, y: number, radius: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void {
|
|
68
|
-
if (startAngle === undefined) {
|
|
69
|
-
data.push(P, x, y, radius)
|
|
70
|
-
} else {
|
|
71
|
-
if (endAngle === undefined) endAngle = 360
|
|
72
|
-
data.push(O, x, y, radius, startAngle, endAngle, anticlockwise ? 1 : 0)
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
moveToEllipse(data: IPathCommandData, x: number, y: number, radiusX: number, radiusY: number, rotation?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void {
|
|
77
|
-
if (rotation === undefined) rotation = 0
|
|
78
|
-
if (startAngle === undefined) startAngle = 0
|
|
79
|
-
if (endAngle === undefined) endAngle = 360
|
|
80
|
-
BezierHelper.ellipse(null, x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise, null, null, startPoint)
|
|
81
|
-
data.push(M, startPoint.x, startPoint.y)
|
|
82
|
-
ellipse(data, x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
moveToArc(data: IPathCommandData, x: number, y: number, radius: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void {
|
|
86
|
-
if (startAngle === undefined) startAngle = 0
|
|
87
|
-
if (endAngle === undefined) endAngle = 360
|
|
88
|
-
BezierHelper.arc(null, x, y, radius, startAngle, endAngle, anticlockwise, null, null, startPoint)
|
|
89
|
-
data.push(M, startPoint.x, startPoint.y)
|
|
90
|
-
arc(data, x, y, radius, startAngle, endAngle, anticlockwise)
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
arcTo(data: IPathCommandData, x1: number, y1: number, x2: number, y2: number, radius: number): void {
|
|
94
|
-
data.push(U, x1, y1, x2, y2, radius)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const { ellipse, arc } = PathCommandDataHelper
|
package/src/PathCommandMap.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { INumberMap, IStringMap } from '@leafer/interface'
|
|
2
|
-
|
|
3
|
-
export const CanvasCommandOnlyMap: INumberMap = {
|
|
4
|
-
|
|
5
|
-
N: 21, // rect
|
|
6
|
-
D: 22, // roundRect
|
|
7
|
-
X: 23, // simple roundRect
|
|
8
|
-
G: 24, // ellipse
|
|
9
|
-
F: 25, // simple ellipse
|
|
10
|
-
O: 26, // arc
|
|
11
|
-
P: 27, // simple arc
|
|
12
|
-
U: 28 // arcTo
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const PathCommandMap: INumberMap = {
|
|
17
|
-
|
|
18
|
-
// svg and canvas
|
|
19
|
-
|
|
20
|
-
M: 1, // moveto
|
|
21
|
-
m: 10,
|
|
22
|
-
L: 2, // lineto
|
|
23
|
-
l: 20,
|
|
24
|
-
H: 3, // horizontal lineto
|
|
25
|
-
h: 30,
|
|
26
|
-
V: 4, // vertical lineto
|
|
27
|
-
v: 40,
|
|
28
|
-
C: 5, // curveto
|
|
29
|
-
c: 50,
|
|
30
|
-
S: 6, // smooth curveto
|
|
31
|
-
s: 60,
|
|
32
|
-
Q: 7, // quadratic Belzier curve
|
|
33
|
-
q: 70,
|
|
34
|
-
T: 8, // smooth quadratic Belzier curveto
|
|
35
|
-
t: 80,
|
|
36
|
-
A: 9, //e lliptical Arc
|
|
37
|
-
a: 90,
|
|
38
|
-
Z: 11, // closepath
|
|
39
|
-
z: 11,
|
|
40
|
-
|
|
41
|
-
R: 12, // Catmull Rom
|
|
42
|
-
|
|
43
|
-
// canvas
|
|
44
|
-
...CanvasCommandOnlyMap
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export const PathCommandLengthMap: INumberMap = {
|
|
48
|
-
|
|
49
|
-
M: 3, //moveto
|
|
50
|
-
m: 3,
|
|
51
|
-
L: 3, //lineto
|
|
52
|
-
l: 3,
|
|
53
|
-
H: 2, //horizontal lineto
|
|
54
|
-
h: 2,
|
|
55
|
-
V: 2, //vertical lineto
|
|
56
|
-
v: 2,
|
|
57
|
-
C: 7, //curveto
|
|
58
|
-
c: 7,
|
|
59
|
-
S: 5, //smooth curveto
|
|
60
|
-
s: 5,
|
|
61
|
-
Q: 5, //quadratic Belzier curve
|
|
62
|
-
q: 5,
|
|
63
|
-
T: 3, //smooth quadratic Belzier curveto
|
|
64
|
-
t: 3,
|
|
65
|
-
A: 8, //elliptical Arc
|
|
66
|
-
a: 8,
|
|
67
|
-
Z: 1, //closepath
|
|
68
|
-
z: 1,
|
|
69
|
-
|
|
70
|
-
// canvas
|
|
71
|
-
|
|
72
|
-
N: 5, // rect
|
|
73
|
-
D: 9, // roundRect
|
|
74
|
-
X: 6, // simple roundRect
|
|
75
|
-
G: 9, // ellipse
|
|
76
|
-
F: 5, // simple ellipse
|
|
77
|
-
O: 7, // arc
|
|
78
|
-
P: 4, // simple arc
|
|
79
|
-
U: 6 // arcTo
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export const NeedConvertToCanvasCommandMap: INumberMap = { // convert to: M L C Q Z
|
|
84
|
-
|
|
85
|
-
// M: 1, //moveto
|
|
86
|
-
m: 10,
|
|
87
|
-
// L: 2, //lineto
|
|
88
|
-
l: 20,
|
|
89
|
-
H: 3, //horizontal lineto
|
|
90
|
-
h: 30,
|
|
91
|
-
V: 4, //vertical lineto
|
|
92
|
-
v: 40,
|
|
93
|
-
// C: 5, //curveto
|
|
94
|
-
c: 50,
|
|
95
|
-
S: 6, //smooth curveto
|
|
96
|
-
s: 60,
|
|
97
|
-
// Q: 7, //quadratic Belzier curve
|
|
98
|
-
q: 70,
|
|
99
|
-
T: 8, //smooth quadratic Belzier curveto
|
|
100
|
-
t: 80,
|
|
101
|
-
A: 9, //elliptical Arc
|
|
102
|
-
a: 90,
|
|
103
|
-
// Z: 11, //closepath
|
|
104
|
-
// z: 11
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
export const NeedConvertToCurveCommandMap: INumberMap = {
|
|
110
|
-
...NeedConvertToCanvasCommandMap,
|
|
111
|
-
...CanvasCommandOnlyMap
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const P = PathCommandMap
|
|
115
|
-
|
|
116
|
-
export const PathNumberCommandMap: IStringMap = {}
|
|
117
|
-
for (let key in P) {
|
|
118
|
-
PathNumberCommandMap[P[key]] = key
|
|
119
|
-
}
|
|
120
|
-
// {1: 'M'}
|
|
121
|
-
|
|
122
|
-
export const PathNumberCommandLengthMap: INumberMap = {}
|
|
123
|
-
for (let key in P) {
|
|
124
|
-
PathNumberCommandLengthMap[P[key]] = PathCommandLengthMap[key]
|
|
125
|
-
}
|
|
126
|
-
// {1: 3}
|
package/src/PathConvert.ts
DELETED
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
import { IPathCommandData, IPointData } from '@leafer/interface'
|
|
2
|
-
import { StringNumberMap } from '@leafer/math'
|
|
3
|
-
import { Debug } from '@leafer/debug'
|
|
4
|
-
|
|
5
|
-
import { PathCommandMap as Command, NeedConvertToCanvasCommandMap, NeedConvertToCurveCommandMap, PathCommandLengthMap, PathNumberCommandMap, PathNumberCommandLengthMap } from './PathCommandMap'
|
|
6
|
-
import { BezierHelper } from './BezierHelper'
|
|
7
|
-
import { EllipseHelper } from './EllipseHelper'
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
interface ICurrentCommand {
|
|
11
|
-
name?: number
|
|
12
|
-
length?: number
|
|
13
|
-
index?: number
|
|
14
|
-
dot?: number
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const { M, m, L, l, H, h, V, v, C, c, S, s, Q, q, T, t, A, a, Z, z, N, D, X, G, F, O, P, U } = Command
|
|
19
|
-
const { rect, roundRect, arcTo, arc, ellipse, quadraticCurveTo } = BezierHelper
|
|
20
|
-
const { ellipticalArc } = EllipseHelper
|
|
21
|
-
const debug = Debug.get('PathConvert')
|
|
22
|
-
|
|
23
|
-
const setEndPoint = {} as IPointData
|
|
24
|
-
|
|
25
|
-
export const PathConvert = {
|
|
26
|
-
|
|
27
|
-
current: { dot: 0 } as ICurrentCommand,
|
|
28
|
-
|
|
29
|
-
stringify(data: IPathCommandData): string {
|
|
30
|
-
let i = 0, len = data.length, count: number, str: string = '', command: number, lastCommand: number
|
|
31
|
-
while (i < len) {
|
|
32
|
-
command = data[i]
|
|
33
|
-
count = PathNumberCommandLengthMap[command]
|
|
34
|
-
if (command === lastCommand) {
|
|
35
|
-
str += ' ' // 重复的命令可以省略
|
|
36
|
-
} else {
|
|
37
|
-
str += PathNumberCommandMap[command]
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
for (let j = 1; j < count; j++) {
|
|
41
|
-
str += data[i + j];
|
|
42
|
-
(j === count - 1) || (str += ' ')
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
lastCommand = command
|
|
46
|
-
i += count
|
|
47
|
-
}
|
|
48
|
-
return str
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
parse(pathString: string, curveMode?: boolean): IPathCommandData {
|
|
52
|
-
|
|
53
|
-
let needConvert: boolean, char: string, lastChar: string, num = ''
|
|
54
|
-
const data: IPathCommandData = []
|
|
55
|
-
const convertCommand = curveMode ? NeedConvertToCurveCommandMap : NeedConvertToCanvasCommandMap
|
|
56
|
-
|
|
57
|
-
for (let i = 0, len = pathString.length; i < len; i++) {
|
|
58
|
-
|
|
59
|
-
char = pathString[i]
|
|
60
|
-
|
|
61
|
-
if (StringNumberMap[char]) {
|
|
62
|
-
|
|
63
|
-
if (char === '.') {
|
|
64
|
-
current.dot++
|
|
65
|
-
if (current.dot > 1) {
|
|
66
|
-
pushData(data, num); num = '' // .375.375
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
num += char
|
|
71
|
-
|
|
72
|
-
} else if (Command[char]) {
|
|
73
|
-
|
|
74
|
-
if (num) { pushData(data, num); num = '' }
|
|
75
|
-
|
|
76
|
-
current.name = Command[char]
|
|
77
|
-
current.length = PathCommandLengthMap[char]
|
|
78
|
-
current.index = 0
|
|
79
|
-
pushData(data, current.name)
|
|
80
|
-
|
|
81
|
-
if (!needConvert && convertCommand[char]) needConvert = true
|
|
82
|
-
|
|
83
|
-
} else {
|
|
84
|
-
|
|
85
|
-
if (char === '-' || char === '+') {
|
|
86
|
-
|
|
87
|
-
if (lastChar === 'e' || lastChar === 'E') { // L45e-12 21e+22
|
|
88
|
-
num += char
|
|
89
|
-
} else {
|
|
90
|
-
if (num) pushData(data, num) // L-34-35 L+12+28
|
|
91
|
-
num = char
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
} else {
|
|
95
|
-
if (num) { pushData(data, num); num = '' }
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
lastChar = char
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (num) pushData(data, num)
|
|
105
|
-
|
|
106
|
-
return needConvert ? PathConvert.toCanvasData(data, curveMode) : data
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
toCanvasData(old: IPathCommandData, curveMode?: boolean): IPathCommandData {
|
|
110
|
-
|
|
111
|
-
let x = 0, y = 0, x1 = 0, y1 = 0, i = 0, len = old.length, controlX: number, controlY: number, command: number, lastCommand: number, smooth: boolean
|
|
112
|
-
const data: IPathCommandData = []
|
|
113
|
-
|
|
114
|
-
while (i < len) {
|
|
115
|
-
|
|
116
|
-
command = old[i]
|
|
117
|
-
|
|
118
|
-
switch (command) {
|
|
119
|
-
//moveto(x, y)
|
|
120
|
-
case m:
|
|
121
|
-
old[i + 1] += x
|
|
122
|
-
old[i + 2] += y
|
|
123
|
-
case M:
|
|
124
|
-
x = old[i + 1]
|
|
125
|
-
y = old[i + 2]
|
|
126
|
-
data.push(M, x, y)
|
|
127
|
-
i += 3
|
|
128
|
-
break
|
|
129
|
-
|
|
130
|
-
//horizontal lineto(x)
|
|
131
|
-
case h:
|
|
132
|
-
old[i + 1] += x
|
|
133
|
-
case H:
|
|
134
|
-
x = old[i + 1]
|
|
135
|
-
data.push(L, x, y)
|
|
136
|
-
i += 2
|
|
137
|
-
break
|
|
138
|
-
|
|
139
|
-
//vertical lineto(y)
|
|
140
|
-
case v:
|
|
141
|
-
old[i + 1] += y
|
|
142
|
-
case V:
|
|
143
|
-
y = old[i + 1]
|
|
144
|
-
data.push(L, x, y)
|
|
145
|
-
i += 2
|
|
146
|
-
break
|
|
147
|
-
|
|
148
|
-
//lineto(x,y)
|
|
149
|
-
case l:
|
|
150
|
-
old[i + 1] += x
|
|
151
|
-
old[i + 2] += y
|
|
152
|
-
case L:
|
|
153
|
-
x = old[i + 1]
|
|
154
|
-
y = old[i + 2]
|
|
155
|
-
data.push(L, x, y)
|
|
156
|
-
i += 3
|
|
157
|
-
break
|
|
158
|
-
|
|
159
|
-
//smooth bezierCurveTo(x2, y2, x, y)
|
|
160
|
-
case s: //smooth
|
|
161
|
-
old[i + 1] += x
|
|
162
|
-
old[i + 2] += y
|
|
163
|
-
old[i + 3] += x
|
|
164
|
-
old[i + 4] += y
|
|
165
|
-
command = S
|
|
166
|
-
case S:
|
|
167
|
-
smooth = (lastCommand === C) || (lastCommand === S)
|
|
168
|
-
x1 = smooth ? (x * 2 - controlX) : old[i + 1]
|
|
169
|
-
y1 = smooth ? (y * 2 - controlY) : old[i + 2]
|
|
170
|
-
controlX = old[i + 1]
|
|
171
|
-
controlY = old[i + 2]
|
|
172
|
-
x = old[i + 3]
|
|
173
|
-
y = old[i + 4]
|
|
174
|
-
data.push(C, x1, y1, controlX, controlY, x, y)
|
|
175
|
-
i += 5
|
|
176
|
-
break
|
|
177
|
-
|
|
178
|
-
//bezierCurveTo(x1, y1, x2, y2, x, y)
|
|
179
|
-
case c:
|
|
180
|
-
old[i + 1] += x
|
|
181
|
-
old[i + 2] += y
|
|
182
|
-
old[i + 3] += x
|
|
183
|
-
old[i + 4] += y
|
|
184
|
-
old[i + 5] += x
|
|
185
|
-
old[i + 6] += y
|
|
186
|
-
command = C
|
|
187
|
-
case C:
|
|
188
|
-
controlX = old[i + 3]
|
|
189
|
-
controlY = old[i + 4]
|
|
190
|
-
x = old[i + 5]
|
|
191
|
-
y = old[i + 6]
|
|
192
|
-
data.push(C, old[i + 1], old[i + 2], controlX, controlY, x, y)
|
|
193
|
-
i += 7
|
|
194
|
-
break
|
|
195
|
-
|
|
196
|
-
//smooth quadraticCurveTo(x, y)
|
|
197
|
-
case t:
|
|
198
|
-
old[i + 1] += x
|
|
199
|
-
old[i + 2] += y
|
|
200
|
-
command = T
|
|
201
|
-
case T: //smooth
|
|
202
|
-
smooth = (lastCommand === Q) || (lastCommand === T)
|
|
203
|
-
controlX = smooth ? (x * 2 - controlX) : old[i + 1]
|
|
204
|
-
controlY = smooth ? (y * 2 - controlY) : old[i + 2]
|
|
205
|
-
curveMode ? quadraticCurveTo(data, x, y, controlX, controlY, old[i + 1], old[i + 2]) : data.push(Q, controlX, controlY, old[i + 1], old[i + 2])
|
|
206
|
-
x = old[i + 1]
|
|
207
|
-
y = old[i + 2]
|
|
208
|
-
i += 3
|
|
209
|
-
break
|
|
210
|
-
|
|
211
|
-
//quadraticCurveTo(x1, y1, x, y)
|
|
212
|
-
case q:
|
|
213
|
-
old[i + 1] += x
|
|
214
|
-
old[i + 2] += y
|
|
215
|
-
old[i + 3] += x
|
|
216
|
-
old[i + 4] += y
|
|
217
|
-
command = Q
|
|
218
|
-
case Q:
|
|
219
|
-
controlX = old[i + 1]
|
|
220
|
-
controlY = old[i + 2]
|
|
221
|
-
curveMode ? quadraticCurveTo(data, x, y, controlX, controlY, old[i + 3], old[i + 4]) : data.push(Q, controlX, controlY, old[i + 3], old[i + 4])
|
|
222
|
-
x = old[i + 3]
|
|
223
|
-
y = old[i + 4]
|
|
224
|
-
i += 5
|
|
225
|
-
break
|
|
226
|
-
|
|
227
|
-
//ellipticalArc(rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y)
|
|
228
|
-
case a:
|
|
229
|
-
old[i + 6] += x
|
|
230
|
-
old[i + 7] += y
|
|
231
|
-
case A:
|
|
232
|
-
ellipticalArc(data, x, y, old[i + 1], old[i + 2], old[i + 3], old[i + 4], old[i + 5], old[i + 6], old[i + 7], curveMode) // convert to canvas ellipse or curve
|
|
233
|
-
x = old[i + 6]
|
|
234
|
-
y = old[i + 7]
|
|
235
|
-
i += 8
|
|
236
|
-
break
|
|
237
|
-
case z:
|
|
238
|
-
case Z:
|
|
239
|
-
data.push(Z)
|
|
240
|
-
i++
|
|
241
|
-
break
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
// canvas command
|
|
245
|
-
|
|
246
|
-
case N: // rect(x, y, width, height)
|
|
247
|
-
x = old[i + 1]
|
|
248
|
-
y = old[i + 2]
|
|
249
|
-
curveMode ? rect(data, x, y, old[i + 3], old[i + 4]) : copyData(data, old, i, 5)
|
|
250
|
-
i += 5
|
|
251
|
-
break
|
|
252
|
-
case D: // roundRect(x, y, width, height, radius1, radius2, radius3, radius4)
|
|
253
|
-
x = old[i + 1]
|
|
254
|
-
y = old[i + 2]
|
|
255
|
-
curveMode ? roundRect(data, x, y, old[i + 3], old[i + 4], [old[i + 5], old[i + 6], old[i + 7], old[i + 8]]) : copyData(data, old, i, 9)
|
|
256
|
-
i += 9
|
|
257
|
-
break
|
|
258
|
-
case X: // simple roundRect(x, y, width, height, radius)
|
|
259
|
-
x = old[i + 1]
|
|
260
|
-
y = old[i + 2]
|
|
261
|
-
curveMode ? roundRect(data, x, y, old[i + 3], old[i + 4], old[i + 5]) : copyData(data, old, i, 6)
|
|
262
|
-
i += 6
|
|
263
|
-
break
|
|
264
|
-
case G: // ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)
|
|
265
|
-
ellipse(curveMode ? data : copyData(data, old, i, 9), old[i + 1], old[i + 2], old[i + 3], old[i + 4], old[i + 5], old[i + 6], old[i + 7], old[i + 8] as unknown as boolean, null, setEndPoint)
|
|
266
|
-
x = setEndPoint.x
|
|
267
|
-
y = setEndPoint.y
|
|
268
|
-
i += 9
|
|
269
|
-
break
|
|
270
|
-
case F: // simple ellipse(x, y, radiusX, radiusY)
|
|
271
|
-
curveMode ? ellipse(data, old[i + 1], old[i + 2], old[i + 3], old[i + 4], 0, 0, 360, false) : copyData(data, old, i, 5)
|
|
272
|
-
x = old[i + 1] + old[i + 3]
|
|
273
|
-
y = old[i + 2]
|
|
274
|
-
i += 5
|
|
275
|
-
break
|
|
276
|
-
case O: // arc(x, y, radius, startAngle, endAngle, anticlockwise)
|
|
277
|
-
arc(curveMode ? data : copyData(data, old, i, 7), old[i + 1], old[i + 2], old[i + 3], old[i + 4], old[i + 5], old[i + 6] as unknown as boolean, null, setEndPoint)
|
|
278
|
-
x = setEndPoint.x
|
|
279
|
-
y = setEndPoint.y
|
|
280
|
-
i += 7
|
|
281
|
-
break
|
|
282
|
-
case P: // simple arc(x, y, radius)
|
|
283
|
-
curveMode ? arc(data, old[i + 1], old[i + 2], old[i + 3], 0, 360, false) : copyData(data, old, i, 4)
|
|
284
|
-
x = old[i + 1] + old[i + 3]
|
|
285
|
-
y = old[i + 2]
|
|
286
|
-
i += 4
|
|
287
|
-
break
|
|
288
|
-
case U: // arcTo(x1, y1, x2, y2, radius)
|
|
289
|
-
arcTo(curveMode ? data : copyData(data, old, i, 6), x, y, old[i + 1], old[i + 2], old[i + 3], old[i + 4], old[i + 5], null, setEndPoint)
|
|
290
|
-
x = setEndPoint.x
|
|
291
|
-
y = setEndPoint.y
|
|
292
|
-
i += 6
|
|
293
|
-
break
|
|
294
|
-
default:
|
|
295
|
-
debug.error(`command: ${command} [index:${i}]`, old)
|
|
296
|
-
return data
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
lastCommand = command
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
return data
|
|
303
|
-
|
|
304
|
-
},
|
|
305
|
-
|
|
306
|
-
copyData(data: IPathCommandData, old: IPathCommandData, index: number, count: number): void {
|
|
307
|
-
for (let i = index, end = index + count; i < end; i++) {
|
|
308
|
-
data.push(old[i])
|
|
309
|
-
}
|
|
310
|
-
},
|
|
311
|
-
|
|
312
|
-
pushData(data: IPathCommandData, strNum: string | number) {
|
|
313
|
-
if (current.index === current.length) { // 单个命令,多个数据的情况
|
|
314
|
-
current.index = 1
|
|
315
|
-
data.push(current.name)
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
data.push(Number(strNum))
|
|
319
|
-
current.index++
|
|
320
|
-
current.dot = 0
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
const { current, pushData, copyData } = PathConvert
|
package/src/PathCorner.ts
DELETED
package/src/PathCreator.ts
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { IPathCommandData, IPathDrawer, IPathString } from '@leafer/interface'
|
|
2
|
-
import { PathCommandDataHelper } from './PathCommandDataHelper'
|
|
3
|
-
import { PathHelper } from './PathHelper'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const { moveTo, lineTo, quadraticCurveTo, bezierCurveTo, closePath, beginPath, rect, roundRect, ellipse, arc, arcTo, moveToEllipse, moveToArc } = PathCommandDataHelper
|
|
7
|
-
|
|
8
|
-
export class PathCreator implements IPathDrawer {
|
|
9
|
-
|
|
10
|
-
public path: IPathCommandData
|
|
11
|
-
|
|
12
|
-
constructor(path?: IPathCommandData | IPathString) {
|
|
13
|
-
if (path) {
|
|
14
|
-
this.path = typeof path === 'string' ? PathHelper.parse(path) : path
|
|
15
|
-
} else {
|
|
16
|
-
this.path = []
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
public beginPath(): PathCreator {
|
|
21
|
-
beginPath(this.path)
|
|
22
|
-
return this
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// svg and canvas
|
|
26
|
-
|
|
27
|
-
public moveTo(x: number, y: number): PathCreator {
|
|
28
|
-
moveTo(this.path, x, y)
|
|
29
|
-
return this
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
public lineTo(x: number, y: number): PathCreator {
|
|
33
|
-
lineTo(this.path, x, y)
|
|
34
|
-
return this
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
public bezierCurveTo(x1: number, y1: number, x2: number, y2: number, x: number, y: number): PathCreator {
|
|
38
|
-
bezierCurveTo(this.path, x1, y1, x2, y2, x, y)
|
|
39
|
-
return this
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
public quadraticCurveTo(x1: number, y1: number, x: number, y: number): PathCreator {
|
|
43
|
-
quadraticCurveTo(this.path, x1, y1, x, y)
|
|
44
|
-
return this
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
public closePath(): PathCreator {
|
|
48
|
-
closePath(this.path)
|
|
49
|
-
return this
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// canvas
|
|
53
|
-
|
|
54
|
-
public rect(x: number, y: number, width: number, height: number): PathCreator {
|
|
55
|
-
rect(this.path, x, y, width, height)
|
|
56
|
-
return this
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
public roundRect(x: number, y: number, width: number, height: number, cornerRadius: number | number[]): PathCreator {
|
|
60
|
-
roundRect(this.path, x, y, width, height, cornerRadius)
|
|
61
|
-
return this
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
public ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): PathCreator {
|
|
65
|
-
ellipse(this.path, x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)
|
|
66
|
-
return this
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
public arc(x: number, y: number, radius: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): PathCreator {
|
|
70
|
-
arc(this.path, x, y, radius, startAngle, endAngle, anticlockwise)
|
|
71
|
-
return this
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
public arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): PathCreator {
|
|
75
|
-
arcTo(this.path, x1, y1, x2, y2, radius)
|
|
76
|
-
return this
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// moveTo, then draw
|
|
80
|
-
|
|
81
|
-
public moveToEllipse(x: number, y: number, radiusX: number, radiusY: number, rotation?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): PathCreator {
|
|
82
|
-
moveToEllipse(this.path, x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)
|
|
83
|
-
return this
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
public moveToArc(x: number, y: number, radius: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): PathCreator {
|
|
87
|
-
moveToArc(this.path, x, y, radius, startAngle, endAngle, anticlockwise)
|
|
88
|
-
return this
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
}
|
package/src/PathDrawer.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { IPathDrawer, IPathCommandData } from '@leafer/interface'
|
|
2
|
-
import { OneRadian, PI2 } from '@leafer/math'
|
|
3
|
-
import { Debug } from '@leafer/debug'
|
|
4
|
-
|
|
5
|
-
import { PathCommandMap as Command } from './PathCommandMap'
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const { M, L, C, Q, Z, N, D, X, G, F, O, P, U } = Command
|
|
9
|
-
const debug = Debug.get('PathDrawer')
|
|
10
|
-
|
|
11
|
-
export const PathDrawer = {
|
|
12
|
-
|
|
13
|
-
drawPathByData(drawer: IPathDrawer, data: IPathCommandData): void {
|
|
14
|
-
if (!data) return
|
|
15
|
-
|
|
16
|
-
let command: number
|
|
17
|
-
let i = 0, len = data.length
|
|
18
|
-
|
|
19
|
-
while (i < len) {
|
|
20
|
-
command = data[i]
|
|
21
|
-
switch (command) {
|
|
22
|
-
case M: //moveto(x, y)
|
|
23
|
-
drawer.moveTo(data[i + 1], data[i + 2])
|
|
24
|
-
i += 3
|
|
25
|
-
break
|
|
26
|
-
case L: //lineto(x, y)
|
|
27
|
-
drawer.lineTo(data[i + 1], data[i + 2])
|
|
28
|
-
i += 3
|
|
29
|
-
break
|
|
30
|
-
case C: //bezierCurveTo(x1, y1, x2, y2, x, y)
|
|
31
|
-
drawer.bezierCurveTo(data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])
|
|
32
|
-
i += 7
|
|
33
|
-
break
|
|
34
|
-
case Q: //quadraticCurveTo(x1, y1, x, y)
|
|
35
|
-
drawer.quadraticCurveTo(data[i + 1], data[i + 2], data[i + 3], data[i + 4])
|
|
36
|
-
i += 5
|
|
37
|
-
break
|
|
38
|
-
case Z: //closepath()
|
|
39
|
-
drawer.closePath()
|
|
40
|
-
i += 1
|
|
41
|
-
break
|
|
42
|
-
|
|
43
|
-
// canvas command
|
|
44
|
-
|
|
45
|
-
case N: // rect(x, y, width, height)
|
|
46
|
-
drawer.rect(data[i + 1], data[i + 2], data[i + 3], data[i + 4])
|
|
47
|
-
i += 5
|
|
48
|
-
break
|
|
49
|
-
case D: // roundRect(x, y, width, height, radius1, radius2, radius3, radius4)
|
|
50
|
-
drawer.roundRect(data[i + 1], data[i + 2], data[i + 3], data[i + 4], [data[i + 5], data[i + 6], data[i + 7], data[i + 8]])
|
|
51
|
-
i += 9
|
|
52
|
-
break
|
|
53
|
-
case X: // simple roundRect(x, y, width, height, radius)
|
|
54
|
-
drawer.roundRect(data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5])
|
|
55
|
-
i += 6
|
|
56
|
-
break
|
|
57
|
-
case G: // ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)
|
|
58
|
-
drawer.ellipse(data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5] * OneRadian, data[i + 6] * OneRadian, data[i + 7] * OneRadian, data[i + 8] as unknown as boolean)
|
|
59
|
-
i += 9
|
|
60
|
-
break
|
|
61
|
-
case F: // simple ellipse(x, y, radiusX, radiusY)
|
|
62
|
-
drawer.ellipse(data[i + 1], data[i + 2], data[i + 3], data[i + 4], 0, 0, PI2, false)
|
|
63
|
-
i += 5
|
|
64
|
-
break
|
|
65
|
-
case O: // arc(x, y, radius, startAngle, endAngle, anticlockwise)
|
|
66
|
-
drawer.arc(data[i + 1], data[i + 2], data[i + 3], data[i + 4] * OneRadian, data[i + 5] * OneRadian, data[i + 6] as unknown as boolean)
|
|
67
|
-
i += 7
|
|
68
|
-
break
|
|
69
|
-
case P: // simple arc(x, y, radius)
|
|
70
|
-
drawer.arc(data[i + 1], data[i + 2], data[i + 3], 0, PI2, false)
|
|
71
|
-
i += 4
|
|
72
|
-
break
|
|
73
|
-
case U: // arcTo(x1, y1, x2, y2, radius)
|
|
74
|
-
drawer.arcTo(data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5])
|
|
75
|
-
i += 6
|
|
76
|
-
break
|
|
77
|
-
default:
|
|
78
|
-
debug.error(`command: ${command} [index:${i}]`, data)
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
}
|
package/src/PathHelper.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { IPathCommandData, IPathCreator } from '@leafer/interface'
|
|
2
|
-
|
|
3
|
-
export const PathHelper = {
|
|
4
|
-
// index.ts rewrite
|
|
5
|
-
creator: {} as IPathCreator,
|
|
6
|
-
parse(_pathString: string, _curveMode?: boolean): IPathCommandData { return undefined },
|
|
7
|
-
convertToCanvasData(_old: IPathCommandData, _curveMode?: boolean): IPathCommandData { return undefined }
|
|
8
|
-
}
|
package/src/RectHelper.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { IPathDrawer } from '@leafer/interface'
|
|
2
|
-
import { MathHelper } from '@leafer/math'
|
|
3
|
-
|
|
4
|
-
export const RectHelper = {
|
|
5
|
-
|
|
6
|
-
drawRoundRect(drawer: IPathDrawer, x: number, y: number, width: number, height: number, cornerRadius: number | number[]): void {
|
|
7
|
-
let [topLeft, topRight, bottomRight, bottomLeft] = MathHelper.fourNumber(cornerRadius)
|
|
8
|
-
|
|
9
|
-
const max = Math.min(width / 2, height / 2)
|
|
10
|
-
if (topLeft > max) topLeft = max
|
|
11
|
-
if (topRight > max) topRight = max
|
|
12
|
-
if (bottomRight > max) bottomRight = max
|
|
13
|
-
if (bottomLeft > max) bottomLeft = max
|
|
14
|
-
|
|
15
|
-
topLeft ? drawer.moveTo(x + topLeft, y) : drawer.moveTo(x, y)
|
|
16
|
-
topRight ? drawer.arcTo(x + width, y, x + width, y + height, topRight) : drawer.lineTo(x + width, y)
|
|
17
|
-
bottomRight ? drawer.arcTo(x + width, y + height, x, y + height, bottomRight) : drawer.lineTo(x + width, y + height)
|
|
18
|
-
bottomLeft ? drawer.arcTo(x, y + height, x, y, bottomLeft) : drawer.lineTo(x, y + height)
|
|
19
|
-
topLeft ? drawer.arcTo(x, y, x + width, y, topLeft) : drawer.lineTo(x, y)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
}
|