@leafer/path 1.0.0-rc.6 → 1.0.0-rc.8
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 +4 -4
- package/src/PathBounds.ts +6 -6
- package/src/PathCommandDataHelper.ts +11 -3
- package/src/PathCorner.ts +17 -10
- package/src/PathScaler.ts +93 -0
- package/src/RectHelper.ts +8 -11
- package/src/index.ts +1 -0
- package/types/index.d.ts +7 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafer/path",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.8",
|
|
4
4
|
"description": "@leafer/path",
|
|
5
5
|
"author": "Chao (Leafer) Wan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"leaferjs"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@leafer/math": "1.0.0-rc.
|
|
26
|
-
"@leafer/debug": "1.0.0-rc.
|
|
25
|
+
"@leafer/math": "1.0.0-rc.8",
|
|
26
|
+
"@leafer/debug": "1.0.0-rc.8"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@leafer/interface": "1.0.0-rc.
|
|
29
|
+
"@leafer/interface": "1.0.0-rc.8"
|
|
30
30
|
}
|
|
31
31
|
}
|
package/src/PathBounds.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { PathCommandMap as Command } from './PathCommandMap'
|
|
|
8
8
|
|
|
9
9
|
const { M, L, C, Q, Z, N, D, X, G, F, O, P, U } = Command
|
|
10
10
|
const { toTwoPointBounds, toTwoPointBoundsByQuadraticCurve, arcTo, arc, ellipse } = BezierHelper
|
|
11
|
-
const {
|
|
11
|
+
const { addPointBounds, copy, addPoint, setPoint, addBounds, toBounds } = TwoPointBoundsHelper
|
|
12
12
|
const debug = Debug.get('PathBounds')
|
|
13
13
|
|
|
14
14
|
let radius: number, radiusX: number, radiusY: number
|
|
@@ -54,7 +54,7 @@ export const PathBounds = {
|
|
|
54
54
|
toX = data[i + 5]
|
|
55
55
|
toY = data[i + 6]
|
|
56
56
|
toTwoPointBounds(x, y, data[i + 1], data[i + 2], data[i + 3], data[i + 4], toX, toY, tempPointBounds)
|
|
57
|
-
|
|
57
|
+
addPointBounds(setPointBounds, tempPointBounds)
|
|
58
58
|
x = toX
|
|
59
59
|
y = toY
|
|
60
60
|
i += 7
|
|
@@ -65,7 +65,7 @@ export const PathBounds = {
|
|
|
65
65
|
toX = data[i + 3]
|
|
66
66
|
toY = data[i + 4]
|
|
67
67
|
toTwoPointBoundsByQuadraticCurve(x, y, x1, y1, toX, toY, tempPointBounds)
|
|
68
|
-
|
|
68
|
+
addPointBounds(setPointBounds, tempPointBounds)
|
|
69
69
|
x = toX
|
|
70
70
|
y = toY
|
|
71
71
|
i += 5
|
|
@@ -91,7 +91,7 @@ export const PathBounds = {
|
|
|
91
91
|
break
|
|
92
92
|
case G: // ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)
|
|
93
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) :
|
|
94
|
+
i === 0 ? copy(setPointBounds, tempPointBounds) : addPointBounds(setPointBounds, tempPointBounds)
|
|
95
95
|
x = setEndPoint.x
|
|
96
96
|
y = setEndPoint.y
|
|
97
97
|
i += 9
|
|
@@ -107,7 +107,7 @@ export const PathBounds = {
|
|
|
107
107
|
break
|
|
108
108
|
case O: // arc(x, y, radius, startAngle, endAngle, anticlockwise)
|
|
109
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) :
|
|
110
|
+
i === 0 ? copy(setPointBounds, tempPointBounds) : addPointBounds(setPointBounds, tempPointBounds)
|
|
111
111
|
x = setEndPoint.x
|
|
112
112
|
y = setEndPoint.y
|
|
113
113
|
i += 7
|
|
@@ -122,7 +122,7 @@ export const PathBounds = {
|
|
|
122
122
|
break
|
|
123
123
|
case U: // arcTo(x1, y1, x2, y2, radius)
|
|
124
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) :
|
|
125
|
+
i === 0 ? copy(setPointBounds, tempPointBounds) : addPointBounds(setPointBounds, tempPointBounds)
|
|
126
126
|
x = setEndPoint.x
|
|
127
127
|
y = setEndPoint.y
|
|
128
128
|
i += 6
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { IPathCommandData, IPointData } from '@leafer/interface'
|
|
2
|
+
import { MathHelper, PointHelper } from '@leafer/math'
|
|
3
|
+
|
|
2
4
|
import { PathCommandMap } from './PathCommandMap'
|
|
3
5
|
import { BezierHelper } from './BezierHelper'
|
|
4
|
-
import { MathHelper } from '@leafer/math'
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
const { M, L, C, Q, Z, N, D, X, G, F, O, P, U } = PathCommandMap
|
|
9
|
+
const { getMinDistanceFrom, getRadianFrom } = PointHelper
|
|
10
|
+
const { tan, min, abs } = Math
|
|
8
11
|
const startPoint = {} as IPointData
|
|
9
12
|
|
|
10
13
|
export const PathCommandDataHelper = {
|
|
@@ -73,8 +76,13 @@ export const PathCommandDataHelper = {
|
|
|
73
76
|
}
|
|
74
77
|
},
|
|
75
78
|
|
|
76
|
-
arcTo(data: IPathCommandData, x1: number, y1: number, x2: number, y2: number, radius: number): void {
|
|
77
|
-
|
|
79
|
+
arcTo(data: IPathCommandData, x1: number, y1: number, x2: number, y2: number, radius: number, lastX?: number, lastY?: number): void {
|
|
80
|
+
if (lastX !== undefined) {
|
|
81
|
+
const maxRadius = tan(getRadianFrom(lastX, lastY, x1, y1, x2, y2) / 2) * (getMinDistanceFrom(lastX, lastY, x1, y1, x2, y2) / 2)
|
|
82
|
+
data.push(U, x1, y1, x2, y2, min(radius, abs(maxRadius)))
|
|
83
|
+
} else {
|
|
84
|
+
data.push(U, x1, y1, x2, y2, radius)
|
|
85
|
+
}
|
|
78
86
|
},
|
|
79
87
|
|
|
80
88
|
// new
|
package/src/PathCorner.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { IPathCommandData } from '@leafer/interface'
|
|
2
|
+
import { PointHelper } from '@leafer/math'
|
|
3
|
+
|
|
2
4
|
import { PathCommandMap as Command } from './PathCommandMap'
|
|
5
|
+
import { PathCommandDataHelper } from './PathCommandDataHelper'
|
|
3
6
|
|
|
4
7
|
|
|
5
|
-
const { M, L, C, Z
|
|
8
|
+
const { M, L, C, Z } = Command
|
|
9
|
+
const { getCenterX, getCenterY } = PointHelper
|
|
10
|
+
const { arcTo } = PathCommandDataHelper
|
|
6
11
|
|
|
7
12
|
export const PathCorner = {
|
|
8
13
|
|
|
9
14
|
smooth(data: IPathCommandData, cornerRadius: number, _cornerSmoothing?: number): IPathCommandData {
|
|
10
15
|
let command: number
|
|
11
|
-
let i
|
|
16
|
+
let i = 0, x = 0, y = 0, startX = 0, startY = 0, secondX = 0, secondY = 0, lastX = 0, lastY = 0
|
|
12
17
|
|
|
13
18
|
const len = data.length
|
|
14
19
|
const smooth: IPathCommandData = []
|
|
@@ -17,13 +22,13 @@ export const PathCorner = {
|
|
|
17
22
|
command = data[i]
|
|
18
23
|
switch (command) {
|
|
19
24
|
case M: //moveto(x, y)
|
|
20
|
-
startX = data[i + 1]
|
|
21
|
-
startY = data[i + 2]
|
|
25
|
+
startX = lastX = data[i + 1]
|
|
26
|
+
startY = lastY = data[i + 2]
|
|
22
27
|
i += 3
|
|
23
28
|
if (data[i] === L) { // next lineTo
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
smooth.push(M,
|
|
29
|
+
secondX = data[i + 1]
|
|
30
|
+
secondY = data[i + 2]
|
|
31
|
+
smooth.push(M, getCenterX(startX, secondX), getCenterY(startY, secondY))
|
|
27
32
|
} else {
|
|
28
33
|
smooth.push(M, startX, startY)
|
|
29
34
|
}
|
|
@@ -34,21 +39,23 @@ export const PathCorner = {
|
|
|
34
39
|
i += 3
|
|
35
40
|
switch (data[i]) { // next command
|
|
36
41
|
case L: // lineTo()
|
|
37
|
-
smooth
|
|
42
|
+
arcTo(smooth, x, y, data[i + 1], data[i + 2], cornerRadius, lastX, lastY) // use arcTo(x1, y1, x2, y2, radius)
|
|
38
43
|
break
|
|
39
44
|
case Z: // closePath()
|
|
40
|
-
smooth
|
|
45
|
+
arcTo(smooth, x, y, startX, startY, cornerRadius, lastX, lastY) // use arcTo(x1, y1, x2, y2, radius)
|
|
41
46
|
break
|
|
42
47
|
default:
|
|
43
48
|
smooth.push(L, x, y)
|
|
44
49
|
}
|
|
50
|
+
lastX = x
|
|
51
|
+
lastY = y
|
|
45
52
|
break
|
|
46
53
|
case C: //bezierCurveTo(x1, y1, x2, y2, x, y)
|
|
47
54
|
smooth.push(C, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], data[i + 6])
|
|
48
55
|
i += 7
|
|
49
56
|
break
|
|
50
57
|
case Z: //closepath()
|
|
51
|
-
smooth
|
|
58
|
+
arcTo(smooth, startX, startY, secondX, secondY, cornerRadius, lastX, lastY) // use arcTo(x1, y1, x2, y2, radius)
|
|
52
59
|
smooth.push(Z)
|
|
53
60
|
i += 1
|
|
54
61
|
break
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { IPathCommandData } from '@leafer/interface'
|
|
2
|
+
|
|
3
|
+
import { PathCommandMap as Command } from './PathCommandMap'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const { M, L, C, Q, Z, N, D, X, G, F, O, P, U } = Command
|
|
7
|
+
|
|
8
|
+
export const PathScaler = {
|
|
9
|
+
|
|
10
|
+
scale(data: IPathCommandData, scaleX: number, scaleY: number): void {
|
|
11
|
+
if (!data) return
|
|
12
|
+
|
|
13
|
+
let command: number
|
|
14
|
+
let i = 0, len = data.length
|
|
15
|
+
|
|
16
|
+
while (i < len) {
|
|
17
|
+
command = data[i]
|
|
18
|
+
switch (command) {
|
|
19
|
+
case M: //moveto(x, y)
|
|
20
|
+
scalePoints(data, scaleX, scaleY, i, 1)
|
|
21
|
+
i += 3
|
|
22
|
+
break
|
|
23
|
+
case L: //lineto(x, y)
|
|
24
|
+
scalePoints(data, scaleX, scaleY, i, 1)
|
|
25
|
+
i += 3
|
|
26
|
+
break
|
|
27
|
+
case C: //bezierCurveTo(x1, y1, x2, y2, x, y)
|
|
28
|
+
scalePoints(data, scaleX, scaleY, i, 3)
|
|
29
|
+
i += 7
|
|
30
|
+
break
|
|
31
|
+
case Q: //quadraticCurveTo(x1, y1, x, y)
|
|
32
|
+
scalePoints(data, scaleX, scaleY, i, 2)
|
|
33
|
+
i += 5
|
|
34
|
+
break
|
|
35
|
+
case Z: //closepath()
|
|
36
|
+
i += 1
|
|
37
|
+
break
|
|
38
|
+
|
|
39
|
+
// canvas command
|
|
40
|
+
|
|
41
|
+
case N: // rect(x, y, width, height)
|
|
42
|
+
scalePoints(data, scaleX, scaleY, i, 2)
|
|
43
|
+
i += 5
|
|
44
|
+
break
|
|
45
|
+
case D: // roundRect(x, y, width, height, radius1, radius2, radius3, radius4)
|
|
46
|
+
scalePoints(data, scaleX, scaleY, i, 2)
|
|
47
|
+
i += 9
|
|
48
|
+
break
|
|
49
|
+
case X: // simple roundRect(x, y, width, height, radius)
|
|
50
|
+
scalePoints(data, scaleX, scaleY, i, 2)
|
|
51
|
+
i += 6
|
|
52
|
+
break
|
|
53
|
+
case G: // ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)
|
|
54
|
+
scalePoints(data, scaleX, scaleY, i, 2)
|
|
55
|
+
i += 9
|
|
56
|
+
break
|
|
57
|
+
case F: // simple ellipse(x, y, radiusX, radiusY)
|
|
58
|
+
scalePoints(data, scaleX, scaleY, i, 2)
|
|
59
|
+
i += 5
|
|
60
|
+
break
|
|
61
|
+
case O: // arc(x, y, radius, startAngle, endAngle, anticlockwise)
|
|
62
|
+
data[i] = G // to ellipse
|
|
63
|
+
data.splice(i + 4, 0, data[i + 3], 0)
|
|
64
|
+
scalePoints(data, scaleX, scaleY, i, 2)
|
|
65
|
+
i += 7 + 2
|
|
66
|
+
len += 2
|
|
67
|
+
break
|
|
68
|
+
case P: // simple arc(x, y, radius)
|
|
69
|
+
data[i] = F // to simple ellipse
|
|
70
|
+
data.splice(i + 4, 0, data[i + 3])
|
|
71
|
+
scalePoints(data, scaleX, scaleY, i, 2)
|
|
72
|
+
i += 4 + 1
|
|
73
|
+
len += 1
|
|
74
|
+
break
|
|
75
|
+
case U: // arcTo(x1, y1, x2, y2, radius)
|
|
76
|
+
scalePoints(data, scaleX, scaleY, i, 2)
|
|
77
|
+
i += 6
|
|
78
|
+
break
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
scalePoints(data: IPathCommandData, scaleX: number, scaleY: number, start?: number, pointCount?: number): void {
|
|
85
|
+
for (let i = pointCount ? start + 1 : 0, end = pointCount ? i + pointCount * 2 : data.length; i < end; i += 2) {
|
|
86
|
+
data[i] *= scaleX
|
|
87
|
+
data[i + 1] *= scaleY
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const { scalePoints } = PathScaler
|
package/src/RectHelper.ts
CHANGED
|
@@ -4,19 +4,16 @@ import { MathHelper } from '@leafer/math'
|
|
|
4
4
|
export const RectHelper = {
|
|
5
5
|
|
|
6
6
|
drawRoundRect(drawer: IPathDrawer, x: number, y: number, width: number, height: number, cornerRadius: number | number[]): void {
|
|
7
|
-
|
|
7
|
+
const data = MathHelper.fourNumber(cornerRadius, Math.min(width / 2, height / 2))
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
if (topRight > max) topRight = max
|
|
12
|
-
if (bottomRight > max) bottomRight = max
|
|
13
|
-
if (bottomLeft > max) bottomLeft = max
|
|
9
|
+
const right = x + width
|
|
10
|
+
const bottom = y + height
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
data[0] ? drawer.moveTo(x + data[0], y) : drawer.moveTo(x, y)
|
|
13
|
+
data[1] ? drawer.arcTo(right, y, right, bottom, data[1]) : drawer.lineTo(right, y)
|
|
14
|
+
data[2] ? drawer.arcTo(right, bottom, x, bottom, data[2]) : drawer.lineTo(right, bottom)
|
|
15
|
+
data[3] ? drawer.arcTo(x, bottom, x, y, data[3]) : drawer.lineTo(x, bottom)
|
|
16
|
+
data[0] ? drawer.arcTo(x, y, right, y, data[0]) : drawer.lineTo(x, y)
|
|
20
17
|
}
|
|
21
18
|
|
|
22
19
|
}
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ export { PathConvert } from './PathConvert'
|
|
|
3
3
|
export { PathCreator } from './PathCreator'
|
|
4
4
|
export { PathCommandDataHelper } from './PathCommandDataHelper'
|
|
5
5
|
export { PathDrawer } from './PathDrawer'
|
|
6
|
+
export { PathScaler } from './PathScaler'
|
|
6
7
|
export { PathBounds } from './PathBounds'
|
|
7
8
|
export { PathCorner } from './PathCorner'
|
|
8
9
|
export { BezierHelper } from './BezierHelper'
|
package/types/index.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ declare const PathCommandDataHelper: {
|
|
|
51
51
|
roundRect(data: IPathCommandData, x: number, y: number, width: number, height: number, cornerRadius: number | number[]): void;
|
|
52
52
|
ellipse(data: IPathCommandData, x: number, y: number, radiusX: number, radiusY: number, rotation?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void;
|
|
53
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;
|
|
54
|
+
arcTo(data: IPathCommandData, x1: number, y1: number, x2: number, y2: number, radius: number, lastX?: number, lastY?: number): void;
|
|
55
55
|
drawEllipse(data: IPathCommandData, x: number, y: number, radiusX: number, radiusY: number, rotation?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void;
|
|
56
56
|
drawArc(data: IPathCommandData, x: number, y: number, radius: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void;
|
|
57
57
|
drawPoints(data: IPathCommandData, points: number[], curve?: boolean | number, close?: boolean): void;
|
|
@@ -61,6 +61,11 @@ declare const PathDrawer: {
|
|
|
61
61
|
drawPathByData(drawer: IPathDrawer, data: IPathCommandData): void;
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
+
declare const PathScaler: {
|
|
65
|
+
scale(data: IPathCommandData, scaleX: number, scaleY: number): void;
|
|
66
|
+
scalePoints(data: IPathCommandData, scaleX: number, scaleY: number, start?: number, pointCount?: number): void;
|
|
67
|
+
};
|
|
68
|
+
|
|
64
69
|
declare const PathBounds: {
|
|
65
70
|
toBounds(data: IPathCommandData, setBounds: IBoundsData): void;
|
|
66
71
|
toTwoPointBounds(data: IPathCommandData, setPointBounds: ITwoPointBoundsData): void;
|
|
@@ -97,4 +102,4 @@ declare const NeedConvertToCanvasCommandMap: INumberMap;
|
|
|
97
102
|
declare const PathNumberCommandMap: IStringMap;
|
|
98
103
|
declare const PathNumberCommandLengthMap: INumberMap;
|
|
99
104
|
|
|
100
|
-
export { BezierHelper, EllipseHelper, NeedConvertToCanvasCommandMap, PathBounds, PathCommandDataHelper, PathCommandMap, PathConvert, PathCorner, PathCreator, PathDrawer, PathHelper, PathNumberCommandLengthMap, PathNumberCommandMap, RectHelper };
|
|
105
|
+
export { BezierHelper, EllipseHelper, NeedConvertToCanvasCommandMap, PathBounds, PathCommandDataHelper, PathCommandMap, PathConvert, PathCorner, PathCreator, PathDrawer, PathHelper, PathNumberCommandLengthMap, PathNumberCommandMap, PathScaler, RectHelper };
|