@logicflow/core 2.1.3 → 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.
Files changed (96) hide show
  1. package/.turbo/turbo-build$colon$dev.log +2 -2
  2. package/.turbo/turbo-build.log +6 -6
  3. package/CHANGELOG.md +15 -0
  4. package/dist/index.min.js +1 -1
  5. package/dist/index.min.js.map +1 -1
  6. package/es/LogicFlow.d.ts +2 -1
  7. package/es/LogicFlow.js +4 -1
  8. package/es/constant/index.d.ts +3 -1
  9. package/es/constant/index.js +2 -0
  10. package/es/model/EditConfigModel.d.ts +3 -1
  11. package/es/model/EditConfigModel.js +5 -0
  12. package/es/model/GraphModel.d.ts +9 -1
  13. package/es/model/GraphModel.js +35 -8
  14. package/es/model/edge/BaseEdgeModel.d.ts +2 -1
  15. package/es/model/edge/BaseEdgeModel.js +29 -5
  16. package/es/model/node/BaseNodeModel.d.ts +2 -1
  17. package/es/model/node/BaseNodeModel.js +29 -5
  18. package/es/tool/MultipleSelectTool.d.ts +1 -1
  19. package/es/tool/MultipleSelectTool.js +1 -1
  20. package/es/util/drag.d.ts +4 -4
  21. package/es/util/drag.js +12 -6
  22. package/es/view/Anchor.d.ts +3 -3
  23. package/es/view/Anchor.js +30 -4
  24. package/es/view/Control.js +1 -1
  25. package/es/view/Rotate.js +1 -1
  26. package/es/view/behavior/dnd.d.ts +4 -8
  27. package/es/view/behavior/dnd.js +50 -14
  28. package/es/view/edge/AdjustPoint.d.ts +1 -1
  29. package/es/view/edge/AdjustPoint.js +1 -1
  30. package/es/view/edge/BaseEdge.d.ts +2 -1
  31. package/es/view/edge/BaseEdge.js +18 -1
  32. package/es/view/edge/PolylineEdge.d.ts +1 -1
  33. package/es/view/edge/PolylineEdge.js +1 -1
  34. package/es/view/node/BaseNode.d.ts +2 -1
  35. package/es/view/node/BaseNode.js +30 -3
  36. package/es/view/overlay/BezierAdjustOverlay.js +1 -1
  37. package/es/view/overlay/CanvasOverlay.d.ts +12 -1
  38. package/es/view/overlay/CanvasOverlay.js +94 -15
  39. package/es/view/text/BaseText.d.ts +1 -1
  40. package/es/view/text/BaseText.js +1 -1
  41. package/lib/LogicFlow.d.ts +2 -1
  42. package/lib/LogicFlow.js +3 -0
  43. package/lib/constant/index.d.ts +3 -1
  44. package/lib/constant/index.js +2 -0
  45. package/lib/model/EditConfigModel.d.ts +3 -1
  46. package/lib/model/EditConfigModel.js +5 -0
  47. package/lib/model/GraphModel.d.ts +9 -1
  48. package/lib/model/GraphModel.js +35 -8
  49. package/lib/model/edge/BaseEdgeModel.d.ts +2 -1
  50. package/lib/model/edge/BaseEdgeModel.js +29 -5
  51. package/lib/model/node/BaseNodeModel.d.ts +2 -1
  52. package/lib/model/node/BaseNodeModel.js +29 -5
  53. package/lib/tool/MultipleSelectTool.d.ts +1 -1
  54. package/lib/tool/MultipleSelectTool.js +1 -1
  55. package/lib/util/drag.d.ts +4 -4
  56. package/lib/util/drag.js +12 -6
  57. package/lib/view/Anchor.d.ts +3 -3
  58. package/lib/view/Anchor.js +30 -4
  59. package/lib/view/Control.js +1 -1
  60. package/lib/view/Rotate.js +1 -1
  61. package/lib/view/behavior/dnd.d.ts +4 -8
  62. package/lib/view/behavior/dnd.js +50 -14
  63. package/lib/view/edge/AdjustPoint.d.ts +1 -1
  64. package/lib/view/edge/AdjustPoint.js +1 -1
  65. package/lib/view/edge/BaseEdge.d.ts +2 -1
  66. package/lib/view/edge/BaseEdge.js +18 -1
  67. package/lib/view/edge/PolylineEdge.d.ts +1 -1
  68. package/lib/view/edge/PolylineEdge.js +1 -1
  69. package/lib/view/node/BaseNode.d.ts +2 -1
  70. package/lib/view/node/BaseNode.js +30 -3
  71. package/lib/view/overlay/BezierAdjustOverlay.js +1 -1
  72. package/lib/view/overlay/CanvasOverlay.d.ts +12 -1
  73. package/lib/view/overlay/CanvasOverlay.js +94 -15
  74. package/lib/view/text/BaseText.d.ts +1 -1
  75. package/lib/view/text/BaseText.js +1 -1
  76. package/package.json +1 -1
  77. package/src/LogicFlow.tsx +9 -1
  78. package/src/constant/index.ts +2 -0
  79. package/src/model/EditConfigModel.ts +3 -0
  80. package/src/model/GraphModel.ts +37 -11
  81. package/src/model/edge/BaseEdgeModel.ts +32 -5
  82. package/src/model/node/BaseNodeModel.ts +30 -5
  83. package/src/tool/MultipleSelectTool.tsx +2 -2
  84. package/src/util/drag.ts +16 -12
  85. package/src/view/Anchor.tsx +32 -6
  86. package/src/view/Control.tsx +1 -1
  87. package/src/view/Rotate.tsx +1 -1
  88. package/src/view/behavior/dnd.ts +55 -16
  89. package/src/view/edge/AdjustPoint.tsx +2 -2
  90. package/src/view/edge/BaseEdge.tsx +23 -3
  91. package/src/view/edge/PolylineEdge.tsx +2 -2
  92. package/src/view/node/BaseNode.tsx +30 -4
  93. package/src/view/overlay/BezierAdjustOverlay.tsx +1 -1
  94. package/src/view/overlay/CanvasOverlay.tsx +110 -4
  95. package/src/view/text/BaseText.tsx +5 -2
  96. package/stats.html +1 -1
