@gedit/editor-2d 0.2.46 → 0.2.47
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/lib/browser/model/editor2d-document.d.ts +11 -2
- package/lib/browser/model/editor2d-document.d.ts.map +1 -1
- package/lib/browser/model/editor2d-document.js +44 -8
- package/lib/browser/model/editor2d-document.js.map +1 -1
- package/lib/browser/model/editor2d-model-container.d.ts.map +1 -1
- package/lib/browser/model/editor2d-model-container.js +1 -1
- package/lib/browser/model/editor2d-model-container.js.map +1 -1
- package/lib/browser/model/editor2d-model.d.ts +2 -0
- package/lib/browser/model/editor2d-model.d.ts.map +1 -1
- package/lib/browser/model/editor2d-model.js +5 -0
- package/lib/browser/model/editor2d-model.js.map +1 -1
- package/lib/browser/model/editor2d.d.ts +2 -0
- package/lib/browser/model/editor2d.d.ts.map +1 -1
- package/lib/browser/model/editor2d.js +4 -2
- package/lib/browser/model/editor2d.js.map +1 -1
- package/lib/browser/playground/canvas-draw.d.ts.map +1 -1
- package/lib/browser/playground/canvas-draw.js +30 -27
- package/lib/browser/playground/canvas-draw.js.map +1 -1
- package/lib/browser/playground/canvas-layer.d.ts +14 -2
- package/lib/browser/playground/canvas-layer.d.ts.map +1 -1
- package/lib/browser/playground/canvas-layer.js +96 -50
- package/lib/browser/playground/canvas-layer.js.map +1 -1
- package/lib/browser/playground/index.d.ts +2 -0
- package/lib/browser/playground/index.d.ts.map +1 -1
- package/lib/browser/playground/index.js +2 -0
- package/lib/browser/playground/index.js.map +1 -1
- package/lib/browser/playground/path-edit/index.d.ts +4 -0
- package/lib/browser/playground/path-edit/index.d.ts.map +1 -0
- package/lib/browser/playground/path-edit/index.js +20 -0
- package/lib/browser/playground/path-edit/index.js.map +1 -0
- package/lib/browser/playground/path-edit/path-edit-layer-move-point.d.ts +18 -0
- package/lib/browser/playground/path-edit/path-edit-layer-move-point.d.ts.map +1 -0
- package/lib/browser/playground/path-edit/path-edit-layer-move-point.js +52 -0
- package/lib/browser/playground/path-edit/path-edit-layer-move-point.js.map +1 -0
- package/lib/browser/playground/path-edit/path-edit-layer-svg-path.d.ts +21 -0
- package/lib/browser/playground/path-edit/path-edit-layer-svg-path.d.ts.map +1 -0
- package/lib/browser/playground/path-edit/path-edit-layer-svg-path.js +158 -0
- package/lib/browser/playground/path-edit/path-edit-layer-svg-path.js.map +1 -0
- package/lib/browser/playground/path-edit/utils.d.ts +37 -0
- package/lib/browser/playground/path-edit/utils.d.ts.map +1 -0
- package/lib/browser/playground/path-edit/utils.js +236 -0
- package/lib/browser/playground/path-edit/utils.js.map +1 -0
- package/lib/browser/playground/path-edit-layer.d.ts +32 -12
- package/lib/browser/playground/path-edit-layer.d.ts.map +1 -1
- package/lib/browser/playground/path-edit-layer.js +460 -146
- package/lib/browser/playground/path-edit-layer.js.map +1 -1
- package/lib/browser/playground/playground-context.d.ts +5 -2
- package/lib/browser/playground/playground-context.d.ts.map +1 -1
- package/lib/browser/playground/playground-context.js +13 -2
- package/lib/browser/playground/playground-context.js.map +1 -1
- package/lib/browser/playground/playground-contribution.d.ts +2 -1
- package/lib/browser/playground/playground-contribution.d.ts.map +1 -1
- package/lib/browser/playground/playground-contribution.js +4 -21
- package/lib/browser/playground/playground-contribution.js.map +1 -1
- package/lib/browser/playground/selection-entity-manager.d.ts.map +1 -1
- package/lib/browser/playground/selection-entity-manager.js +24 -8
- package/lib/browser/playground/selection-entity-manager.js.map +1 -1
- package/lib/browser/playground/selector-extend-renderer.d.ts +2 -1
- package/lib/browser/playground/selector-extend-renderer.d.ts.map +1 -1
- package/lib/browser/playground/selector-extend-renderer.js +50 -21
- package/lib/browser/playground/selector-extend-renderer.js.map +1 -1
- package/lib/browser/utils/snapshot.d.ts +1 -0
- package/lib/browser/utils/snapshot.d.ts.map +1 -1
- package/lib/browser/utils/snapshot.js +11 -0
- package/lib/browser/utils/snapshot.js.map +1 -1
- package/package.json +9 -7
- package/src/browser/model/editor2d-document.ts +44 -6
- package/src/browser/model/editor2d-model-container.ts +2 -0
- package/src/browser/model/editor2d-model.ts +2 -0
- package/src/browser/model/editor2d.ts +4 -1
- package/src/browser/playground/canvas-draw.ts +30 -25
- package/src/browser/playground/canvas-layer.ts +97 -52
- package/src/browser/playground/index.ts +2 -0
- package/src/browser/playground/path-edit/index.ts +3 -0
- package/src/browser/playground/path-edit/path-edit-layer-move-point.tsx +108 -0
- package/src/browser/playground/path-edit/path-edit-layer-svg-path.tsx +283 -0
- package/src/browser/playground/path-edit/utils.tsx +285 -0
- package/src/browser/playground/path-edit-layer.tsx +563 -216
- package/src/browser/playground/playground-context.ts +7 -1
- package/src/browser/playground/playground-contribution.ts +2 -21
- package/src/browser/playground/selection-entity-manager.tsx +34 -6
- package/src/browser/playground/selector-extend-renderer.tsx +69 -37
- package/src/browser/style/path-edit-layer.less +17 -30
- package/src/browser/svg/pen_close.svg +24 -0
- package/src/browser/utils/snapshot.ts +11 -0
- package/lib/browser/playground/path-edit-layer-move-point.d.ts +0 -15
- package/lib/browser/playground/path-edit-layer-move-point.d.ts.map +0 -1
- package/lib/browser/playground/path-edit-layer-move-point.js +0 -47
- package/lib/browser/playground/path-edit-layer-move-point.js.map +0 -1
- package/lib/browser/playground/path-edit-layer-svg-path.d.ts +0 -11
- package/lib/browser/playground/path-edit-layer-svg-path.d.ts.map +0 -1
- package/lib/browser/playground/path-edit-layer-svg-path.js +0 -21
- package/lib/browser/playground/path-edit-layer-svg-path.js.map +0 -1
- package/src/browser/playground/path-edit-layer-move-point.tsx +0 -71
- package/src/browser/playground/path-edit-layer-svg-path.tsx +0 -50
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
PathChild,
|
|
4
|
+
PATH_FUNC_TYPE,
|
|
5
|
+
getPointsToPaths /* getPathToBezier */,
|
|
6
|
+
} from '@gedit/canvas-draw';
|
|
7
|
+
import {
|
|
8
|
+
PointMoveDefault,
|
|
9
|
+
PointDefaultProps,
|
|
10
|
+
} from './path-edit-layer-move-point';
|
|
11
|
+
import { PathEditLayerEventContext } from '../path-edit-layer';
|
|
12
|
+
import clsx from 'clsx';
|
|
13
|
+
import { generateUuid } from '@gedit/utils';
|
|
14
|
+
import { PathSelectMode } from '@gedit/playground';
|
|
15
|
+
|
|
16
|
+
export interface PointSelection {
|
|
17
|
+
pointId?: string;
|
|
18
|
+
bezierKey?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface PathSVGProps {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
scale: number;
|
|
24
|
+
paths: PathChild[];
|
|
25
|
+
closed: boolean; // 是否闭合路径
|
|
26
|
+
selection?: PointSelection[];
|
|
27
|
+
selectMode?: PathSelectMode;
|
|
28
|
+
getPosFromMouseEvent: PointDefaultProps['getPosFromMouseEvent'];
|
|
29
|
+
getPointIsStartOrEnd: () => boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const SvgPath = ({
|
|
33
|
+
width,
|
|
34
|
+
height,
|
|
35
|
+
paths = [],
|
|
36
|
+
closed,
|
|
37
|
+
scale,
|
|
38
|
+
selection = [],
|
|
39
|
+
selectMode,
|
|
40
|
+
getPosFromMouseEvent,
|
|
41
|
+
getPointIsStartOrEnd,
|
|
42
|
+
}: PathSVGProps) => {
|
|
43
|
+
const isMultiple = selection.length > 1; // 多选模式;
|
|
44
|
+
const isSelect = selectMode !== PathSelectMode.ADD_PATH; // 选择点模式
|
|
45
|
+
const [hideMovePoint, setHideMovePoint] = React.useState(false);
|
|
46
|
+
const [closePath, setClosePath] = React.useState(false);
|
|
47
|
+
const onHideMovePoint = () => {
|
|
48
|
+
setHideMovePoint(true);
|
|
49
|
+
};
|
|
50
|
+
const onShowMovePoint = () => {
|
|
51
|
+
setHideMovePoint(false);
|
|
52
|
+
};
|
|
53
|
+
const onClosePath = () => {
|
|
54
|
+
setClosePath(true);
|
|
55
|
+
};
|
|
56
|
+
const onReClosePath = () => {
|
|
57
|
+
setClosePath(false);
|
|
58
|
+
};
|
|
59
|
+
const {
|
|
60
|
+
onPointMouseDown,
|
|
61
|
+
onClosePath: onClosedPath,
|
|
62
|
+
onPathAddPoint,
|
|
63
|
+
onBezierPointMouseDown,
|
|
64
|
+
} = React.useContext(PathEditLayerEventContext);
|
|
65
|
+
const p = [...paths];
|
|
66
|
+
if (closed) {
|
|
67
|
+
p.push({
|
|
68
|
+
...paths[0],
|
|
69
|
+
id: generateUuid(),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const pathsStringArray = getPointsToPaths(p);
|
|
73
|
+
/**
|
|
74
|
+
* 路径点
|
|
75
|
+
* 1. 没有任何点的情况,显示默认移动点,不绘制路径;
|
|
76
|
+
* 2. 有点的情况,显示所有点,绘制最后点到移动点的路径;
|
|
77
|
+
* 3. 选中中间点的情况,不显示移动点与路径;
|
|
78
|
+
* 4. 选中起始点的情况,显示移动点,绘制起点到移动点的路径,反转点的 x1=x2, y1=y2;
|
|
79
|
+
* 5. 选中贝赛尔点时,不显示移动点与路径;
|
|
80
|
+
* @param bezierSelect 是否选中贝赛尔点
|
|
81
|
+
* @param pointIsStartOrEnd 是否选中起始点或结束点
|
|
82
|
+
* @param currentPointIndex 当前选中点的索引
|
|
83
|
+
* @param closePointIndex 当前选中点的闭合点索引
|
|
84
|
+
*/
|
|
85
|
+
const bezierSelect =
|
|
86
|
+
!isMultiple &&
|
|
87
|
+
selection[0] &&
|
|
88
|
+
typeof selection[0].bezierKey !== 'undefined';
|
|
89
|
+
const pointIsStartOrEnd = getPointIsStartOrEnd();
|
|
90
|
+
const currentPointIndex =
|
|
91
|
+
!isSelect && selection.length
|
|
92
|
+
? paths.findIndex(c => c.id === selection[0].pointId)
|
|
93
|
+
: undefined;
|
|
94
|
+
const closePointIndex =
|
|
95
|
+
currentPointIndex === paths.length - 1 ? 0 : paths.length - 1;
|
|
96
|
+
const allPoints = paths.map((item, i) => {
|
|
97
|
+
/**
|
|
98
|
+
* 经过点时,是否关闭路径;
|
|
99
|
+
* 条件:
|
|
100
|
+
* 1. 点的数量大于2; 或者点的数量等于2,但是有一点不是直线时;
|
|
101
|
+
* 2. 不是闭合路径时; 闭合路径了选择器是 select_bezier;
|
|
102
|
+
* 3. 不是多选模式;
|
|
103
|
+
* 4. 第一帧或最后一帧时;
|
|
104
|
+
* 5. 选中的点是起始点时,最后一点是闭合点;选中的点是结束点时,第一点是闭合点;
|
|
105
|
+
*/
|
|
106
|
+
const closePoint =
|
|
107
|
+
(paths.length > 2 ||
|
|
108
|
+
(paths.length === 2 &&
|
|
109
|
+
paths.some(c => c.type !== PATH_FUNC_TYPE.STRAIGHT))) &&
|
|
110
|
+
!closed &&
|
|
111
|
+
!isMultiple &&
|
|
112
|
+
pointIsStartOrEnd &&
|
|
113
|
+
closePointIndex === i;
|
|
114
|
+
return (
|
|
115
|
+
<circle
|
|
116
|
+
className={clsx('gedit-path-edit-layer-point', {
|
|
117
|
+
'gedit-path-edit-layer-point-closed': closePoint,
|
|
118
|
+
'gedit-path-edit-layer-point-active':
|
|
119
|
+
selection.some(c => c.pointId === item.id) && !bezierSelect,
|
|
120
|
+
})}
|
|
121
|
+
cx={item.x}
|
|
122
|
+
cy={item.y}
|
|
123
|
+
r={4 / scale}
|
|
124
|
+
key={item.id}
|
|
125
|
+
strokeWidth="1"
|
|
126
|
+
onMouseDown={e => {
|
|
127
|
+
e.preventDefault();
|
|
128
|
+
e.stopPropagation();
|
|
129
|
+
if (closePoint) {
|
|
130
|
+
onClosedPath();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
onPointMouseDown?.(e, item);
|
|
134
|
+
}}
|
|
135
|
+
onMouseEnter={closePoint ? onClosePath : onHideMovePoint}
|
|
136
|
+
onMouseLeave={closePoint ? onReClosePath : onShowMovePoint}
|
|
137
|
+
/>
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
// 贝塞尔点
|
|
141
|
+
const bezierPointNodes: JSX.Element[] = [];
|
|
142
|
+
const bezierPathNodes: JSX.Element[] = [];
|
|
143
|
+
const bezierPoints: PathChild[] = [];
|
|
144
|
+
// 插入贝塞尔点
|
|
145
|
+
selection.forEach(item => {
|
|
146
|
+
const { pointId: currentPointId } = item;
|
|
147
|
+
const index = paths.findIndex(c => c.id === currentPointId);
|
|
148
|
+
// 关闭路径把第一个贝赛尔点加入
|
|
149
|
+
if (closed) {
|
|
150
|
+
if (index === paths.length - 1) {
|
|
151
|
+
bezierPoints.push(paths[0]);
|
|
152
|
+
}
|
|
153
|
+
if (index === 0) {
|
|
154
|
+
bezierPoints.push(paths[paths.length - 1]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// 前后两点加当前开启贝赛尔点
|
|
158
|
+
paths.filter((_, i) => i >= index - 1 && i <= index + 1).forEach(c => {
|
|
159
|
+
if (bezierPoints.some(d => d.id === c.id)) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
bezierPoints.push(c);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
bezierPoints.forEach((p, i) => {
|
|
166
|
+
const selectionNode = selection.find(c => c.pointId === p.id);
|
|
167
|
+
const { bezierKey, pointId: currentPointId } = selectionNode || {};
|
|
168
|
+
if (p.type === PATH_FUNC_TYPE.STRAIGHT) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if ('x1' in p && 'y1' in p) {
|
|
172
|
+
bezierPathNodes.push(
|
|
173
|
+
<path
|
|
174
|
+
key={`${p.id}_${i}_x1-line`}
|
|
175
|
+
className="gedit-path-edit-layer-point-bezier-line"
|
|
176
|
+
strokeWidth={1 / scale}
|
|
177
|
+
d={`M${p.x},${p.y} L${p.x1},${p.y1}`}
|
|
178
|
+
/>
|
|
179
|
+
);
|
|
180
|
+
bezierPointNodes.push(
|
|
181
|
+
<circle
|
|
182
|
+
key={`${p.id}_${i}_x1_point`}
|
|
183
|
+
className={clsx('gedit-path-edit-layer-point-bezier', {
|
|
184
|
+
'gedit-path-edit-layer-point-active':
|
|
185
|
+
bezierKey === 'left' && currentPointId === p.id,
|
|
186
|
+
})}
|
|
187
|
+
cx={p.x1}
|
|
188
|
+
cy={p.y1}
|
|
189
|
+
r={3 / scale}
|
|
190
|
+
onMouseDown={e => {
|
|
191
|
+
onBezierPointMouseDown(e, p, 'left');
|
|
192
|
+
}}
|
|
193
|
+
onMouseEnter={onHideMovePoint}
|
|
194
|
+
onMouseLeave={onShowMovePoint}
|
|
195
|
+
/>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
if ('x2' in p && 'y2' in p) {
|
|
199
|
+
bezierPathNodes.push(
|
|
200
|
+
<path
|
|
201
|
+
key={`${p.id}_${i}_x2-line`}
|
|
202
|
+
className="gedit-path-edit-layer-point-bezier-line"
|
|
203
|
+
strokeWidth={1 / scale}
|
|
204
|
+
d={`M${p.x},${p.y} L${p.x2},${p.y2}`}
|
|
205
|
+
/>
|
|
206
|
+
);
|
|
207
|
+
bezierPointNodes.push(
|
|
208
|
+
<circle
|
|
209
|
+
key={`${p.id}_${i}x2_point`}
|
|
210
|
+
className={clsx('gedit-path-edit-layer-point-bezier', {
|
|
211
|
+
'gedit-path-edit-layer-point-active':
|
|
212
|
+
bezierKey === 'right' && currentPointId === p.id,
|
|
213
|
+
})}
|
|
214
|
+
cx={p.x2}
|
|
215
|
+
cy={p.y2}
|
|
216
|
+
r={3 / scale}
|
|
217
|
+
onMouseDown={e => {
|
|
218
|
+
onBezierPointMouseDown(e, p, 'right');
|
|
219
|
+
}}
|
|
220
|
+
onMouseEnter={onHideMovePoint}
|
|
221
|
+
onMouseLeave={onShowMovePoint}
|
|
222
|
+
/>
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
const showDefaultMovePoint =
|
|
228
|
+
!isMultiple && // 不是多选模式
|
|
229
|
+
!isSelect && // 不是选择模式
|
|
230
|
+
!hideMovePoint && // 没经过点时
|
|
231
|
+
!closed && // 不是关闭路径时
|
|
232
|
+
(!paths.length || // 没有点时
|
|
233
|
+
pointIsStartOrEnd); // 选中起始点或结束点时
|
|
234
|
+
// const ppp = [...paths, paths[0]];
|
|
235
|
+
// const bezierBox = getPathToBezier(ppp).map(c => c.bbox());
|
|
236
|
+
|
|
237
|
+
return (
|
|
238
|
+
<svg
|
|
239
|
+
width={width || 300}
|
|
240
|
+
height={height || 300}
|
|
241
|
+
className={clsx('gedit-path-edit-layer-svg', {
|
|
242
|
+
// 'gedit-path-edit-layer-pen': !closed,
|
|
243
|
+
})}
|
|
244
|
+
>
|
|
245
|
+
{showDefaultMovePoint && (
|
|
246
|
+
<PointMoveDefault
|
|
247
|
+
getPosFromMouseEvent={getPosFromMouseEvent}
|
|
248
|
+
paths={paths}
|
|
249
|
+
scale={scale}
|
|
250
|
+
closePath={closePath}
|
|
251
|
+
currentPointId={selection[0]?.pointId}
|
|
252
|
+
/>
|
|
253
|
+
)}
|
|
254
|
+
{pathsStringArray.map((p, i) => (
|
|
255
|
+
<path
|
|
256
|
+
className={clsx(
|
|
257
|
+
'gedit-path-edit-layer-path',
|
|
258
|
+
'gedit-path-edit-layer-pen'
|
|
259
|
+
)}
|
|
260
|
+
key={i.toString()}
|
|
261
|
+
strokeLinecap="round"
|
|
262
|
+
strokeWidth={1.5 / scale}
|
|
263
|
+
d={p}
|
|
264
|
+
onMouseEnter={onHideMovePoint}
|
|
265
|
+
onMouseLeave={onShowMovePoint}
|
|
266
|
+
onMouseDown={e => {
|
|
267
|
+
e.preventDefault();
|
|
268
|
+
e.stopPropagation();
|
|
269
|
+
}}
|
|
270
|
+
onClick={e => {
|
|
271
|
+
e.preventDefault();
|
|
272
|
+
e.stopPropagation();
|
|
273
|
+
onPathAddPoint(i, e);
|
|
274
|
+
}}
|
|
275
|
+
/>
|
|
276
|
+
))}
|
|
277
|
+
{/* bezierBox.map(c => <rect stroke='#000' strokeWidth={2} fill="none" x={c.x.min} y={c.y.min} width={c.x.size} height={c.y.size} />) */}
|
|
278
|
+
{bezierPathNodes}
|
|
279
|
+
{allPoints}
|
|
280
|
+
{bezierPointNodes}
|
|
281
|
+
</svg>
|
|
282
|
+
);
|
|
283
|
+
};
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/* eslint-disable max-len*/
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import {
|
|
4
|
+
PathChild,
|
|
5
|
+
Point,
|
|
6
|
+
toFixedValue,
|
|
7
|
+
PATH_FUNC_TYPE,
|
|
8
|
+
getLineWidth,
|
|
9
|
+
BezierArray,
|
|
10
|
+
quadraticToCubic,
|
|
11
|
+
cubicToQuadratic,
|
|
12
|
+
getPathBounds,
|
|
13
|
+
PathSchema,
|
|
14
|
+
} from '@gedit/canvas-draw';
|
|
15
|
+
import { Bezier } from 'bezier-js';
|
|
16
|
+
import { generateUuid, PositionSchema } from '@gedit/utils';
|
|
17
|
+
import { PointSchema } from './path-edit-layer-move-point';
|
|
18
|
+
import { Editor2dPathNode } from '../../model';
|
|
19
|
+
|
|
20
|
+
export const pathFuncIcon = [
|
|
21
|
+
{
|
|
22
|
+
icon: (
|
|
23
|
+
<svg width="1em" height="1em" viewBox="0 0 16 16">
|
|
24
|
+
<g stroke="none" fill="currentColor" fillRule="nonzero">
|
|
25
|
+
<path d="M10.4684227,7.89241331 L13.8353656,11.2580367 C14.2258898,11.648561 14.2258898,12.281726 13.8353656,12.6722503 C13.6478292,12.8597867 13.3934753,12.9651435 13.1282588,12.9651435 L2.87174123,12.9651435 C2.31945648,12.9651435 1.87174123,12.5174282 1.87174123,11.9651435 C1.87174123,11.699927 1.97709807,11.4455731 2.16463445,11.2580367 L5.5315773,7.89241331 C6.17107192,8.50939201 7.04121784,8.88888889 8,8.88888889 C8.95878216,8.88888889 9.82892808,8.50939201 10.4684227,7.89241331 Z" />
|
|
26
|
+
<path d="M8,3.11111111 C6.77270056,3.11111111 5.77777778,4.10603389 5.77777778,5.33333333 C5.77777778,6.56063278 6.77270056,7.55555556 8,7.55555556 C9.22729944,7.55555556 10.2222222,6.56063278 10.2222222,5.33333333 C10.2222222,4.10603389 9.22729944,3.11111111 8,3.11111111 Z M8,4 C8.73637967,4 9.33333333,4.59695367 9.33333333,5.33333333 C9.33333333,6.069713 8.73637967,6.66666667 8,6.66666667 C7.26362033,6.66666667 6.66666667,6.069713 6.66666667,5.33333333 C6.66666667,4.59695367 7.26362033,4 8,4 Z" />
|
|
27
|
+
</g>
|
|
28
|
+
</svg>
|
|
29
|
+
),
|
|
30
|
+
type: PATH_FUNC_TYPE.STRAIGHT,
|
|
31
|
+
name: '笔直',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
icon: (
|
|
35
|
+
<svg width="1em" height="1em" viewBox="0 0 16 16">
|
|
36
|
+
<g stroke="none" fill="currentColor" fillRule="nonzero">
|
|
37
|
+
<path d="M11.0960993,7.08278272 C12.90892,7.79368793 13.8669699,9.26586873 13.9715946,11.4991392 C13.9974693,12.0508335 13.5711839,12.5190234 13.0194883,12.5448693 L12.9960956,12.545691 L12.9960956,12.545691 L3.02729199,12.5459649 C2.47501636,12.5459484 2.0273085,12.0982406 2.0273085,11.5459649 C2.0273085,11.5303611 2.02767372,11.5147595 2.02840387,11.4991728 C2.13302028,9.26588707 3.09106789,7.7936962 4.9025467,7.08260023 C5.51453959,8.16114343 6.67228276,8.88888889 8,8.88888889 C9.32771724,8.88888889 10.4854604,8.16114343 11.0960993,7.08278272 Z M8,3.11111111 C9.07494019,3.11111111 9.97161786,3.87434369 10.1776822,4.88845806 L12.3150306,4.88807899 C12.4866723,4.49608833 12.8780204,4.22222222 13.3333333,4.22222222 C13.9469831,4.22222222 14.4444444,4.71968361 14.4444444,5.33333333 C14.4444444,5.94698306 13.9469831,6.44444444 13.3333333,6.44444444 C12.8776416,6.44444444 12.4860212,6.17012247 12.3146027,5.77760908 L10.1776822,5.7782086 C9.97161786,6.79232298 9.07494019,7.55555556 8,7.55555556 C6.92505981,7.55555556 6.02838214,6.79232298 5.82231777,5.7782086 L3.68539731,5.77760908 C3.51397881,6.17012247 3.1223584,6.44444444 2.66666667,6.44444444 C2.05301694,6.44444444 1.55555556,5.94698306 1.55555556,5.33333333 C1.55555556,4.71968361 2.05301694,4.22222222 2.66666667,4.22222222 C3.12197961,4.22222222 3.51332769,4.49608833 3.68496938,4.88807899 L5.82231777,4.88845806 C6.02838214,3.87434369 6.92505981,3.11111111 8,3.11111111 Z M8,4 C7.26362033,4 6.66666667,4.59695367 6.66666667,5.33333333 C6.66666667,6.069713 7.26362033,6.66666667 8,6.66666667 C8.73637967,6.66666667 9.33333333,6.069713 9.33333333,5.33333333 C9.33333333,4.59695367 8.73637967,4 8,4 Z M2.66666667,4.66666667 C2.29847683,4.66666667 2,4.9651435 2,5.33333333 C2,5.70152317 2.29847683,6 2.66666667,6 C3.0348565,6 3.33333333,5.70152317 3.33333333,5.33333333 C3.33333333,4.9651435 3.0348565,4.66666667 2.66666667,4.66666667 Z M13.3333333,4.66666667 C12.9651435,4.66666667 12.6666667,4.9651435 12.6666667,5.33333333 C12.6666667,5.70152317 12.9651435,6 13.3333333,6 C13.7015232,6 14,5.70152317 14,5.33333333 C14,4.9651435 13.7015232,4.66666667 13.3333333,4.66666667 Z" />
|
|
38
|
+
</g>
|
|
39
|
+
</svg>
|
|
40
|
+
),
|
|
41
|
+
type: PATH_FUNC_TYPE.EQUAL,
|
|
42
|
+
name: '平衡对称',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
icon: (
|
|
46
|
+
<svg width="1em" height="1em" viewBox="0 0 16 16">
|
|
47
|
+
<g stroke="none" fill="currentColor" fillRule="nonzero">
|
|
48
|
+
<path d="M4.9025467,7.08260023 C5.51453959,8.16114343 6.67228277,8.88888889 8,8.88888889 C8.74203543,8.88888889 9.43097987,8.66157939 10.0009996,8.27279411 L10.1137604,8.37175614 L10.1137604,8.37175614 L10.2225556,8.46711111 L10.2278018,8.60314648 C10.3091765,9.75637815 11.2705058,10.6666667 12.4444444,10.6666667 L12.5461712,10.6633099 C12.6121342,10.7325386 12.6759208,10.800472 12.7375309,10.8671103 C13.1124477,11.272636 13.087643,11.9053101 12.6821225,12.2802325 C12.4973359,12.4510762 12.2549271,12.5459649 12.0032653,12.5459649 L3.027292,12.5459649 C2.47501636,12.5459484 2.0273085,12.0982406 2.0273085,11.5459649 C2.0273085,11.5303612 2.02767373,11.5147595 2.02840387,11.4991728 C2.13302028,9.26588707 3.09106789,7.7936962 4.9025467,7.08260023 Z M8,3.11111111 C9.22729944,3.11111111 10.2222222,4.10603389 10.2222222,5.33333333 C10.2222222,5.49236269 10.2055174,5.64749043 10.1737666,5.79705753 L11.8370907,7.45894334 C12.2356667,7.30306411 12.7061115,7.38611945 13.0281014,7.70810937 C13.4620173,8.14202525 13.4620173,8.84554189 13.0281014,9.27945777 C12.5941856,9.71337365 11.8906689,9.71337365 11.456753,9.27945777 C11.1345303,8.95723505 11.0515878,8.48634268 11.2079255,8.08758262 L9.78192352,6.66134751 C9.37675045,7.20412589 8.72941562,7.55555556 8,7.55555556 C6.92505981,7.55555556 6.02838214,6.79232298 5.82231777,5.7782086 L3.68539731,5.77760908 C3.51397881,6.17012247 3.1223584,6.44444444 2.66666667,6.44444444 C2.05301694,6.44444444 1.55555556,5.94698306 1.55555556,5.33333333 C1.55555556,4.71968361 2.05301694,4.22222222 2.66666667,4.22222222 C3.07649292,4.22222222 3.43449636,4.44410206 3.62710432,4.77428908 L3.68502542,4.888207 L5.82231777,4.88845806 C6.02838214,3.87434369 6.92505981,3.11111111 8,3.11111111 Z M11.7710227,8.02237905 C11.5106732,8.28272858 11.5106732,8.70483856 11.7710227,8.96518809 C12.0313722,9.22553762 12.4534822,9.22553762 12.7138318,8.96518809 C12.9741813,8.70483856 12.9741813,8.28272858 12.7138318,8.02237905 C12.4534822,7.76202952 12.0313722,7.76202952 11.7710227,8.02237905 Z M8,4 C7.26362033,4 6.66666667,4.59695367 6.66666667,5.33333333 C6.66666667,6.069713 7.26362033,6.66666667 8,6.66666667 C8.73637967,6.66666667 9.33333333,6.069713 9.33333333,5.33333333 C9.33333333,4.59695367 8.73637967,4 8,4 Z M2.66666667,4.66666667 C2.29847683,4.66666667 2,4.9651435 2,5.33333333 C2,5.70152317 2.29847683,6 2.66666667,6 C3.0348565,6 3.33333333,5.70152317 3.33333333,5.33333333 C3.33333333,4.9651435 3.0348565,4.66666667 2.66666667,4.66666667 Z" />
|
|
49
|
+
</g>
|
|
50
|
+
</svg>
|
|
51
|
+
),
|
|
52
|
+
type: PATH_FUNC_TYPE.BREAK,
|
|
53
|
+
name: '断开链接',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
icon: (
|
|
57
|
+
<svg width="1em" height="1em" viewBox="0 0 16 16">
|
|
58
|
+
<g stroke="none" fill="currentColor" fillRule="nonzero">
|
|
59
|
+
<path d="M9.48113654,6.75735761 C11.4348163,7.48824028 12.802824,8.97509642 13.5854936,11.2162897 C13.7675572,11.7376913 13.4924892,12.307972 12.9710939,12.4900537 C12.8651151,12.5270636 12.7536611,12.5459649 12.6414058,12.5459649 L2.93734326,12.5459649 C2.41280388,12.5459761 1.97740772,12.1406813 1.93989294,11.6174852 C1.79069809,9.53675393 2.20550284,8.05786209 3.18430719,7.18080967 C3.80834692,8.20534701 4.93545969,8.88888889 6.22222222,8.88888889 C7.67952934,8.88888889 8.93206301,8.01214956 9.48113654,6.75735761 Z M8.39990445,5.7782086 C8.19384008,6.79232298 7.29716241,7.55555556 6.22222222,7.55555556 C5.14728203,7.55555556 4.25060437,6.79232298 4.04453999,5.7782086 L3.68539731,5.77760908 C3.51397881,6.17012247 3.1223584,6.44444444 2.66666667,6.44444444 C2.05301694,6.44444444 1.55555556,5.94698306 1.55555556,5.33333333 C1.55555556,4.71968361 2.05301694,4.22222222 2.66666667,4.22222222 C3.07649292,4.22222222 3.43449636,4.44410206 3.62710432,4.77428908 L3.68502542,4.888207 L4.04453999,4.88845806 C4.25060437,3.87434369 5.14728203,3.11111111 6.22222222,3.11111111 C7.29716241,3.11111111 8.19384008,3.87434369 8.39990445,4.88845806 L10.5371968,4.888207 C10.7088093,4.49614795 11.1001931,4.22222222 11.5555556,4.22222222 C12.1692053,4.22222222 12.6666667,4.71968361 12.6666667,5.33333333 C12.6666667,5.94698306 12.1692053,6.44444444 11.5555556,6.44444444 C11.0998638,6.44444444 10.7082434,6.17012247 10.5368249,5.77760908 Z M6.22222222,4 C5.48584256,4 4.88888889,4.59695367 4.88888889,5.33333333 C4.88888889,6.069713 5.48584256,6.66666667 6.22222222,6.66666667 C6.95860189,6.66666667 7.55555556,6.069713 7.55555556,5.33333333 C7.55555556,4.59695367 6.95860189,4 6.22222222,4 Z M11.5555556,4.66666667 C11.1873657,4.66666667 10.8888889,4.9651435 10.8888889,5.33333333 C10.8888889,5.70152317 11.1873657,6 11.5555556,6 C11.9237454,6 12.2222222,5.70152317 12.2222222,5.33333333 C12.2222222,4.9651435 11.9237454,4.66666667 11.5555556,4.66666667 Z M2.66666667,4.66666667 C2.29847683,4.66666667 2,4.9651435 2,5.33333333 C2,5.70152317 2.29847683,6 2.66666667,6 C3.0348565,6 3.33333333,5.70152317 3.33333333,5.33333333 C3.33333333,4.9651435 3.0348565,4.66666667 2.66666667,4.66666667 Z" />
|
|
60
|
+
</g>
|
|
61
|
+
</svg>
|
|
62
|
+
),
|
|
63
|
+
type: PATH_FUNC_TYPE.UNEQUAL,
|
|
64
|
+
name: '平衡不对称',
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
export const getLeftRightCenterPoint = (item: PathChild) => {
|
|
69
|
+
const l: PathChild = { x: item.x1 ?? item.x, y: item.y1 ?? item.y };
|
|
70
|
+
const r: PathChild = { x: item.x2 ?? item.x, y: item.y2 ?? item.y };
|
|
71
|
+
const c: PathChild = { x: item.x, y: item.y };
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
left: l,
|
|
75
|
+
right: r,
|
|
76
|
+
center: c,
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const getBezierHullByPos = (
|
|
81
|
+
points: BezierArray,
|
|
82
|
+
pos: Point
|
|
83
|
+
): { x: number; y: number }[] => {
|
|
84
|
+
// 判断是二次还是三次贝塞尔曲线
|
|
85
|
+
/* const [x1, y1, x2, y2, x3, y3, x4, y4] = points;
|
|
86
|
+
let p: BezierArray | BezierArray<number, 6> = points;
|
|
87
|
+
const isQuadratic = x1 === x2 && y1 === y2 || x3 === x4 && y3 === y4;
|
|
88
|
+
if (isQuadratic) {
|
|
89
|
+
const xB = x1 === x2 && y1 === y2 ? x3 : x1;
|
|
90
|
+
const yB = x1 === x2 && y1 === y2 ? y3 : y1;
|
|
91
|
+
p = [x1, y1, xB, yB, x4, y4];
|
|
92
|
+
} */
|
|
93
|
+
const bezier = new Bezier(...points);
|
|
94
|
+
const { t = 0 } = bezier.project(pos);
|
|
95
|
+
const h = bezier.hull(t);
|
|
96
|
+
const hull = h.slice(-6);
|
|
97
|
+
return hull;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* 按点获取扩展点
|
|
101
|
+
* @param c
|
|
102
|
+
* @param s
|
|
103
|
+
* @returns
|
|
104
|
+
*/
|
|
105
|
+
export const getExtendPositionByPoint = (c: Point, s: Point): Point => ({ x: c.x * 2 - s.x, y: c.y * 2 - s.y });
|
|
106
|
+
|
|
107
|
+
export const getExtendPositionByRadius = (
|
|
108
|
+
c: PathChild,
|
|
109
|
+
p: PathChild,
|
|
110
|
+
r: number
|
|
111
|
+
): PathChild => {
|
|
112
|
+
const ang = (Math.atan2(p.y - c.y, p.x - c.x) / Math.PI) * 180;
|
|
113
|
+
const angle = 180 + ang;
|
|
114
|
+
const x = c.x + r * Math.cos((angle * Math.PI) / 180);
|
|
115
|
+
const y = c.y + r * Math.sin((angle * Math.PI) / 180);
|
|
116
|
+
// console.log(ang, angle);
|
|
117
|
+
return { x, y };
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 获取点击线上的新增点
|
|
122
|
+
*/
|
|
123
|
+
export const getNewPoint = (
|
|
124
|
+
point: PathChild,
|
|
125
|
+
nextPoint: PathChild,
|
|
126
|
+
pos: PointSchema
|
|
127
|
+
): PathChild => {
|
|
128
|
+
const afterQuadratic =
|
|
129
|
+
point.type === PATH_FUNC_TYPE.STRAIGHT &&
|
|
130
|
+
nextPoint.type !== PATH_FUNC_TYPE.STRAIGHT &&
|
|
131
|
+
typeof nextPoint.x1 === 'number' &&
|
|
132
|
+
typeof nextPoint.y1 === 'number';
|
|
133
|
+
const beforeQuadratic =
|
|
134
|
+
point.type !== PATH_FUNC_TYPE.STRAIGHT &&
|
|
135
|
+
nextPoint.type === PATH_FUNC_TYPE.STRAIGHT &&
|
|
136
|
+
typeof point.x2 === 'number' &&
|
|
137
|
+
typeof point.y2 === 'number';
|
|
138
|
+
const isQuadratic = beforeQuadratic || afterQuadratic;
|
|
139
|
+
const bezier: BezierArray = [
|
|
140
|
+
point.x,
|
|
141
|
+
point.y,
|
|
142
|
+
point.x2 ?? point.x,
|
|
143
|
+
point.y2 ?? point.y,
|
|
144
|
+
nextPoint.x1 ?? nextPoint.x,
|
|
145
|
+
nextPoint.y1 ?? nextPoint.y,
|
|
146
|
+
nextPoint.x,
|
|
147
|
+
nextPoint.y,
|
|
148
|
+
];
|
|
149
|
+
if (isQuadratic) {
|
|
150
|
+
// 转换三次贝赛尔
|
|
151
|
+
const cubic = quadraticToCubic(
|
|
152
|
+
{
|
|
153
|
+
x: point.x,
|
|
154
|
+
y: point.y,
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
x: beforeQuadratic ? point.x2! : nextPoint.x1!,
|
|
158
|
+
y: beforeQuadratic ? point.y2! : nextPoint.y1!,
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
x: nextPoint.x,
|
|
162
|
+
y: nextPoint.y,
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
bezier[2] = cubic[0];
|
|
166
|
+
bezier[3] = cubic[1];
|
|
167
|
+
bezier[4] = cubic[2];
|
|
168
|
+
bezier[5] = cubic[3];
|
|
169
|
+
}
|
|
170
|
+
const hull = getBezierHullByPos(bezier, pos);
|
|
171
|
+
/**
|
|
172
|
+
* 0, 1, 2: 二次贝赛尔点,1为中心点,没用
|
|
173
|
+
* 3, 4: 三次点,
|
|
174
|
+
* 5: 新增点
|
|
175
|
+
*/
|
|
176
|
+
const newPoint: PathChild = {
|
|
177
|
+
x: hull[5].x,
|
|
178
|
+
y: hull[5].y,
|
|
179
|
+
x1: hull[3].x,
|
|
180
|
+
y1: hull[3].y,
|
|
181
|
+
x2: hull[4].x,
|
|
182
|
+
y2: hull[4].y,
|
|
183
|
+
id: generateUuid(),
|
|
184
|
+
type: PATH_FUNC_TYPE.UNEQUAL,
|
|
185
|
+
};
|
|
186
|
+
let pCenter;
|
|
187
|
+
if (point.type !== PATH_FUNC_TYPE.STRAIGHT) {
|
|
188
|
+
point.type = PATH_FUNC_TYPE.UNEQUAL;
|
|
189
|
+
point.x2 = toFixedValue(hull[0].x, 4);
|
|
190
|
+
point.y2 = toFixedValue(hull[0].y, 4);
|
|
191
|
+
} else {
|
|
192
|
+
// 不是贝赛尔时,转换回二次贝赛尔点;
|
|
193
|
+
pCenter = cubicToQuadratic(hull[5], hull[3]);
|
|
194
|
+
newPoint.x1 = toFixedValue(pCenter.x, 4);
|
|
195
|
+
newPoint.y1 = toFixedValue(pCenter.y, 4);
|
|
196
|
+
}
|
|
197
|
+
if (nextPoint.type !== PATH_FUNC_TYPE.STRAIGHT) {
|
|
198
|
+
nextPoint.type = PATH_FUNC_TYPE.UNEQUAL;
|
|
199
|
+
nextPoint.x1 = toFixedValue(hull[2].x, 4);
|
|
200
|
+
nextPoint.y1 = toFixedValue(hull[2].y, 4);
|
|
201
|
+
} else {
|
|
202
|
+
pCenter = cubicToQuadratic(hull[5], hull[4]);
|
|
203
|
+
newPoint.x2 = toFixedValue(pCenter.x, 4);
|
|
204
|
+
newPoint.y2 = toFixedValue(pCenter.y, 4);
|
|
205
|
+
}
|
|
206
|
+
return newPoint;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
export const setBezierMovePoint = (
|
|
210
|
+
path: PathChild,
|
|
211
|
+
key: 'left' | 'right',
|
|
212
|
+
pos: PointSchema
|
|
213
|
+
): PathChild => {
|
|
214
|
+
const { type } = path;
|
|
215
|
+
const x = key === 'left' ? 'x1' : 'x2';
|
|
216
|
+
const x1 = key === 'left' ? 'x2' : 'x1';
|
|
217
|
+
const y = key === 'left' ? 'y1' : 'y2';
|
|
218
|
+
const y1 = key === 'left' ? 'y2' : 'y1';
|
|
219
|
+
const center = { x: path.x, y: path.y };
|
|
220
|
+
const currentPoint = { x: pos.x, y: pos.y };
|
|
221
|
+
path[x] = toFixedValue(pos.x, 4);
|
|
222
|
+
path[y] = toFixedValue(pos.y, 4);
|
|
223
|
+
let p2: PointSchema | false = false;
|
|
224
|
+
const isOnly =
|
|
225
|
+
typeof path[x1] === 'undefined' && typeof path[y1] === 'undefined';
|
|
226
|
+
if (!isOnly) {
|
|
227
|
+
switch (type) {
|
|
228
|
+
case PATH_FUNC_TYPE.EQUAL:
|
|
229
|
+
p2 = getExtendPositionByPoint(center, currentPoint);
|
|
230
|
+
break;
|
|
231
|
+
case PATH_FUNC_TYPE.UNEQUAL:
|
|
232
|
+
// 取半径,走圆周;
|
|
233
|
+
const radius = getLineWidth(center, { x: path[x1]!, y: path[y1]! });
|
|
234
|
+
p2 = getExtendPositionByRadius(center, currentPoint, radius);
|
|
235
|
+
break;
|
|
236
|
+
default:
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
if (p2) {
|
|
240
|
+
path[x1] = toFixedValue(p2.x, 4);
|
|
241
|
+
path[y1] = toFixedValue(p2.y, 4);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return path;
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
export const updatePathNodeData = (node: Editor2dPathNode): { path: PathSchema, position: PositionSchema } => {
|
|
248
|
+
const { position, origin, path } = node;
|
|
249
|
+
const { paths: p = [], closed } = path;
|
|
250
|
+
const paths = [...p];
|
|
251
|
+
if (closed) {
|
|
252
|
+
paths.push(paths[0]);
|
|
253
|
+
}
|
|
254
|
+
const bounds = getPathBounds(paths);
|
|
255
|
+
|
|
256
|
+
const x = bounds.minX + bounds.width * (origin?.x || 0.5);
|
|
257
|
+
const y = bounds.minY + bounds.height * (origin?.y || 0.5);
|
|
258
|
+
const newPath = p.map(c => {
|
|
259
|
+
const item = {
|
|
260
|
+
...c,
|
|
261
|
+
x: toFixedValue(c.x - x, 4),
|
|
262
|
+
y: toFixedValue(c.y - y, 4),
|
|
263
|
+
};
|
|
264
|
+
if (typeof c.x1 === 'number') {
|
|
265
|
+
item.x1 = toFixedValue(c.x1 - x, 4);
|
|
266
|
+
}
|
|
267
|
+
if (typeof c.x2 === 'number') {
|
|
268
|
+
item.x2 = toFixedValue(c.x2 - x, 4);
|
|
269
|
+
}
|
|
270
|
+
if (typeof c.y1 === 'number') {
|
|
271
|
+
item.y1 = toFixedValue(c.y1 - y, 4);
|
|
272
|
+
}
|
|
273
|
+
if (typeof c.y2 === 'number') {
|
|
274
|
+
item.y2 = toFixedValue(c.y2 - y, 4);
|
|
275
|
+
}
|
|
276
|
+
return item;
|
|
277
|
+
});
|
|
278
|
+
return {
|
|
279
|
+
path: { ...path, paths: newPath },
|
|
280
|
+
position: {
|
|
281
|
+
x: x + (position?.x || 0),
|
|
282
|
+
y: y + (position?.y || 0),
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
};
|