@logicflow/core 2.1.4 → 2.2.0
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/.turbo/turbo-build$colon$dev.log +2 -2
- package/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +6 -0
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/es/model/EditConfigModel.d.ts +3 -1
- package/es/model/EditConfigModel.js +5 -0
- package/es/model/GraphModel.js +1 -0
- package/es/tool/MultipleSelectTool.d.ts +1 -1
- package/es/tool/MultipleSelectTool.js +1 -1
- package/es/util/drag.d.ts +4 -4
- package/es/util/drag.js +12 -6
- package/es/view/Anchor.d.ts +3 -3
- package/es/view/Anchor.js +30 -4
- package/es/view/Control.js +1 -1
- package/es/view/Rotate.js +1 -1
- package/es/view/behavior/dnd.d.ts +4 -8
- package/es/view/behavior/dnd.js +50 -14
- package/es/view/edge/AdjustPoint.d.ts +1 -1
- package/es/view/edge/AdjustPoint.js +1 -1
- package/es/view/edge/BaseEdge.d.ts +2 -1
- package/es/view/edge/BaseEdge.js +18 -1
- package/es/view/edge/PolylineEdge.d.ts +1 -1
- package/es/view/edge/PolylineEdge.js +1 -1
- package/es/view/node/BaseNode.d.ts +2 -1
- package/es/view/node/BaseNode.js +17 -1
- package/es/view/overlay/BezierAdjustOverlay.js +1 -1
- package/es/view/overlay/CanvasOverlay.d.ts +12 -1
- package/es/view/overlay/CanvasOverlay.js +94 -15
- package/es/view/text/BaseText.d.ts +1 -1
- package/es/view/text/BaseText.js +1 -1
- package/lib/model/EditConfigModel.d.ts +3 -1
- package/lib/model/EditConfigModel.js +5 -0
- package/lib/model/GraphModel.js +1 -0
- package/lib/tool/MultipleSelectTool.d.ts +1 -1
- package/lib/tool/MultipleSelectTool.js +1 -1
- package/lib/util/drag.d.ts +4 -4
- package/lib/util/drag.js +12 -6
- package/lib/view/Anchor.d.ts +3 -3
- package/lib/view/Anchor.js +30 -4
- package/lib/view/Control.js +1 -1
- package/lib/view/Rotate.js +1 -1
- package/lib/view/behavior/dnd.d.ts +4 -8
- package/lib/view/behavior/dnd.js +50 -14
- package/lib/view/edge/AdjustPoint.d.ts +1 -1
- package/lib/view/edge/AdjustPoint.js +1 -1
- package/lib/view/edge/BaseEdge.d.ts +2 -1
- package/lib/view/edge/BaseEdge.js +18 -1
- package/lib/view/edge/PolylineEdge.d.ts +1 -1
- package/lib/view/edge/PolylineEdge.js +1 -1
- package/lib/view/node/BaseNode.d.ts +2 -1
- package/lib/view/node/BaseNode.js +17 -1
- package/lib/view/overlay/BezierAdjustOverlay.js +1 -1
- package/lib/view/overlay/CanvasOverlay.d.ts +12 -1
- package/lib/view/overlay/CanvasOverlay.js +94 -15
- package/lib/view/text/BaseText.d.ts +1 -1
- package/lib/view/text/BaseText.js +1 -1
- package/package.json +1 -1
- package/src/model/EditConfigModel.ts +3 -0
- package/src/model/GraphModel.ts +1 -0
- package/src/tool/MultipleSelectTool.tsx +2 -2
- package/src/util/drag.ts +16 -12
- package/src/view/Anchor.tsx +32 -6
- package/src/view/Control.tsx +1 -1
- package/src/view/Rotate.tsx +1 -1
- package/src/view/behavior/dnd.ts +55 -16
- package/src/view/edge/AdjustPoint.tsx +2 -2
- package/src/view/edge/BaseEdge.tsx +23 -3
- package/src/view/edge/PolylineEdge.tsx +2 -2
- package/src/view/node/BaseNode.tsx +21 -5
- package/src/view/overlay/BezierAdjustOverlay.tsx +1 -1
- package/src/view/overlay/CanvasOverlay.tsx +110 -4
- package/src/view/text/BaseText.tsx +5 -2
- package/stats.html +1 -1
|
@@ -34,6 +34,7 @@ export abstract class BaseEdge<P extends IProps> extends Component<
|
|
|
34
34
|
startTime?: number
|
|
35
35
|
contextMenuTime?: number
|
|
36
36
|
clickTimer?: number
|
|
37
|
+
longPressTimer?: number
|
|
37
38
|
textRef = createRef()
|
|
38
39
|
|
|
39
40
|
constructor() {
|
|
@@ -479,13 +480,27 @@ export abstract class BaseEdge<P extends IProps> extends Component<
|
|
|
479
480
|
/**
|
|
480
481
|
* 不支持重写
|
|
481
482
|
*/
|
|
482
|
-
handleMouseDown = (e:
|
|
483
|
+
handleMouseDown = (e: PointerEvent) => {
|
|
483
484
|
e.stopPropagation()
|
|
484
485
|
this.startTime = new Date().getTime()
|
|
486
|
+
if (this.longPressTimer) {
|
|
487
|
+
clearTimeout(this.longPressTimer)
|
|
488
|
+
}
|
|
489
|
+
if (e.pointerType === 'touch') {
|
|
490
|
+
this.longPressTimer = window.setTimeout(() => {
|
|
491
|
+
if (!this.props.model.isDragging) {
|
|
492
|
+
this.handleContextMenu(e)
|
|
493
|
+
}
|
|
494
|
+
}, 500)
|
|
495
|
+
}
|
|
485
496
|
}
|
|
486
497
|
handleMouseUp = () => {
|
|
487
498
|
const { model } = this.props
|
|
488
499
|
this.mouseUpDrag = model.isDragging
|
|
500
|
+
if (this.longPressTimer) {
|
|
501
|
+
clearTimeout(this.longPressTimer)
|
|
502
|
+
this.longPressTimer = undefined
|
|
503
|
+
}
|
|
489
504
|
}
|
|
490
505
|
/**
|
|
491
506
|
* 不支持重写
|
|
@@ -606,10 +621,15 @@ export abstract class BaseEdge<P extends IProps> extends Component<
|
|
|
606
621
|
]
|
|
607
622
|
.filter(Boolean)
|
|
608
623
|
.join(' ')}
|
|
609
|
-
|
|
610
|
-
|
|
624
|
+
style={{
|
|
625
|
+
touchAction: 'none',
|
|
626
|
+
WebkitTouchCallout: 'none',
|
|
627
|
+
}}
|
|
611
628
|
onClick={this.handleClick}
|
|
612
629
|
onContextMenu={this.handleContextMenu}
|
|
630
|
+
onPointerDown={this.handleMouseDown}
|
|
631
|
+
onPointerUp={this.handleMouseUp}
|
|
632
|
+
onPointerCancel={this.handleMouseUp}
|
|
613
633
|
onMouseOver={this.setHoverOn}
|
|
614
634
|
onMouseEnter={this.setHoverOn}
|
|
615
635
|
onMouseLeave={this.setHoverOff}
|
|
@@ -95,7 +95,7 @@ export class PolylineEdge extends BaseEdge<IPolylineEdgeProps> {
|
|
|
95
95
|
/**
|
|
96
96
|
* 不支持重写
|
|
97
97
|
*/
|
|
98
|
-
beforeDragStart = (e, appendInfo) => {
|
|
98
|
+
beforeDragStart = (e: PointerEvent, appendInfo) => {
|
|
99
99
|
// 如果允许拖拽调整触发事件处理
|
|
100
100
|
if (appendInfo.draggable) {
|
|
101
101
|
this.drag.handleMouseDown(e)
|
|
@@ -284,7 +284,7 @@ export class PolylineEdge extends BaseEdge<IPolylineEdgeProps> {
|
|
|
284
284
|
append = (
|
|
285
285
|
<g
|
|
286
286
|
className={this.isDragging ? 'lf-dragging' : 'lf-drag-able'}
|
|
287
|
-
|
|
287
|
+
onPointerDown={(e) => this.beforeDragStart(e, appendInfo)}
|
|
288
288
|
>
|
|
289
289
|
<g className={className}>{this.getAppendShape(appendInfo)}</g>
|
|
290
290
|
</g>
|
|
@@ -42,6 +42,7 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
|
|
|
42
42
|
mouseUpDrag?: boolean
|
|
43
43
|
startTime?: number
|
|
44
44
|
modelDisposer: IReactionDisposer
|
|
45
|
+
longPressTimer?: number
|
|
45
46
|
|
|
46
47
|
constructor(props: IProps) {
|
|
47
48
|
super()
|
|
@@ -88,9 +89,9 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
|
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
91
|
|
|
91
|
-
componentDidMount() {
|
|
92
|
+
componentDidMount() {}
|
|
92
93
|
|
|
93
|
-
componentDidUpdate() {
|
|
94
|
+
componentDidUpdate() {}
|
|
94
95
|
|
|
95
96
|
abstract getShape(): h.JSX.Element | null
|
|
96
97
|
|
|
@@ -330,6 +331,10 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
|
|
|
330
331
|
handleMouseUp = () => {
|
|
331
332
|
const { model } = this.props
|
|
332
333
|
this.mouseUpDrag = model.isDragging
|
|
334
|
+
if (this.longPressTimer) {
|
|
335
|
+
clearTimeout(this.longPressTimer)
|
|
336
|
+
this.longPressTimer = undefined
|
|
337
|
+
}
|
|
333
338
|
}
|
|
334
339
|
|
|
335
340
|
handleClick = (e: MouseEvent) => {
|
|
@@ -431,13 +436,23 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
|
|
|
431
436
|
}
|
|
432
437
|
}
|
|
433
438
|
|
|
434
|
-
handleMouseDown = (ev:
|
|
439
|
+
handleMouseDown = (ev: PointerEvent) => {
|
|
435
440
|
const { model, graphModel } = this.props
|
|
436
441
|
this.startTime = new Date().getTime()
|
|
437
442
|
const { editConfigModel } = graphModel
|
|
438
443
|
if (editConfigModel.adjustNodePosition && model.draggable) {
|
|
439
444
|
this.stepDrag && this.stepDrag.handleMouseDown(ev)
|
|
440
445
|
}
|
|
446
|
+
if (this.longPressTimer) {
|
|
447
|
+
clearTimeout(this.longPressTimer)
|
|
448
|
+
}
|
|
449
|
+
if (ev.pointerType === 'touch') {
|
|
450
|
+
this.longPressTimer = window.setTimeout(() => {
|
|
451
|
+
if (!this.props.model.isDragging) {
|
|
452
|
+
this.handleContextMenu(ev)
|
|
453
|
+
}
|
|
454
|
+
}, 500)
|
|
455
|
+
}
|
|
441
456
|
}
|
|
442
457
|
|
|
443
458
|
handleFocus = () => {
|
|
@@ -532,9 +547,10 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
|
|
|
532
547
|
nodeShape = (
|
|
533
548
|
<g
|
|
534
549
|
className={`${this.getStateClassName()} ${className}`}
|
|
535
|
-
|
|
536
|
-
|
|
550
|
+
onPointerDown={this.handleMouseDown}
|
|
551
|
+
onPointerUp={this.handleMouseUp}
|
|
537
552
|
onClick={this.handleClick}
|
|
553
|
+
//因为移动端点击操作完成会按顺序触发enter、leave、click事件,所以会造成节点的闪烁,所以在这里没有统一状态为Pointer
|
|
538
554
|
onMouseEnter={this.setHoverOn}
|
|
539
555
|
onMouseOver={this.setHoverOn}
|
|
540
556
|
onMouseLeave={this.setHoverOff}
|
|
@@ -18,6 +18,12 @@ export class CanvasOverlay extends Component<IProps, IState> {
|
|
|
18
18
|
stepDrag: StepDrag
|
|
19
19
|
stepScrollX = 0
|
|
20
20
|
stepScrollY = 0
|
|
21
|
+
pointers = new Map<number, { x: number; y: number }>()
|
|
22
|
+
pinchStartDistance?: number
|
|
23
|
+
pinchStartScale?: number
|
|
24
|
+
pinchLastCenterX?: number
|
|
25
|
+
pinchLastCenterY?: number
|
|
26
|
+
longPressTimer?: number
|
|
21
27
|
|
|
22
28
|
constructor(props: IProps) {
|
|
23
29
|
super()
|
|
@@ -43,6 +49,10 @@ export class CanvasOverlay extends Component<IProps, IState> {
|
|
|
43
49
|
// return this.props as InjectedProps;
|
|
44
50
|
// }
|
|
45
51
|
onDragging = ({ deltaX, deltaY }: IDragParams) => {
|
|
52
|
+
if (this.longPressTimer) {
|
|
53
|
+
clearTimeout(this.longPressTimer)
|
|
54
|
+
this.longPressTimer = undefined
|
|
55
|
+
}
|
|
46
56
|
this.setState({
|
|
47
57
|
isDragging: true,
|
|
48
58
|
})
|
|
@@ -125,7 +135,7 @@ export class CanvasOverlay extends Component<IProps, IState> {
|
|
|
125
135
|
}
|
|
126
136
|
}
|
|
127
137
|
// 鼠标、触摸板 按下
|
|
128
|
-
|
|
138
|
+
pointerDownHandler = (ev: PointerEvent) => {
|
|
129
139
|
const {
|
|
130
140
|
graphModel: {
|
|
131
141
|
eventCenter,
|
|
@@ -134,6 +144,36 @@ export class CanvasOverlay extends Component<IProps, IState> {
|
|
|
134
144
|
gridSize,
|
|
135
145
|
},
|
|
136
146
|
} = this.props
|
|
147
|
+
this.pointers.set(ev.pointerId, { x: ev.clientX, y: ev.clientY })
|
|
148
|
+
if (this.longPressTimer) {
|
|
149
|
+
clearTimeout(this.longPressTimer)
|
|
150
|
+
}
|
|
151
|
+
if (ev.pointerType === 'touch') {
|
|
152
|
+
this.longPressTimer = window.setTimeout(() => {
|
|
153
|
+
this.handleContextMenu(ev)
|
|
154
|
+
}, 500)
|
|
155
|
+
}
|
|
156
|
+
// 检测双指触摸,初始化捏合缩放
|
|
157
|
+
if (this.pointers.size === 2) {
|
|
158
|
+
const {
|
|
159
|
+
graphModel: { transformModel, editConfigModel },
|
|
160
|
+
} = this.props
|
|
161
|
+
// 记录两指当前位置用于计算初始距离
|
|
162
|
+
const pts = Array.from(this.pointers.values())
|
|
163
|
+
const dx = pts[0].x - pts[1].x
|
|
164
|
+
const dy = pts[0].y - pts[1].y
|
|
165
|
+
const cx = (pts[0].x + pts[1].x) / 2
|
|
166
|
+
const cy = (pts[0].y + pts[1].y) / 2
|
|
167
|
+
// 记录捏合起始距离与当前缩放,后续按比例计算缩放
|
|
168
|
+
this.pinchStartDistance = Math.hypot(dx, dy)
|
|
169
|
+
this.pinchStartScale = transformModel.SCALE_X
|
|
170
|
+
// 双指操作下取消画布拖拽,避免与捏合缩放冲突
|
|
171
|
+
this.stepDrag.cancelDrag()
|
|
172
|
+
this.pinchLastCenterX = cx
|
|
173
|
+
this.pinchLastCenterY = cy
|
|
174
|
+
editConfigModel.updateEditConfig({ isPinching: true })
|
|
175
|
+
return
|
|
176
|
+
}
|
|
137
177
|
const { adjustEdge, adjustNodePosition, stopMoveGraph } = editConfigModel
|
|
138
178
|
const target = ev.target as HTMLElement
|
|
139
179
|
const isFrozenElement = !adjustEdge && !adjustNodePosition
|
|
@@ -148,13 +188,76 @@ export class CanvasOverlay extends Component<IProps, IState> {
|
|
|
148
188
|
this.clickHandler(ev)
|
|
149
189
|
}
|
|
150
190
|
}
|
|
191
|
+
pointerMoveHandler = (ev: PointerEvent) => {
|
|
192
|
+
// 记录当前指针位置(按 pointerId)
|
|
193
|
+
this.pointers.set(ev.pointerId, { x: ev.clientX, y: ev.clientY })
|
|
194
|
+
// 当已记录初始捏合距离且存在两指时,执行捏合缩放
|
|
195
|
+
if (this.pinchStartDistance && this.pointers.size >= 2) {
|
|
196
|
+
const {
|
|
197
|
+
graphModel,
|
|
198
|
+
graphModel: { editConfigModel, transformModel },
|
|
199
|
+
} = this.props
|
|
200
|
+
if (editConfigModel.stopZoomGraph) return
|
|
201
|
+
// 取消触摸长按计时,避免捏合过程中误触发上下文菜单
|
|
202
|
+
if (this.longPressTimer) {
|
|
203
|
+
clearTimeout(this.longPressTimer)
|
|
204
|
+
}
|
|
205
|
+
// 计算两指间当前距离
|
|
206
|
+
const pts = Array.from(this.pointers.values())
|
|
207
|
+
const dx = pts[0].x - pts[1].x
|
|
208
|
+
const dy = pts[0].y - pts[1].y
|
|
209
|
+
const dist = Math.hypot(dx, dy)
|
|
210
|
+
// 以初始缩放为基准,根据距离比例得到新的缩放比例
|
|
211
|
+
const scale =
|
|
212
|
+
(this.pinchStartScale ?? transformModel.SCALE_X) *
|
|
213
|
+
(dist / this.pinchStartDistance)
|
|
214
|
+
// 取两指中心作为缩放原点,并转换为画布坐标系
|
|
215
|
+
const cx = (pts[0].x + pts[1].x) / 2
|
|
216
|
+
const cy = (pts[0].y + pts[1].y) / 2
|
|
217
|
+
const pos = graphModel.getPointByClient({ x: cx, y: cy })
|
|
218
|
+
const { x, y } = pos.canvasOverlayPosition
|
|
219
|
+
transformModel.zoom(scale, [x, y])
|
|
220
|
+
// 双指中心位移驱动画布平移,配合缩放实现捏合移动;
|
|
221
|
+
if (!editConfigModel.stopMoveGraph || editConfigModel.isPinching) {
|
|
222
|
+
const deltaX =
|
|
223
|
+
this.pinchLastCenterX === undefined ? 0 : cx - this.pinchLastCenterX
|
|
224
|
+
const deltaY =
|
|
225
|
+
this.pinchLastCenterY === undefined ? 0 : cy - this.pinchLastCenterY
|
|
226
|
+
transformModel.translate(deltaX, deltaY)
|
|
227
|
+
this.pinchLastCenterX = cx
|
|
228
|
+
this.pinchLastCenterY = cy
|
|
229
|
+
}
|
|
230
|
+
ev.preventDefault()
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
pointerUpHandler = (ev: PointerEvent) => {
|
|
234
|
+
this.pointers.delete(ev.pointerId)
|
|
235
|
+
if (this.longPressTimer) {
|
|
236
|
+
clearTimeout(this.longPressTimer)
|
|
237
|
+
this.longPressTimer = undefined
|
|
238
|
+
}
|
|
239
|
+
// 双指松开或仅剩一指:结束捏合手势并清理临时状态
|
|
240
|
+
if (this.pointers.size < 2) {
|
|
241
|
+
// 清空捏合距离与缩放起始值
|
|
242
|
+
this.pinchStartDistance = undefined
|
|
243
|
+
this.pinchStartScale = undefined
|
|
244
|
+
// 清空上一帧的双指中心
|
|
245
|
+
this.pinchLastCenterX = undefined
|
|
246
|
+
this.pinchLastCenterY = undefined
|
|
247
|
+
const {
|
|
248
|
+
graphModel: { editConfigModel },
|
|
249
|
+
} = this.props
|
|
250
|
+
// 标记退出捏合,框选等交互可恢复
|
|
251
|
+
editConfigModel.updateEditConfig({ isPinching: false })
|
|
252
|
+
}
|
|
253
|
+
}
|
|
151
254
|
|
|
152
255
|
render() {
|
|
153
256
|
const {
|
|
154
257
|
graphModel: { transformModel },
|
|
155
258
|
} = this.props
|
|
156
259
|
const { transform } = transformModel.getTransformStyle()
|
|
157
|
-
const { children
|
|
260
|
+
const { children } = this.props
|
|
158
261
|
const { isDragging } = this.state
|
|
159
262
|
|
|
160
263
|
return (
|
|
@@ -164,14 +267,17 @@ export class CanvasOverlay extends Component<IProps, IState> {
|
|
|
164
267
|
height="100%"
|
|
165
268
|
name="canvas-overlay"
|
|
166
269
|
onWheel={this.zoomHandler}
|
|
167
|
-
|
|
270
|
+
onPointerDown={this.pointerDownHandler}
|
|
271
|
+
onPointerMove={this.pointerMoveHandler}
|
|
272
|
+
onPointerUp={this.pointerUpHandler}
|
|
273
|
+
onPointerCancel={this.pointerUpHandler}
|
|
168
274
|
onContextMenu={this.handleContextMenu}
|
|
275
|
+
style={{ touchAction: 'none', WebkitUserSelect: 'none' }}
|
|
169
276
|
className={
|
|
170
277
|
isDragging
|
|
171
278
|
? 'lf-canvas-overlay lf-dragging'
|
|
172
279
|
: 'lf-canvas-overlay lf-drag-able'
|
|
173
280
|
}
|
|
174
|
-
{...dnd.eventMap()}
|
|
175
281
|
>
|
|
176
282
|
<g transform={transform}>{children}</g>
|
|
177
283
|
</svg>
|
|
@@ -73,7 +73,7 @@ export class BaseText<
|
|
|
73
73
|
)
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
mouseDownHandler = (e:
|
|
76
|
+
mouseDownHandler = (e: PointerEvent) => {
|
|
77
77
|
const { draggable, model, graphModel } = this.props
|
|
78
78
|
const {
|
|
79
79
|
editConfigModel: { nodeTextDraggable },
|
|
@@ -120,7 +120,10 @@ export class BaseText<
|
|
|
120
120
|
} = this.props
|
|
121
121
|
if (text) {
|
|
122
122
|
return (
|
|
123
|
-
<g
|
|
123
|
+
<g
|
|
124
|
+
onPointerDown={this.mouseDownHandler}
|
|
125
|
+
onDblClick={this.dbClickHandler}
|
|
126
|
+
>
|
|
124
127
|
{this.getShape()}
|
|
125
128
|
</g>
|
|
126
129
|
)
|