@@ -6,22 +6,18 @@ export declare class Dnd {
6
6
  nodeConfig: OnDragNodeConfig | null;
7
7
  lf: LogicFlow;
8
8
  fakeNode: BaseNodeModel | null;
9
+ docPointerMove?: (e: PointerEvent) => void;
10
+ docPointerUp?: (e: PointerEvent) => void;
9
11
  constructor(params: {
10
12
  lf: LogicFlow;
11
13
  });
12
14
  clientToLocalPoint({ x, y }: Position): Position;
15
+ isInsideCanvas(e: PointerEvent): boolean;
13
16
  startDrag(nodeConfig: OnDragNodeConfig): void;
14
17
  stopDrag: () => void;
15
- dragEnter: (e: MouseEvent) => void;
18
+ dragEnter: (e: PointerEvent) => void;
16
19
  onDragOver: (e: MouseEvent) => boolean;
17
20
  onDragLeave: () => void;
18
21
  onDrop: (e: MouseEvent) => void;
19
- eventMap(): {
20
- onMouseEnter: (e: MouseEvent) => void;
21
- onMouseOver: (e: MouseEvent) => void;
22
- onMouseMove: (e: MouseEvent) => boolean;
23
- onMouseLeave: () => void;
24
- onMouseUp: (e: MouseEvent) => void;
25
- };
26
22
  }
27
23
  export default Dnd;
