Skip to content

Commit 2961eb4

Browse files
committed
feat: 完成形状解析转换
1 parent a6c08a7 commit 2961eb4

File tree

6 files changed

+1200
-1508
lines changed

6 files changed

+1200
-1508
lines changed

src/model/Layer/ShapePath.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,21 @@ class ShapePath extends Base {
111111
}
112112

113113
// 如果下一个点是 Curve 点
114-
if (
115-
point.type === SVGPathData.LINE_TO &&
116-
nextPoint.type === SVGPathData.CURVE_TO
117-
) {
114+
if (nextPoint.type === SVGPathData.CURVE_TO) {
118115
hasCurveFrom = true;
119116
curveFromPoint = { x: nextPoint.x1, y: nextPoint.y1 };
120117
}
121118

122119
// 确认曲线模式
123120
const curveMode =
124-
hasCurveFrom || hasCurveTo
121+
// 既有前 也有后 就不对称
122+
hasCurveFrom && hasCurveTo
123+
? SketchFormat.CurveMode.Asymmetric
124+
: // 否则 有前或有后 就是弯的
125+
hasCurveFrom || hasCurveTo
125126
? SketchFormat.CurveMode.Disconnected
126-
: SketchFormat.CurveMode.Straight;
127+
: // 不然就是直的
128+
SketchFormat.CurveMode.Straight;
127129

128130
// 如果是闭合路径
129131
// 过滤最后一个点

src/model/Layer/__test__/commonSvgData.ts

Lines changed: 14 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,6 @@ interface TestSvgData {
99
shapePath: ShapePathType;
1010
sketchJSON: SketchFormat.ShapePath;
1111
}
12-
// 可复用的 shapeGroup 信息
13-
const shapeGroupData = {
14-
_class: 'shapeGroup',
15-
do_objectID: 'uuid',
16-
booleanOperation: -1,
17-
isFixedToViewport: false,
18-
isFlippedHorizontal: false,
19-
isFlippedVertical: false,
20-
isLocked: false,
21-
isVisible: true,
22-
layerListExpandedType: 0,
23-
name: 'svg',
24-
nameIsFixed: false,
25-
resizingConstraint: 63,
26-
resizingType: 0,
27-
shouldBreakMaskChain: false,
28-
exportOptions: defaultExportOptions,
29-
rotation: 0,
30-
frame: {
31-
_class: 'rect',
32-
constrainProportions: false,
33-
height: 814.2161138351329,
34-
width: 736.652344,
35-
x: -90,
36-
y: 4,
37-
},
38-
clippingMaskMode: 0,
39-
style: new Style().toSketchJSON(),
40-
hasClickThrough: false,
41-
windingRule: 1,
42-
};
4312

4413
// 可复用的 shapePath 信息
4514
const shapePathData = {
@@ -64,6 +33,15 @@ const shapePathData = {
6433
pointRadiusBehaviour: 1,
6534
};
6635

36+
/**
37+
* SVG 图形如下
38+
* @see https://svg-path-visualizer.netlify.app/#M73.2226562%2C282.36788%20C517.988281%2C268.985067%20740.371094%2C312.330119%20740.371094%2C412.403036%20C740.371094%2C562.512411%20706.574547%2C689.414193%20665.761719%2C731.926473%20C585.929687%2C815.082723%20381.128906%2C824.973348%20240.128906%2C815.082723%20C193.160156%2C721.491578%20114.450521%2C640.427775%204%2C571.891317%20L73.2226562%2C282.36788%20Z%20M288.371094%2C399.757812%20L569.023438%2C399.757812%20L569.023438%2C629.085937%20L288.371094%2C629.085937%20L288.371094%2C399.757812%20Z%20M460%2C4%20L640.652344%2C4%20C695.880819%2C4%20740.652344%2C48.771525%20740.652344%2C104%20L740.652344%2C233.328125%20L460%2C233.328125%20L460%2C4%20Z%20M68%2C4%20L248.652344%2C4%20C303.880819%2C4%20348.652344%2C48.771525%20348.652344%2C104%20L348.652344%2C233.328125%20L68%2C233.328125
39+
*/
40+
export const svgPath = {
41+
path:
42+
'M73.2226562,282.36788 C517.988281,268.985067 740.371094,312.330119 740.371094,412.403036 C740.371094,562.512411 706.574547,689.414193 665.761719,731.926473 C585.929687,815.082723 381.128906,824.973348 240.128906,815.082723 C193.160156,721.491578 114.450521,640.427775 4,571.891317 L73.2226562,282.36788 Z M288.371094,399.757812 L569.023438,399.757812 L569.023438,629.085937 L288.371094,629.085937 L288.371094,399.757812 Z M460,4 L640.652344,4 C695.880819,4 740.652344,48.771525 740.652344,104 L740.652344,233.328125 L460,233.328125 L460,4 Z M68,4 L248.652344,4 C303.880819,4 348.652344,48.771525 348.652344,104 L348.652344,233.328125 L68,233.328125',
43+
};
44+
6745
/**
6846
* 不规则复杂矩形
6947
* Path: M73.2226562,282.36788 C517.988281,268.985067 740.371094,312.330119 740.371094,412.403036 C740.371094,562.512411 706.574547,689.414193 665.761719,731.926473 C585.929687,815.082723 381.128906,824.973348 240.128906,815.082723 C193.160156,721.491578 114.450521,640.427775 4,571.891317 L73.2226562,282.36788 Z
@@ -145,7 +123,7 @@ export const compPath: TestSvgData = {
145123
{
146124
_class: 'curvePoint',
147125
cornerRadius: 0,
148-
curveFrom: '{0.69800170754665725, -0.020465632616830577}',
126+
curveFrom: '{0.6980017075466572, -0.020465632616830685}',
149127
curveMode: 4,
150128
curveTo: '{0.09400512426958466, 0.004399496208155765}',
151129
hasCurveFrom: true,
@@ -155,7 +133,7 @@ export const compPath: TestSvgData = {
155133
{
156134
_class: 'curvePoint',
157135
cornerRadius: 0,
158-
curveFrom: '{1, 0.52490515170303653}',
136+
curveFrom: '{1, 0.5249051517030365}',
159137
curveMode: 3,
160138
curveTo: '{1, 0.060069027914235316}',
161139
hasCurveFrom: true,
@@ -165,7 +143,7 @@ export const compPath: TestSvgData = {
165143
{
166144
_class: 'curvePoint',
167145
cornerRadius: 0,
168-
curveFrom: '{0.79026688003046464, 0.99417819207556657}',
146+
curveFrom: '{0.7902668800304646, 0.9941781920755667}',
169147
curveMode: 3,
170148
curveTo: '{0.954103919510996, 0.7606873566513045}',
171149
hasCurveFrom: true,
@@ -175,8 +153,8 @@ export const compPath: TestSvgData = {
175153
{
176154
_class: 'curvePoint',
177155
cornerRadius: 0,
178-
curveFrom: '{0.25688156086148595, 0.82028680785739161}',
179-
curveMode: 4,
156+
curveFrom: '{0.25688156086148595, 0.8202868078573917}',
157+
curveMode: 3,
180158
curveTo: '{0.5121451793435009, 1.0125548715363522}',
181159
hasCurveFrom: true,
182160
hasCurveTo: true,

src/model/Layer/__test__/shapePath.test.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ describe('ShapePath', () => {
2020
const shapePath = new ShapePath({ isClose, points, ...frame });
2121
expect(shapePath.toSketchJSON()).toStrictEqual(rect.sketchJSON);
2222
});
23+
it('不规则图形compPath转换正常', function () {
24+
const { frame, isClose, points } = compPath.shapePath;
25+
const shapePath = new ShapePath({ isClose, points, ...frame });
26+
expect(shapePath.toSketchJSON()).toStrictEqual(compPath.sketchJSON);
27+
});
2328
it('带圆角的矩形 rectRound2 转换正常', function () {
2429
const { frame, isClose, points } = singleRoundRect.shapePath;
2530
const shapePath = new ShapePath({ isClose, points, ...frame });
@@ -32,7 +37,6 @@ describe('ShapePath', () => {
3237

3338
const shapePath = new ShapePath({ isClose, points, ...frame });
3439

35-
console.log(shapePath.toSketchJSON());
3640
expect(shapePath.toSketchJSON()).toStrictEqual(unclosedRect.sketchJSON);
3741
});
3842
});
@@ -52,7 +56,7 @@ describe('ShapePath', () => {
5256
expect(points).toStrictEqual(singleRoundRect.shapePath);
5357
});
5458

55-
it('不规则图形转换正常', function () {
59+
it('不规则图形compPath转换正常', function () {
5660
const points = ShapePath.svgPathToShapePath(compPath.path);
5761
expect(points).toStrictEqual(compPath.shapePath);
5862
});
@@ -65,15 +69,28 @@ describe('ShapePath', () => {
6569
describe('错误处理', function () {
6670
it('只能转化一个shape', function () {
6771
const path =
68-
'M872 474H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h720c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z M872 474H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h720c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z';
72+
'M872 474H152 z M872 474H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h720c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z';
73+
const t = () => {
74+
try {
75+
ShapePath.svgPathToShapePath(path);
76+
} catch (e) {
77+
throw e;
78+
}
79+
};
80+
expect(t).toThrow(
81+
`Error Path!\nData:${path}\nPlease check whether the path is correct.`
82+
);
83+
});
84+
it('如果没有 M 则报错', function () {
85+
const path =
86+
'H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h720c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z';
6987
const t = () => {
7088
try {
7189
ShapePath.svgPathToShapePath(path);
7290
} catch (e) {
7391
throw e;
7492
}
7593
};
76-
7794
expect(t).toThrow(
7895
`Error Path!\nData:${path}\nPlease check whether the path is correct.`
7996
);

0 commit comments

Comments
 (0)