@leafer/path
Advanced tools
| import { IPathCommandData } from '@leafer/interface' | ||
| import { PathCommandMap as Command } from './PathCommandMap' | ||
| const { M, L, C, Q, Z, N, D, X, G, F, O, P, U } = Command | ||
| export const PathScaler = { | ||
| scale(data: IPathCommandData, scaleX: number, scaleY: number): void { | ||
| if (!data) return | ||
| let command: number | ||
| let i = 0, len = data.length | ||
| while (i < len) { | ||
| command = data[i] | ||
| switch (command) { | ||
| case M: //moveto(x, y) | ||
| scalePoints(data, scaleX, scaleY, i, 1) | ||
| i += 3 | ||
| break | ||
| case L: //lineto(x, y) | ||
| scalePoints(data, scaleX, scaleY, i, 1) | ||
| i += 3 | ||
| break | ||
| case C: //bezierCurveTo(x1, y1, x2, y2, x, y) | ||
| scalePoints(data, scaleX, scaleY, i, 3) | ||
| i += 7 | ||
| break | ||
| case Q: //quadraticCurveTo(x1, y1, x, y) | ||
| scalePoints(data, scaleX, scaleY, i, 2) | ||
| i += 5 | ||
| break | ||
| case Z: //closepath() | ||
| i += 1 | ||
| break | ||
| // canvas command | ||
| case N: // rect(x, y, width, height) | ||
| scalePoints(data, scaleX, scaleY, i, 2) | ||
| i += 5 | ||
| break | ||
| case D: // roundRect(x, y, width, height, radius1, radius2, radius3, radius4) | ||
| scalePoints(data, scaleX, scaleY, i, 2) | ||
| i += 9 | ||
| break | ||
| case X: // simple roundRect(x, y, width, height, radius) | ||
| scalePoints(data, scaleX, scaleY, i, 2) | ||
| i += 6 | ||
| break | ||
| case G: // ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise) | ||
| scalePoints(data, scaleX, scaleY, i, 2) | ||
| console.log('G') | ||
| i += 9 | ||
| break | ||
| case F: // simple ellipse(x, y, radiusX, radiusY) | ||
| scalePoints(data, scaleX, scaleY, i, 2) | ||
| i += 5 | ||
| break | ||
| case O: // arc(x, y, radius, startAngle, endAngle, anticlockwise) | ||
| data[i] = G // to ellipse | ||
| data.splice(i + 4, 0, data[i + 3], 0) | ||
| scalePoints(data, scaleX, scaleY, i, 2) | ||
| i += 7 + 2 | ||
| len += 2 | ||
| break | ||
| case P: // simple arc(x, y, radius) | ||
| data[i] = F // to simple ellipse | ||
| data.splice(i + 4, 0, data[i + 3]) | ||
| scalePoints(data, scaleX, scaleY, i, 2) | ||
| i += 4 + 1 | ||
| len += 1 | ||
| break | ||
| case U: // arcTo(x1, y1, x2, y2, radius) | ||
| scalePoints(data, scaleX, scaleY, i, 2) | ||
| i += 6 | ||
| break | ||
| } | ||
| } | ||
| }, | ||
| scalePoints(data: IPathCommandData, scaleX: number, scaleY: number, start?: number, pointCount?: number): void { | ||
| for (let i = pointCount ? start + 1 : 0, end = pointCount ? i + pointCount * 2 : data.length; i < end; i += 2) { | ||
| data[i] *= scaleX | ||
| data[i + 1] *= scaleY | ||
| } | ||
| } | ||
| } | ||
| const { scalePoints } = PathScaler |
+4
-4
| { | ||
| "name": "@leafer/path", | ||
| "version": "1.0.0-rc.6", | ||
| "version": "1.0.0-rc.7", | ||
| "description": "@leafer/path", | ||
@@ -25,8 +25,8 @@ "author": "Chao (Leafer) Wan", | ||
| "dependencies": { | ||
| "@leafer/math": "1.0.0-rc.6", | ||
| "@leafer/debug": "1.0.0-rc.6" | ||
| "@leafer/math": "1.0.0-rc.7", | ||
| "@leafer/debug": "1.0.0-rc.7" | ||
| }, | ||
| "devDependencies": { | ||
| "@leafer/interface": "1.0.0-rc.6" | ||
| "@leafer/interface": "1.0.0-rc.7" | ||
| } | ||
| } |
+1
-0
@@ -6,2 +6,3 @@ export { PathHelper } from './PathHelper' | ||
| export { PathDrawer } from './PathDrawer' | ||
| export { PathScaler } from './PathScaler' | ||
| export { PathBounds } from './PathBounds' | ||
@@ -8,0 +9,0 @@ export { PathCorner } from './PathCorner' |
@@ -11,3 +11,3 @@ import { ITwoPointBoundsData, IPathCommandData, IBoundsData, IPointData } from '@leafer/interface' | ||
| const { toTwoPointBounds, toTwoPointBoundsByQuadraticCurve, arcTo, arc, ellipse } = BezierHelper | ||
| const { add, copy, addPoint, setPoint, addBounds, toBounds } = TwoPointBoundsHelper | ||
| const { addPointBounds, copy, addPoint, setPoint, addBounds, toBounds } = TwoPointBoundsHelper | ||
| const debug = Debug.get('PathBounds') | ||
@@ -58,3 +58,3 @@ | ||
| toTwoPointBounds(x, y, data[i + 1], data[i + 2], data[i + 3], data[i + 4], toX, toY, tempPointBounds) | ||
| add(setPointBounds, tempPointBounds) | ||
| addPointBounds(setPointBounds, tempPointBounds) | ||
| x = toX | ||
@@ -70,3 +70,3 @@ y = toY | ||
| toTwoPointBoundsByQuadraticCurve(x, y, x1, y1, toX, toY, tempPointBounds) | ||
| add(setPointBounds, tempPointBounds) | ||
| addPointBounds(setPointBounds, tempPointBounds) | ||
| x = toX | ||
@@ -97,3 +97,3 @@ y = toY | ||
| 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) | ||
| i === 0 ? copy(setPointBounds, tempPointBounds) : add(setPointBounds, tempPointBounds) | ||
| i === 0 ? copy(setPointBounds, tempPointBounds) : addPointBounds(setPointBounds, tempPointBounds) | ||
| x = setEndPoint.x | ||
@@ -114,3 +114,3 @@ y = setEndPoint.y | ||
| 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) | ||
| i === 0 ? copy(setPointBounds, tempPointBounds) : add(setPointBounds, tempPointBounds) | ||
| i === 0 ? copy(setPointBounds, tempPointBounds) : addPointBounds(setPointBounds, tempPointBounds) | ||
| x = setEndPoint.x | ||
@@ -130,3 +130,3 @@ y = setEndPoint.y | ||
| arcTo(null, x, y, data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5], tempPointBounds, setEndPoint) | ||
| i === 0 ? copy(setPointBounds, tempPointBounds) : add(setPointBounds, tempPointBounds) | ||
| i === 0 ? copy(setPointBounds, tempPointBounds) : addPointBounds(setPointBounds, tempPointBounds) | ||
| x = setEndPoint.x | ||
@@ -133,0 +133,0 @@ y = setEndPoint.y |
| import { IPathCommandData, IPointData } from '@leafer/interface' | ||
| import { MathHelper, PointHelper } from '@leafer/math' | ||
| import { PathCommandMap } from './PathCommandMap' | ||
| import { BezierHelper } from './BezierHelper' | ||
| import { MathHelper } from '@leafer/math' | ||
| const { M, L, C, Q, Z, N, D, X, G, F, O, P, U } = PathCommandMap | ||
| const { getMinDistanceFrom, getRadianFrom } = PointHelper | ||
| const { tan, min, abs } = Math | ||
| const startPoint = {} as IPointData | ||
@@ -76,4 +79,9 @@ | ||
| arcTo(data: IPathCommandData, x1: number, y1: number, x2: number, y2: number, radius: number): void { | ||
| data.push(U, x1, y1, x2, y2, radius) | ||
| arcTo(data: IPathCommandData, x1: number, y1: number, x2: number, y2: number, radius: number, lastX?: number, lastY?: number): void { | ||
| if (lastX !== undefined) { | ||
| const maxRadius = tan(getRadianFrom(lastX, lastY, x1, y1, x2, y2) / 2) * (getMinDistanceFrom(lastX, lastY, x1, y1, x2, y2) / 2) | ||
| data.push(U, x1, y1, x2, y2, min(radius, abs(maxRadius))) | ||
| } else { | ||
| data.push(U, x1, y1, x2, y2, radius) | ||
| } | ||
| }, | ||
@@ -80,0 +88,0 @@ |
+17
-10
| import { IPathCommandData } from '@leafer/interface' | ||
| import { PointHelper } from '@leafer/math' | ||
| import { PathCommandMap as Command } from './PathCommandMap' | ||
| import { PathCommandDataHelper } from './PathCommandDataHelper' | ||
| const { M, L, C, Z, U } = Command | ||
| const { M, L, C, Z } = Command | ||
| const { getCenterX, getCenterY } = PointHelper | ||
| const { arcTo } = PathCommandDataHelper | ||
@@ -11,3 +16,3 @@ export const PathCorner = { | ||
| let command: number | ||
| let i: number = 0, x: number = 0, y: number = 0, startX: number, startY = 0, centerX: number = 0, centerY: number = 0 | ||
| let i = 0, x = 0, y = 0, startX = 0, startY = 0, secondX = 0, secondY = 0, lastX = 0, lastY = 0 | ||
@@ -21,9 +26,9 @@ const len = data.length | ||
| case M: //moveto(x, y) | ||
| startX = data[i + 1] | ||
| startY = data[i + 2] | ||
| startX = lastX = data[i + 1] | ||
| startY = lastY = data[i + 2] | ||
| i += 3 | ||
| if (data[i] === L) { // next lineTo | ||
| centerX = startX + (data[i + 1] - startX) / 2 | ||
| centerY = startY + (data[i + 2] - startY) / 2 | ||
| smooth.push(M, centerX, centerY) | ||
| secondX = data[i + 1] | ||
| secondY = data[i + 2] | ||
| smooth.push(M, getCenterX(startX, secondX), getCenterY(startY, secondY)) | ||
| } else { | ||
@@ -39,6 +44,6 @@ smooth.push(M, startX, startY) | ||
| case L: // lineTo() | ||
| smooth.push(U, x, y, data[i + 1], data[i + 2], cornerRadius) // use arcTo(x1, y1, x2, y2, radius) | ||
| arcTo(smooth, x, y, data[i + 1], data[i + 2], cornerRadius, lastX, lastY) // use arcTo(x1, y1, x2, y2, radius) | ||
| break | ||
| case Z: // closePath() | ||
| smooth.push(U, x, y, startX, startY, cornerRadius) // use arcTo(x1, y1, x2, y2, radius) | ||
| arcTo(smooth, x, y, startX, startY, cornerRadius, lastX, lastY) // use arcTo(x1, y1, x2, y2, radius) | ||
| break | ||
@@ -48,2 +53,4 @@ default: | ||
| } | ||
| lastX = x | ||
| lastY = y | ||
| break | ||
@@ -55,3 +62,3 @@ case C: //bezierCurveTo(x1, y1, x2, y2, x, y) | ||
| case Z: //closepath() | ||
| smooth.push(U, startX, startY, centerX, centerY, cornerRadius) // use arcTo(x1, y1, x2, y2, radius) | ||
| arcTo(smooth, startX, startY, secondX, secondY, cornerRadius, lastX, lastY) // use arcTo(x1, y1, x2, y2, radius) | ||
| smooth.push(Z) | ||
@@ -58,0 +65,0 @@ i += 1 |
+8
-11
@@ -7,17 +7,14 @@ import { IPathDrawer } from '@leafer/interface' | ||
| drawRoundRect(drawer: IPathDrawer, x: number, y: number, width: number, height: number, cornerRadius: number | number[]): void { | ||
| let [topLeft, topRight, bottomRight, bottomLeft] = MathHelper.fourNumber(cornerRadius) | ||
| const data = MathHelper.fourNumber(cornerRadius, Math.min(width / 2, height / 2)) | ||
| const max = Math.min(width / 2, height / 2) | ||
| if (topLeft > max) topLeft = max | ||
| if (topRight > max) topRight = max | ||
| if (bottomRight > max) bottomRight = max | ||
| if (bottomLeft > max) bottomLeft = max | ||
| const right = x + width | ||
| const bottom = y + height | ||
| topLeft ? drawer.moveTo(x + topLeft, y) : drawer.moveTo(x, y) | ||
| topRight ? drawer.arcTo(x + width, y, x + width, y + height, topRight) : drawer.lineTo(x + width, y) | ||
| bottomRight ? drawer.arcTo(x + width, y + height, x, y + height, bottomRight) : drawer.lineTo(x + width, y + height) | ||
| bottomLeft ? drawer.arcTo(x, y + height, x, y, bottomLeft) : drawer.lineTo(x, y + height) | ||
| topLeft ? drawer.arcTo(x, y, x + width, y, topLeft) : drawer.lineTo(x, y) | ||
| data[0] ? drawer.moveTo(x + data[0], y) : drawer.moveTo(x, y) | ||
| data[1] ? drawer.arcTo(right, y, right, bottom, data[1]) : drawer.lineTo(right, y) | ||
| data[2] ? drawer.arcTo(right, bottom, x, bottom, data[2]) : drawer.lineTo(right, bottom) | ||
| data[3] ? drawer.arcTo(x, bottom, x, y, data[3]) : drawer.lineTo(x, bottom) | ||
| data[0] ? drawer.arcTo(x, y, right, y, data[0]) : drawer.lineTo(x, y) | ||
| } | ||
| } |
+7
-2
@@ -54,3 +54,3 @@ import { IPathCreator, IPathCommandData, IPathDrawer, IPathString, IBoundsData, ITwoPointBoundsData, IPointData, INumberMap, IStringMap } from '@leafer/interface'; | ||
| arc(data: IPathCommandData, x: number, y: number, radius: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void; | ||
| arcTo(data: IPathCommandData, x1: number, y1: number, x2: number, y2: number, radius: number): void; | ||
| arcTo(data: IPathCommandData, x1: number, y1: number, x2: number, y2: number, radius: number, lastX?: number, lastY?: number): void; | ||
| drawEllipse(data: IPathCommandData, x: number, y: number, radiusX: number, radiusY: number, rotation?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void; | ||
@@ -65,2 +65,7 @@ drawArc(data: IPathCommandData, x: number, y: number, radius: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean): void; | ||
| declare const PathScaler: { | ||
| scale(data: IPathCommandData, scaleX: number, scaleY: number): void; | ||
| scalePoints(data: IPathCommandData, scaleX: number, scaleY: number, start?: number, pointCount?: number): void; | ||
| }; | ||
| declare const PathBounds: { | ||
@@ -102,2 +107,2 @@ toBounds(data: IPathCommandData, setBounds: IBoundsData): void; | ||
| export { BezierHelper, EllipseHelper, NeedConvertToCanvasCommandMap, PathBounds, PathCommandDataHelper, PathCommandMap, PathConvert, PathCorner, PathCreator, PathDrawer, PathHelper, PathNumberCommandLengthMap, PathNumberCommandMap, RectHelper }; | ||
| export { BezierHelper, EllipseHelper, NeedConvertToCanvasCommandMap, PathBounds, PathCommandDataHelper, PathCommandMap, PathConvert, PathCorner, PathCreator, PathDrawer, PathHelper, PathNumberCommandLengthMap, PathNumberCommandMap, PathScaler, RectHelper }; |
62584
7.3%17
6.25%1245
8.26%+ Added
+ Added
- Removed
- Removed
Updated
Updated