@@ -19,7 +19,12 @@ var Dnd = /** @class */ (function () {
19
19
  this.fakeNode = null;
20
20
  this.stopDrag = function () {
21
21
  _this.nodeConfig = null;
22
- window.document.removeEventListener('mouseup', _this.stopDrag);
22
+ if (_this.docPointerMove) {
23
+ window.document.removeEventListener('pointermove', _this.docPointerMove);
24
+ }
25
+ if (_this.docPointerUp) {
26
+ window.document.removeEventListener('pointerup', _this.docPointerUp);
27
+ }
23
28
  };
24
29
  this.dragEnter = function (e) {
25
30
  if (!_this.nodeConfig || _this.fakeNode)
@@ -91,22 +96,53 @@ var Dnd = /** @class */ (function () {
91
96
  y: snapToGrid(y1, gridSize, snapGrid),
92
97
  };
93
98
  };
99
+ Dnd.prototype.isInsideCanvas = function (e) {
100
+ var overlay = this.lf.graphModel.rootEl.querySelector('[name="canvas-overlay"]');
101
+ var topEl = window.document.elementFromPoint(e.clientX, e.clientY);
102
+ return (topEl === overlay ||
103
+ (topEl !== null && !!overlay && overlay.contains(topEl)));
104
+ };
94
105
  Dnd.prototype.startDrag = function (nodeConfig) {
106
+ var _this = this;
95
107
  var editConfigModel = this.lf.graphModel.editConfigModel;
96
- if (!(editConfigModel === null || editConfigModel === void 0 ? void 0 : editConfigModel.isSilentMode)) {
97
- this.nodeConfig = nodeConfig;
98
- window.document.addEventListener('mouseup', this.stopDrag);
99
- }
100
- };
101
- Dnd.prototype.eventMap = function () {
102
- return {
103
- onMouseEnter: this.dragEnter,
104
- onMouseOver: this.dragEnter, // IE11
105
- onMouseMove: this.onDragOver,
106
- onMouseLeave: this.onDragLeave,
107
- // onMouseOut: this.onDragLeave, // IE11
108
- onMouseUp: this.onDrop,
108
+ if (editConfigModel === null || editConfigModel === void 0 ? void 0 : editConfigModel.isSilentMode)
109
+ return;
110
+ this.nodeConfig = nodeConfig;
111
+ // 指针移动:根据命中结果判断是否在画布覆盖层上,驱动假节点创建/移动或清理
112
+ this.docPointerMove = function (e) {
113
+ if (!_this.nodeConfig)
114
+ return;
115
+ // 离开画布:清理吸附线与假节点
116
+ if (!_this.isInsideCanvas(e)) {
117
+ _this.onDragLeave();
118
+ return;
119
+ }
120
+ // 首次进入画布:创建假节点并初始化位置
121
+ if (!_this.fakeNode) {
122
+ _this.dragEnter(e);
123
+ return;
124
+ }
125
+ // 在画布内移动:更新假节点位置与吸附线
126
+ _this.onDragOver(e);
127
+ };
128
+ // 指针抬起:在画布内落点生成节点,否则清理假节点
129
+ this.docPointerUp = function (e) {
130
+ if (!_this.nodeConfig)
131
+ return;
132
+ if (_this.isInsideCanvas(e)) {
133
+ _this.onDrop(e);
134
+ }
135
+ else {
136
+ _this.onDragLeave();
137
+ }
138
+ // 阻止默认行为与冒泡,避免滚动/点击穿透
139
+ e.preventDefault();
140
+ e.stopPropagation();
141
+ // 结束拖拽并移除监听
142
+ _this.stopDrag();
109
143
  };
144
+ window.document.addEventListener('pointermove', this.docPointerMove);
145
+ window.document.addEventListener('pointerup', this.docPointerUp);
110
146
  };
111
147
  return Dnd;
112
148
  }());
@@ -34,7 +34,7 @@ export declare class AdjustPoint extends Component<IProps, IState> {
34
34
  targetRuleResults: Map<any, any>;
35
35
  sourceRuleResults: Map<any, any>;
36
36
  constructor(props: IProps);
37
- handleMouseDown: (ev: MouseEvent) => void;
37
+ handleMouseDown: (ev: PointerEvent) => void;
38
38
  onDragStart: () => void;
39
39
  onDragging: ({ deltaX, deltaY }: IDragParams) => void;
40
40
  onDragEnd: ({ event }: Partial<IDragParams>) => void;
@@ -348,7 +348,7 @@ var AdjustPoint = /** @class */ (function (_super) {
348
348
  AdjustPoint.prototype.render = function () {
349
349
  var _a = this.props, x = _a.x, y = _a.y, getAdjustPointShape = _a.getAdjustPointShape, edgeModel = _a.edgeModel;
350
350
  var dragging = this.state.dragging;
351
- return (_jsx("g", { pointerEvents: dragging ? 'none' : '', onMouseDown: this.handleMouseDown, children: !dragging ? getAdjustPointShape(x, y, edgeModel) : '' }));
351
+ return (_jsx("g", { pointerEvents: dragging ? 'none' : '', onPointerDown: this.handleMouseDown, children: !dragging ? getAdjustPointShape(x, y, edgeModel) : '' }));
352
352
  };
353
353
  return AdjustPoint;
354
354
  }(Component));
@@ -17,6 +17,7 @@ export declare abstract class BaseEdge<P extends IProps> extends Component<P, IE
17
17
  startTime?: number;
18
18
  contextMenuTime?: number;
19
19
  clickTimer?: number;
20
+ longPressTimer?: number;
20
21
  textRef: import("preact").RefObject<any>;
21
22
  constructor();
22
23
  /**
@@ -131,7 +132,7 @@ export declare abstract class BaseEdge<P extends IProps> extends Component<P, IE
131
132
  /**
132
133
  * 不支持重写
133
134
  */
134
- handleMouseDown: (e: MouseEvent) => void;
135
+ handleMouseDown: (e: PointerEvent) => void;
135
136
  handleMouseUp: () => void;
136
137
  /**
137
138
  * 不支持重写
@@ -126,10 +126,24 @@ var BaseEdge = /** @class */ (function (_super) {
126
126
  _this.handleMouseDown = function (e) {
127
127
  e.stopPropagation();
128
128
  _this.startTime = new Date().getTime();
129
+ if (_this.longPressTimer) {
130
+ clearTimeout(_this.longPressTimer);
131
+ }
132
+ if (e.pointerType === 'touch') {
133
+ _this.longPressTimer = window.setTimeout(function () {
134
+ if (!_this.props.model.isDragging) {
135
+ _this.handleContextMenu(e);
136
+ }
137
+ }, 500);
138
+ }
129
139
  };
130
140
  _this.handleMouseUp = function () {
131
141
  var model = _this.props.model;
132
142
  _this.mouseUpDrag = model.isDragging;
143
+ if (_this.longPressTimer) {
144
+ clearTimeout(_this.longPressTimer);
145
+ _this.longPressTimer = undefined;
146
+ }
133
147
  };
134
148
  /**
135
149
  * 不支持重写
@@ -452,7 +466,10 @@ var BaseEdge = /** @class */ (function (_super) {
452
466
  isSelected && 'lf-edge-selected',
453
467
  ]
454
468
  .filter(Boolean)
455
- .join(' '), onMouseDown: this.handleMouseDown, onMouseUp: this.handleMouseUp, onClick: this.handleClick, onContextMenu: this.handleContextMenu, onMouseOver: this.setHoverOn, onMouseEnter: this.setHoverOn, onMouseLeave: this.setHoverOff, onFocus: this.handleFocus, onBlur: this.handleBlur, children: [this.getShape(), this.getAppend(), this.getText(), this.getArrow()] }), isShowAdjustPoint && isSelected ? this.getAdjustPoints() : ''] }));
469
+ .join(' '), style: {
470
+ touchAction: 'none',
471
+ WebkitTouchCallout: 'none',
472
+ }, onClick: this.handleClick, onContextMenu: this.handleContextMenu, onPointerDown: this.handleMouseDown, onPointerUp: this.handleMouseUp, onPointerCancel: this.handleMouseUp, onMouseOver: this.setHoverOn, onMouseEnter: this.setHoverOn, onMouseLeave: this.setHoverOff, onFocus: this.handleFocus, onBlur: this.handleBlur, children: [this.getShape(), this.getAppend(), this.getText(), this.getArrow()] }), isShowAdjustPoint && isSelected ? this.getAdjustPoints() : ''] }));
456
473
  };
457
474
  BaseEdge.isObserved = false;
458
475
  return BaseEdge;
