@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leafer/path",
3
- "version": "1.0.0-rc.6",
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.6",
26
- "@leafer/debug": "1.0.0-rc.6"
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.6"
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 { add, copy, addPoint, setPoint, addBounds, toBounds } = TwoPointBoundsHelper
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
- add(setPointBounds, tempPointBounds)
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
- add(setPointBounds, tempPointBounds)
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) : add(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) : add(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) : add(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
- data.push(U, x1, y1, x2, y2, radius)
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, U } = Command
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: number = 0, x: number = 0, y: number = 0, startX: number, startY = 0, centerX: number = 0, centerY: number = 0
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
- centerX = startX + (data[i + 1] - startX) / 2
25
- centerY = startY + (data[i + 2] - startY) / 2
26
- smooth.push(M, centerX, centerY)
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.push(U, x, y, data[i + 1], data[i + 2], cornerRadius) // use arcTo(x1, y1, x2, y2, radius)
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.push(U, x, y, startX, startY, cornerRadius) // use arcTo(x1, y1, x2, y2, radius)
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.push(U, startX, startY, centerX, centerY, cornerRadius) // use arcTo(x1, y1, x2, y2, radius)
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
- let [topLeft, topRight, bottomRight, bottomLeft] = MathHelper.fourNumber(cornerRadius)
7
+ const data = MathHelper.fourNumber(cornerRadius, Math.min(width / 2, height / 2))
8
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
9
+ const right = x + width
10
+ const bottom = y + height
14
11
 
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)
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 };