@@ -34,7 +34,7 @@ export declare class PolylineEdge extends BaseEdge<IPolylineEdgeProps> {
34
34
  /**
35
35
  * 不支持重写
36
36
  */
37
- beforeDragStart: (e: any, appendInfo: any) => void;
37
+ beforeDragStart: (e: PointerEvent, appendInfo: any) => void;
38
38
  /**
39
39
  * @overridable 支持重写, 此方法为获取边的形状,如果需要自定义边的形状,请重写此方法。
40
40
  * @example https://docs.logic-flow.cn/docs/#/zh/guide/basic/edge?id=%e5%9f%ba%e4%ba%8e-react-%e7%bb%84%e4%bb%b6%e8%87%aa%e5%ae%9a%e4%b9%89%e8%be%b9
@@ -257,7 +257,7 @@ var PolylineEdge = /** @class */ (function (_super) {
257
257
  }
258
258
  appendInfo.direction = SegmentDirection.HORIZONTAL;
259
259
  }
260
- append = (_jsx("g", { className: this_1.isDragging ? 'lf-dragging' : 'lf-drag-able', onMouseDown: function (e) { return _this.beforeDragStart(e, appendInfo); }, children: _jsx("g", { className: className, children: this_1.getAppendShape(appendInfo) }) }));
260
+ append = (_jsx("g", { className: this_1.isDragging ? 'lf-dragging' : 'lf-drag-able', onPointerDown: function (e) { return _this.beforeDragStart(e, appendInfo); }, children: _jsx("g", { className: className, children: this_1.getAppendShape(appendInfo) }) }));
261
261
  }
262
262
  LineAppendList.push(append);
263
263
  };
@@ -19,6 +19,7 @@ export declare abstract class BaseNode<P extends IProps = IProps> extends Compon
19
19
  mouseUpDrag?: boolean;
20
20
  startTime?: number;
21
21
  modelDisposer: IReactionDisposer;
22
+ longPressTimer?: number;
22
23
  constructor(props: IProps);
23
24
  componentWillUnmount(): void;
24
25
  componentDidMount(): void;
@@ -37,7 +38,7 @@ export declare abstract class BaseNode<P extends IProps = IProps> extends Compon
37
38
  handleMouseUp: () => void;
38
39
  handleClick: (e: MouseEvent) => void;
39
40
  handleContextMenu: (ev: MouseEvent) => void;
40
- handleMouseDown: (ev: MouseEvent) => void;
41
+ handleMouseDown: (ev: PointerEvent) => void;
41
42
  handleFocus: () => void;
42
43
  handleBlur: () => void;
43
44
  setHoverOn: (ev: MouseEvent) => void;
@@ -168,16 +168,28 @@ var BaseNode = /** @class */ (function (_super) {
168
168
  _this.handleMouseUp = function () {
169
169
  var model = _this.props.model;
170
170
  _this.mouseUpDrag = model.isDragging;
171
+ if (_this.longPressTimer) {
172
+ clearTimeout(_this.longPressTimer);
173
+ _this.longPressTimer = undefined;
174
+ }
171
175
  };
172
176
  _this.handleClick = function (e) {
173
177
  // 节点拖拽进画布之后,不触发click事件相关emit
174
178
  // 点拖拽进画布没有触发mousedown事件,没有startTime,用这个值做区分
175
179
  var isDragging = _this.mouseUpDrag === false;
180
+ var curTime = new Date().getTime();
176
181
  if (!_this.startTime)
177
182
  return;
183
+ var timeInterval = curTime - _this.startTime;
178
184
  var _a = _this.props, model = _a.model, graphModel = _a.graphModel;
179
- if (!isDragging)
180
- return; // 如果是拖拽, 不触发click事件。
185
+ // 这里会有一种极端情况:当网格大小是1或者关闭网格吸附时,用触摸板点击节点会触发拖拽事件导致节点无法选中
186
+ // 当触摸板点击节点时,为了防止误触发拖拽导致节点无法选中,允许在非拖拽状态且时间间隔小于100ms时触发点击事件
187
+ if (!isDragging && timeInterval > 100)
188
+ return;
189
+ if (!isDragging) {
190
+ _this.onDragEnd();
191
+ _this.handleMouseUp();
192
+ }
181
193
  // 节点数据,多为事件对象数据抛出
182
194
  var nodeData = model.getData();
183
195
  var position = graphModel.getPointByClient({
@@ -260,6 +272,16 @@ var BaseNode = /** @class */ (function (_super) {
260
272
  if (editConfigModel.adjustNodePosition && model.draggable) {
261
273
  _this.stepDrag && _this.stepDrag.handleMouseDown(ev);
262
274
  }
275
+ if (_this.longPressTimer) {
276
+ clearTimeout(_this.longPressTimer);
277
+ }
278
+ if (ev.pointerType === 'touch') {
279
+ _this.longPressTimer = window.setTimeout(function () {
280
+ if (!_this.props.model.isDragging) {
281
+ _this.handleContextMenu(ev);
282
+ }
283
+ }, 500);
284
+ }
263
285
  };
264
286
  _this.handleFocus = function () {
265
287
  var _a = _this.props, model = _a.model, graphModel = _a.graphModel;
@@ -268,6 +290,9 @@ var BaseNode = /** @class */ (function (_super) {
268
290
  });
269
291
  };
270
292
  _this.handleBlur = function () {
293
+ // 当节点通过自定义锚点实现节点删除时,这里props会变成undefined,需兼容一下
294
+ if (!_this.props)
295
+ return;
271
296
  var _a = _this.props, model = _a.model, graphModel = _a.graphModel;
272
297
  graphModel.eventCenter.emit(EventType.NODE_BLUR, {
273
298
  data: model.getData(),
@@ -438,7 +463,9 @@ var BaseNode = /** @class */ (function (_super) {
438
463
  if (adjustNodePosition && draggable) {
439
464
  this.stepDrag.setStep(gridSize * SCALE_X);
440
465
  }
441
- nodeShape = (_jsx("g", __assign({ className: "".concat(this.getStateClassName(), " ").concat(className), onMouseDown: this.handleMouseDown, onMouseUp: this.handleMouseUp, onClick: this.handleClick, onMouseEnter: this.setHoverOn, onMouseOver: this.setHoverOn, onMouseLeave: this.setHoverOff, onMouseOut: this.onMouseOut, onContextMenu: this.handleContextMenu, onFocus: this.handleFocus, onBlur: this.handleBlur }, restAttributes, { children: nodeShapeInner })));
466
+ nodeShape = (_jsx("g", __assign({ className: "".concat(this.getStateClassName(), " ").concat(className), onPointerDown: this.handleMouseDown, onPointerUp: this.handleMouseUp, onClick: this.handleClick,
467
+ //因为移动端点击操作完成会按顺序触发enter、leave、click事件,所以会造成节点的闪烁,所以在这里没有统一状态为Pointer
468
+ onMouseEnter: this.setHoverOn, onMouseOver: this.setHoverOn, onMouseLeave: this.setHoverOff, onMouseOut: this.onMouseOut, onContextMenu: this.handleContextMenu, onFocus: this.handleFocus, onBlur: this.handleBlur }, restAttributes, { children: nodeShapeInner })));
442
469
  }
443
470
  return nodeShape;
444
471
  };
@@ -88,7 +88,7 @@ var BezierAdjustAnchor = /** @class */ (function (_super) {
88
88
  var x = position.x, y = position.y;
89
89
  var bezierModel = this.props.bezierModel;
90
90
  var adjustAnchor = bezierModel.getEdgeStyle().adjustAnchor;
91
- return (_jsx(Circle, __assign({ className: "lf-bezier-adjust-anchor", x: x, y: y }, adjustAnchor, { onMouseDown: function (ev) {
91
+ return (_jsx(Circle, __assign({ className: "lf-bezier-adjust-anchor", x: x, y: y }, adjustAnchor, { onPointerDown: function (ev) {
92
92
  // if (edgeAddable !== false) {
93
93
  _this.dragHandler.handleMouseDown(ev);
94
94
  // }
@@ -13,13 +13,24 @@ export declare class CanvasOverlay extends Component<IProps, IState> {
13
13
  stepDrag: StepDrag;
14
14
  stepScrollX: number;
15
15
  stepScrollY: number;
16
+ pointers: Map<number, {
17
+ x: number;
18
+ y: number;
19
+ }>;
20
+ pinchStartDistance?: number;
21
+ pinchStartScale?: number;
22
+ pinchLastCenterX?: number;
23
+ pinchLastCenterY?: number;
24
+ longPressTimer?: number;
16
25
  constructor(props: IProps);
17
26
  onDragging: ({ deltaX, deltaY }: IDragParams) => void;
18
27
  onDragEnd: () => void;
19
28
  zoomHandler: (ev: WheelEvent) => void;
20
29
  clickHandler: (ev: MouseEvent) => void;
21
30
  handleContextMenu: (ev: MouseEvent) => void;
22
- mouseDownHandler: (ev: MouseEvent) => void;
31
+ pointerDownHandler: (ev: PointerEvent) => void;
32
+ pointerMoveHandler: (ev: PointerEvent) => void;
33
+ pointerUpHandler: (ev: PointerEvent) => void;
23
34
  render(): import("preact/compat").JSX.Element;
24
35
  }
25
36
  export default CanvasOverlay;
@@ -13,17 +13,6 @@ var __extends = (this && this.__extends) || (function () {
13
13
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14
14
  };
15
15
  })();
16
- var __assign = (this && this.__assign) || function () {
17
- __assign = Object.assign || function(t) {
18
- for (var s, i = 1, n = arguments.length; i < n; i++) {
19
- s = arguments[i];
20
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
21
- t[p] = s[p];
22
- }
23
- return t;
24
- };
25
- return __assign.apply(this, arguments);
26
- };
27
16
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
28
17
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
29
18
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -41,11 +30,16 @@ var CanvasOverlay = /** @class */ (function (_super) {
41
30
  var _this = _super.call(this) || this;
42
31
  _this.stepScrollX = 0;
43
32
  _this.stepScrollY = 0;
33
+ _this.pointers = new Map();
44
34
  // get InjectedProps() {
45
35
  // return this.props as InjectedProps;
46
36
  // }
47
37
  _this.onDragging = function (_a) {
48
38
  var deltaX = _a.deltaX, deltaY = _a.deltaY;
39
+ if (_this.longPressTimer) {
40
+ clearTimeout(_this.longPressTimer);
41
+ _this.longPressTimer = undefined;
42
+ }
49
43
  _this.setState({
50
44
  isDragging: true,
51
45
  });
@@ -123,8 +117,36 @@ var CanvasOverlay = /** @class */ (function (_super) {
123
117
  }
124
118
  };
125
119
  // 鼠标、触摸板 按下
126
- _this.mouseDownHandler = function (ev) {
120
+ _this.pointerDownHandler = function (ev) {
127
121
  var _a = _this.props.graphModel, eventCenter = _a.eventCenter, editConfigModel = _a.editConfigModel, SCALE_X = _a.transformModel.SCALE_X, gridSize = _a.gridSize;
122
+ _this.pointers.set(ev.pointerId, { x: ev.clientX, y: ev.clientY });
123
+ if (_this.longPressTimer) {
124
+ clearTimeout(_this.longPressTimer);
125
+ }
126
+ if (ev.pointerType === 'touch') {
127
+ _this.longPressTimer = window.setTimeout(function () {
128
+ _this.handleContextMenu(ev);
129
+ }, 500);
130
+ }
131
+ // 检测双指触摸,初始化捏合缩放
132
+ if (_this.pointers.size === 2) {
133
+ var _b = _this.props.graphModel, transformModel = _b.transformModel, editConfigModel_1 = _b.editConfigModel;
134
+ // 记录两指当前位置用于计算初始距离
135
+ var pts = Array.from(_this.pointers.values());
136
+ var dx = pts[0].x - pts[1].x;
137
+ var dy = pts[0].y - pts[1].y;
138
+ var cx = (pts[0].x + pts[1].x) / 2;
139
+ var cy = (pts[0].y + pts[1].y) / 2;
140
+ // 记录捏合起始距离与当前缩放,后续按比例计算缩放
141
+ _this.pinchStartDistance = Math.hypot(dx, dy);
142
+ _this.pinchStartScale = transformModel.SCALE_X;
143
+ // 双指操作下取消画布拖拽,避免与捏合缩放冲突
144
+ _this.stepDrag.cancelDrag();
145
+ _this.pinchLastCenterX = cx;
146
+ _this.pinchLastCenterY = cy;
147
+ editConfigModel_1.updateEditConfig({ isPinching: true });
148
+ return;
149
+ }
128
150
  var adjustEdge = editConfigModel.adjustEdge, adjustNodePosition = editConfigModel.adjustNodePosition, stopMoveGraph = editConfigModel.stopMoveGraph;
129
151
  var target = ev.target;
130
152
  var isFrozenElement = !adjustEdge && !adjustNodePosition;
@@ -140,6 +162,63 @@ var CanvasOverlay = /** @class */ (function (_super) {
140
162
  _this.clickHandler(ev);
141
163
  }
142
164
  };
165
+ _this.pointerMoveHandler = function (ev) {
166
+ var _a;
167
+ // 记录当前指针位置(按 pointerId)
168
+ _this.pointers.set(ev.pointerId, { x: ev.clientX, y: ev.clientY });
169
+ // 当已记录初始捏合距离且存在两指时,执行捏合缩放
170
+ if (_this.pinchStartDistance && _this.pointers.size >= 2) {
171
+ var _b = _this.props, graphModel = _b.graphModel, _c = _b.graphModel, editConfigModel = _c.editConfigModel, transformModel = _c.transformModel;
172
+ if (editConfigModel.stopZoomGraph)
173
+ return;
174
+ // 取消触摸长按计时,避免捏合过程中误触发上下文菜单
175
+ if (_this.longPressTimer) {
176
+ clearTimeout(_this.longPressTimer);
177
+ }
178
+ // 计算两指间当前距离
179
+ var pts = Array.from(_this.pointers.values());
180
+ var dx = pts[0].x - pts[1].x;
181
+ var dy = pts[0].y - pts[1].y;
182
+ var dist = Math.hypot(dx, dy);
183
+ // 以初始缩放为基准,根据距离比例得到新的缩放比例
184
+ var scale = ((_a = _this.pinchStartScale) !== null && _a !== void 0 ? _a : transformModel.SCALE_X) *
185
+ (dist / _this.pinchStartDistance);
186
+ // 取两指中心作为缩放原点,并转换为画布坐标系
187
+ var cx = (pts[0].x + pts[1].x) / 2;
188
+ var cy = (pts[0].y + pts[1].y) / 2;
189
+ var pos = graphModel.getPointByClient({ x: cx, y: cy });
190
+ var _d = pos.canvasOverlayPosition, x = _d.x, y = _d.y;
191
+ transformModel.zoom(scale, [x, y]);
192
+ // 双指中心位移驱动画布平移,配合缩放实现捏合移动;
193
+ if (!editConfigModel.stopMoveGraph || editConfigModel.isPinching) {
194
+ var deltaX = _this.pinchLastCenterX === undefined ? 0 : cx - _this.pinchLastCenterX;
195
+ var deltaY = _this.pinchLastCenterY === undefined ? 0 : cy - _this.pinchLastCenterY;
196
+ transformModel.translate(deltaX, deltaY);
197
+ _this.pinchLastCenterX = cx;
198
+ _this.pinchLastCenterY = cy;
199
+ }
200
+ ev.preventDefault();
201
+ }
202
+ };
203
+ _this.pointerUpHandler = function (ev) {
204
+ _this.pointers.delete(ev.pointerId);
205
+ if (_this.longPressTimer) {
206
+ clearTimeout(_this.longPressTimer);
207
+ _this.longPressTimer = undefined;
208
+ }
209
+ // 双指松开或仅剩一指:结束捏合手势并清理临时状态
210
+ if (_this.pointers.size < 2) {
211
+ // 清空捏合距离与缩放起始值
212
+ _this.pinchStartDistance = undefined;
213
+ _this.pinchStartScale = undefined;
214
+ // 清空上一帧的双指中心
215
+ _this.pinchLastCenterX = undefined;
216
+ _this.pinchLastCenterY = undefined;
217
+ var editConfigModel = _this.props.graphModel.editConfigModel;
218
+ // 标记退出捏合,框选等交互可恢复
219
+ editConfigModel.updateEditConfig({ isPinching: false });
220
+ }
221
+ };
143
222
  var _a = props.graphModel, gridSize = _a.gridSize, eventCenter = _a.eventCenter;
144
223
  _this.stepDrag = new StepDrag({
145
224
  onDragging: _this.onDragging,
@@ -159,11 +238,11 @@ var CanvasOverlay = /** @class */ (function (_super) {
159
238
  CanvasOverlay.prototype.render = function () {
160
239
  var transformModel = this.props.graphModel.transformModel;
161
240
  var transform = transformModel.getTransformStyle().transform;
162
- var _a = this.props, children = _a.children, dnd = _a.dnd;
241
+ var children = this.props.children;
163
242
  var isDragging = this.state.isDragging;
164
- return (_jsx("svg", __assign({ xmlns: "http://www.w3.org/2000/svg", width: "100%", height: "100%", name: "canvas-overlay", onWheel: this.zoomHandler, onMouseDown: this.mouseDownHandler, onContextMenu: this.handleContextMenu, className: isDragging
243
+ return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "100%", height: "100%", name: "canvas-overlay", onWheel: this.zoomHandler, onPointerDown: this.pointerDownHandler, onPointerMove: this.pointerMoveHandler, onPointerUp: this.pointerUpHandler, onPointerCancel: this.pointerUpHandler, onContextMenu: this.handleContextMenu, style: { touchAction: 'none', WebkitUserSelect: 'none' }, className: isDragging
165
244
  ? 'lf-canvas-overlay lf-dragging'
166
- : 'lf-canvas-overlay lf-drag-able' }, dnd.eventMap(), { children: _jsx("g", { transform: transform, children: children }) })));
245
+ : 'lf-canvas-overlay lf-drag-able', children: _jsx("g", { transform: transform, children: children }) }));
167
246
  };
168
247
  CanvasOverlay = __decorate([
169
248
  observer
@@ -14,7 +14,7 @@ export declare class BaseText<P extends IBaseTextProps, S extends IBaseTextState
14
14
  stepperDrag: StepDrag;
15
15
  constructor(props: P);
16
16
  getShape(): h.JSX.Element | null;
17
- mouseDownHandler: (e: MouseEvent) => void;
17
+ mouseDownHandler: (e: PointerEvent) => void;
18
18
  onDragging: ({ deltaX, deltaY }: IDragParams) => void;
19
19
  dbClickHandler: () => void;
20
20
  render(): h.JSX.Element | undefined;
@@ -119,7 +119,7 @@ var BaseText = /** @class */ (function (_super) {
119
119
  BaseText.prototype.render = function () {
120
120
  var text = this.props.model.text;
121
121
  if (text) {
122
- return (_jsx("g", { onMouseDown: this.mouseDownHandler, onDblClick: this.dbClickHandler, children: this.getShape() }));
122
+ return (_jsx("g", { onPointerDown: this.mouseDownHandler, onDblClick: this.dbClickHandler, children: this.getShape() }));
123
123
  }
124
124
  };
125
125
  return BaseText;
@@ -7,7 +7,7 @@ import Tool from './tool';
7
7
  import History from './history';
8
8
  import Keyboard from './keyboard';
9
9
  import { EventCallback, CallbackArgs, EventArgs } from './event/eventEmitter';
10
- import { EventType, SegmentDirection } from './constant';
10
+ import { EventType, OverlapMode, SegmentDirection } from './constant';
11
11
  import { Grid } from './view/overlay';
12
12
  import Extension = LogicFlow.Extension;
13
13
  import ExtensionConfig = LogicFlow.ExtensionConfig;
@@ -430,6 +430,7 @@ export declare class LogicFlow {
430
430
  * 清空画布
431
431
  */
432
432
  clearData(): void;
433
+ setOverlapMode(mode: OverlapMode): void;
433
434
  /*********************************************************
434
435
  * LogicFlow Render方法
435
436
  ********************************************************/
package/lib/LogicFlow.js CHANGED
@@ -962,6 +962,9 @@ var LogicFlow = /** @class */ (function () {
962
962
  // 强制刷新数据, 让 preact 清除对已删除节点的引用
963
963
  this.render({});
964
964
  };
965
+ LogicFlow.prototype.setOverlapMode = function (mode) {
966
+ this.graphModel.setOverlapMode(mode);
967
+ };
965
968
  /*********************************************************
966
969
  * LogicFlow Render方法
967
970
  ********************************************************/
@@ -134,8 +134,10 @@ export declare enum EventType {
134
134
  EDIT_CONFIG_CHANGED = "editConfig:changed"
135
135
  }
136
136
  export declare enum OverlapMode {
137
+ STATIC = -1,// 静态(元素层级不随点击变化)
137
138
  DEFAULT = 0,// 默认
138
- INCREASE = 1
139
+ INCREASE = 1,// 递增
140
+ EDGE_TOP = 2
139
141
  }
140
142
  export declare enum SegmentDirection {
141
143
  HORIZONTAL = "horizontal",
@@ -152,8 +152,10 @@ var EventType;
152
152
  })(EventType || (exports.EventType = EventType = {}));
153
153
  var OverlapMode;
154
154
  (function (OverlapMode) {
155
+ OverlapMode[OverlapMode["STATIC"] = -1] = "STATIC";
155
156
  OverlapMode[OverlapMode["DEFAULT"] = 0] = "DEFAULT";
156
157
  OverlapMode[OverlapMode["INCREASE"] = 1] = "INCREASE";
158
+ OverlapMode[OverlapMode["EDGE_TOP"] = 2] = "EDGE_TOP";
157
159
  })(OverlapMode || (exports.OverlapMode = OverlapMode = {}));
158
160
  var SegmentDirection;
159
161
  (function (SegmentDirection) {
@@ -114,6 +114,7 @@ export interface IEditConfigType {
114
114
  nodeTextMode: TextMode;
115
115
  edgeTextMode: TextMode;
116
116
  snapGrid: boolean;
117
+ isPinching: boolean;
117
118
  }
118
119
  export type IConfigKeys = keyof IEditConfigType;
119
120
  /**
@@ -129,6 +130,7 @@ export declare class EditConfigModel {
129
130
  stopMoveGraph: boolean;
130
131
  stopScrollGraph: boolean;
131
132
  snapGrid: boolean;
133
+ isPinching: boolean;
132
134
  /*********************************************************
133
135
  * 文本相关配置(全局)
134
136
  ********************************************************/
@@ -170,7 +172,7 @@ export declare class EditConfigModel {
170
172
  multipleSelectKey: string;
171
173
  constructor(config: Partial<IEditConfigType>);
172
174
  updateEditConfig(config: Partial<IEditConfigType>): void;
173
- computeConfig(config: Partial<IEditConfigType>): Partial<IEditConfigType> & Pick<Partial<IEditConfigType>, "textMode" | "adjustEdgeStartAndEnd" | "edgeTextDraggable" | "edgeTextEdit" | "nodeTextDraggable" | "nodeTextEdit" | "adjustEdge" | "edgeTextMode" | "nodeTextMode" | "allowRotate" | "allowResize" | "isSilentMode" | "stopScrollGraph" | "stopZoomGraph" | "stopMoveGraph" | "textEdit" | "snapGrid" | "adjustNodePosition" | "hoverOutline" | "nodeSelectedOutline" | "edgeSelectedOutline" | "adjustEdgeMiddle" | "adjustEdgeStart" | "adjustEdgeEnd" | "hideAnchors" | "autoExpand" | "textDraggable" | "multipleSelectKey" | "nodeTextMultiple" | "edgeTextMultiple" | "nodeTextVertical" | "edgeTextVertical">;
175
+ computeConfig(config: Partial<IEditConfigType>): Partial<IEditConfigType> & Pick<Partial<IEditConfigType>, "textMode" | "adjustEdgeStartAndEnd" | "edgeTextDraggable" | "edgeTextEdit" | "nodeTextDraggable" | "nodeTextEdit" | "adjustEdge" | "edgeTextMode" | "nodeTextMode" | "allowRotate" | "allowResize" | "isSilentMode" | "stopScrollGraph" | "stopZoomGraph" | "stopMoveGraph" | "textEdit" | "snapGrid" | "adjustEdgeMiddle" | "adjustEdgeStart" | "adjustEdgeEnd" | "adjustNodePosition" | "hideAnchors" | "autoExpand" | "hoverOutline" | "nodeSelectedOutline" | "edgeSelectedOutline" | "textDraggable" | "multipleSelectKey" | "nodeTextMultiple" | "edgeTextMultiple" | "nodeTextVertical" | "edgeTextVertical" | "isPinching">;
174
176
  updateTextMode(textMode: TextMode): void;
175
177
  getConfig(): IEditConfigType;
176
178
  }
@@ -65,6 +65,7 @@ var allKeys = [
65
65
  'edgeTextMultiple', // 是否支持多个边文本
66
66
  'nodeTextVertical', // 节点文本是否纵向显示
67
67
  'edgeTextVertical', // 边文本是否纵向显示
68
+ 'isPinching', //是否是双指捏合态
68
69
  ];
69
70
  /**
70
71
  * 页面编辑配置
@@ -79,6 +80,7 @@ var EditConfigModel = /** @class */ (function () {
79
80
  this.stopMoveGraph = false;
80
81
  this.stopScrollGraph = false;
81
82
  this.snapGrid = false;
83
+ this.isPinching = false;
82
84
  /*********************************************************
83
85
  * 文本相关配置(全局)
84
86
  ********************************************************/
@@ -196,6 +198,9 @@ var EditConfigModel = /** @class */ (function () {
196
198
  __decorate([
197
199
  mobx_1.observable
198
200
  ], EditConfigModel.prototype, "snapGrid", void 0);
201
+ __decorate([
202
+ mobx_1.observable
203
+ ], EditConfigModel.prototype, "isPinching", void 0);
199
204
  __decorate([
200
205
  mobx_1.observable
201
206
  ], EditConfigModel.prototype, "textMode", void 0);
@@ -179,6 +179,14 @@ export declare class GraphModel {
179
179
  * @param model
180
180
  */
181
181
  getTextModel(model: BaseNodeModel): TextMode | undefined;
182
+ /**
183
+ * 内部保留方法,请勿直接使用
184
+ */
185
+ /**
186
+ * 设置重叠模式
187
+ * @param mode 重叠模式
188
+ */
189
+ setOverlapMode(mode: OverlapMode): void;
182
190
  /**
183
191
  * 更新元素的文本模式
184
192
  * @param mode
@@ -449,7 +457,7 @@ export declare class GraphModel {
449
457
  */
450
458
  clearData(): void;
451
459
  /**
452
- * 获取图形区域虚拟矩型的尺寸和中心坐标
460
+ * 获取图形区域虚拟矩形的尺寸和中心坐标
453
461
  * @returns
454
462
  */
455
463
  getVirtualRectSize(): GraphModel.VirtualRectProps;