@logicflow/core 2.1.4 → 2.2.0-alpha.1

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 (82) hide show
  1. package/.turbo/turbo-build$colon$dev.log +57 -2
  2. package/.turbo/turbo-build.log +7 -7
  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/model/EditConfigModel.d.ts +5 -1
  7. package/es/model/EditConfigModel.js +10 -0
  8. package/es/model/GraphModel.d.ts +1 -0
  9. package/es/model/GraphModel.js +3 -1
  10. package/es/model/node/BaseNodeModel.js +3 -1
  11. package/es/options.d.ts +3 -1
  12. package/es/tool/MultipleSelectTool.d.ts +1 -1
  13. package/es/tool/MultipleSelectTool.js +1 -1
  14. package/es/util/drag.d.ts +4 -4
  15. package/es/util/drag.js +11 -6
  16. package/es/view/Anchor.d.ts +4 -3
  17. package/es/view/Anchor.js +58 -23
  18. package/es/view/Control.js +1 -1
  19. package/es/view/Rotate.js +1 -1
  20. package/es/view/behavior/dnd.d.ts +4 -8
  21. package/es/view/behavior/dnd.js +50 -14
  22. package/es/view/edge/AdjustPoint.d.ts +1 -1
  23. package/es/view/edge/AdjustPoint.js +1 -1
  24. package/es/view/edge/BaseEdge.d.ts +2 -1
  25. package/es/view/edge/BaseEdge.js +18 -1
  26. package/es/view/edge/PolylineEdge.d.ts +1 -1
  27. package/es/view/edge/PolylineEdge.js +1 -1
  28. package/es/view/node/BaseNode.d.ts +2 -1
  29. package/es/view/node/BaseNode.js +17 -1
  30. package/es/view/overlay/BezierAdjustOverlay.js +1 -1
  31. package/es/view/overlay/CanvasOverlay.d.ts +12 -1
  32. package/es/view/overlay/CanvasOverlay.js +94 -15
  33. package/es/view/text/BaseText.d.ts +1 -1
  34. package/es/view/text/BaseText.js +1 -1
  35. package/lib/model/EditConfigModel.d.ts +5 -1
  36. package/lib/model/EditConfigModel.js +10 -0
  37. package/lib/model/GraphModel.d.ts +1 -0
  38. package/lib/model/GraphModel.js +3 -1
  39. package/lib/model/node/BaseNodeModel.js +3 -1
  40. package/lib/options.d.ts +3 -1
  41. package/lib/tool/MultipleSelectTool.d.ts +1 -1
  42. package/lib/tool/MultipleSelectTool.js +1 -1
  43. package/lib/util/drag.d.ts +4 -4
  44. package/lib/util/drag.js +11 -6
  45. package/lib/view/Anchor.d.ts +4 -3
  46. package/lib/view/Anchor.js +58 -23
  47. package/lib/view/Control.js +1 -1
  48. package/lib/view/Rotate.js +1 -1
  49. package/lib/view/behavior/dnd.d.ts +4 -8
  50. package/lib/view/behavior/dnd.js +50 -14
  51. package/lib/view/edge/AdjustPoint.d.ts +1 -1
  52. package/lib/view/edge/AdjustPoint.js +1 -1
  53. package/lib/view/edge/BaseEdge.d.ts +2 -1
  54. package/lib/view/edge/BaseEdge.js +18 -1
  55. package/lib/view/edge/PolylineEdge.d.ts +1 -1
  56. package/lib/view/edge/PolylineEdge.js +1 -1
  57. package/lib/view/node/BaseNode.d.ts +2 -1
  58. package/lib/view/node/BaseNode.js +17 -1
  59. package/lib/view/overlay/BezierAdjustOverlay.js +1 -1
  60. package/lib/view/overlay/CanvasOverlay.d.ts +12 -1
  61. package/lib/view/overlay/CanvasOverlay.js +94 -15
  62. package/lib/view/text/BaseText.d.ts +1 -1
  63. package/lib/view/text/BaseText.js +1 -1
  64. package/package.json +1 -1
  65. package/src/model/EditConfigModel.ts +6 -0
  66. package/src/model/GraphModel.ts +5 -0
  67. package/src/model/node/BaseNodeModel.ts +4 -1
  68. package/src/options.ts +6 -1
  69. package/src/tool/MultipleSelectTool.tsx +2 -2
  70. package/src/util/drag.ts +15 -12
  71. package/src/view/Anchor.tsx +84 -35
  72. package/src/view/Control.tsx +1 -1
  73. package/src/view/Rotate.tsx +1 -1
  74. package/src/view/behavior/dnd.ts +55 -16
  75. package/src/view/edge/AdjustPoint.tsx +2 -2
  76. package/src/view/edge/BaseEdge.tsx +23 -3
  77. package/src/view/edge/PolylineEdge.tsx +2 -2
  78. package/src/view/node/BaseNode.tsx +21 -5
  79. package/src/view/overlay/BezierAdjustOverlay.tsx +1 -1
  80. package/src/view/overlay/CanvasOverlay.tsx +110 -4
  81. package/src/view/text/BaseText.tsx +5 -2
  82. package/stats.html +1 -1
@@ -114,6 +114,8 @@ export interface IEditConfigType {
114
114
  nodeTextMode: TextMode;
115
115
  edgeTextMode: TextMode;
116
116
  snapGrid: boolean;
117
+ isPinching: boolean;
118
+ anchorProximityValidate: boolean;
117
119
  }
118
120
  export type IConfigKeys = keyof IEditConfigType;
119
121
  /**
@@ -129,6 +131,7 @@ export declare class EditConfigModel {
129
131
  stopMoveGraph: boolean;
130
132
  stopScrollGraph: boolean;
131
133
  snapGrid: boolean;
134
+ isPinching: boolean;
132
135
  /*********************************************************
133
136
  * 文本相关配置(全局)
134
137
  ********************************************************/
@@ -145,6 +148,7 @@ export declare class EditConfigModel {
145
148
  edgeTextDraggable: boolean;
146
149
  edgeTextMultiple: boolean;
147
150
  edgeTextVertical: boolean;
151
+ anchorProximityValidate: boolean;
148
152
  /*********************************************************
149
153
  * 节点相关配置
150
154
  ********************************************************/
@@ -170,7 +174,7 @@ export declare class EditConfigModel {
170
174
  multipleSelectKey: string;
171
175
  constructor(config: Partial<IEditConfigType>);
172
176
  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">;
177
+ 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" | "anchorProximityValidate">;
174
178
  updateTextMode(textMode: TextMode): void;
175
179
  getConfig(): IEditConfigType;
176
180
  }
@@ -62,6 +62,8 @@ var allKeys = [
62
62
  'edgeTextMultiple', // 是否支持多个边文本
63
63
  'nodeTextVertical', // 节点文本是否纵向显示
64
64
  'edgeTextVertical', // 边文本是否纵向显示
65
+ 'isPinching', //是否是双指捏合态
66
+ 'anchorProximityValidate', // 仅在靠近锚点时触发连接校验
65
67
  ];
66
68
  /**
67
69
  * 页面编辑配置
@@ -76,6 +78,7 @@ var EditConfigModel = /** @class */ (function () {
76
78
  this.stopMoveGraph = false;
77
79
  this.stopScrollGraph = false;
78
80
  this.snapGrid = false;
81
+ this.isPinching = false;
79
82
  /*********************************************************
80
83
  * 文本相关配置(全局)
81
84
  ********************************************************/
@@ -94,6 +97,7 @@ var EditConfigModel = /** @class */ (function () {
94
97
  this.edgeTextDraggable = false;
95
98
  this.edgeTextMultiple = false; // 是否支持多个边文本
96
99
  this.edgeTextVertical = false; // 边文本朝向是否是纵向
100
+ this.anchorProximityValidate = false; // 仅在靠近锚点时触发连接校验
97
101
  /*********************************************************
98
102
  * 节点相关配置
99
103
  ********************************************************/
@@ -193,6 +197,9 @@ var EditConfigModel = /** @class */ (function () {
193
197
  __decorate([
194
198
  observable
195
199
  ], EditConfigModel.prototype, "snapGrid", void 0);
200
+ __decorate([
201
+ observable
202
+ ], EditConfigModel.prototype, "isPinching", void 0);
196
203
  __decorate([
197
204
  observable
198
205
  ], EditConfigModel.prototype, "textMode", void 0);
@@ -232,6 +239,9 @@ var EditConfigModel = /** @class */ (function () {
232
239
  __decorate([
233
240
  observable
234
241
  ], EditConfigModel.prototype, "edgeTextVertical", void 0);
242
+ __decorate([
243
+ observable
244
+ ], EditConfigModel.prototype, "anchorProximityValidate", void 0);
235
245
  __decorate([
236
246
  observable
237
247
  ], EditConfigModel.prototype, "hideAnchors", void 0);
@@ -30,6 +30,7 @@ export declare class GraphModel {
30
30
  animation?: boolean | LFOptions.AnimationConfig;
31
31
  idGenerator?: (type?: string) => string | undefined;
32
32
  edgeGenerator: LFOptions.Definition['edgeGenerator'];
33
+ customTargetAnchor?: LFOptions.Definition['customTargetAnchor'];
33
34
  nodeModelMap: Map<string, BaseNodeModel>;
34
35
  edgeModelMap: Map<string, BaseEdgeModel>;
35
36
  elementsModelMap: Map<string, BaseNodeModel | BaseEdgeModel>;
@@ -96,7 +96,7 @@ var GraphModel = /** @class */ (function () {
96
96
  // 控制是否开启局部渲染
97
97
  this.partial = false;
98
98
  this.waitCleanEffects = [];
99
- var container = options.container, partial = options.partial, _c = options.background, background = _c === void 0 ? {} : _c, grid = options.grid, idGenerator = options.idGenerator, edgeGenerator = options.edgeGenerator, animation = options.animation, customTrajectory = options.customTrajectory;
99
+ var container = options.container, partial = options.partial, _c = options.background, background = _c === void 0 ? {} : _c, grid = options.grid, idGenerator = options.idGenerator, edgeGenerator = options.edgeGenerator, animation = options.animation, customTrajectory = options.customTrajectory, customTargetAnchor = options.customTargetAnchor;
100
100
  this.rootEl = container;
101
101
  this.partial = !!partial;
102
102
  this.background = background;
@@ -151,6 +151,7 @@ var GraphModel = /** @class */ (function () {
151
151
  this.idGenerator = idGenerator;
152
152
  this.edgeGenerator = createEdgeGenerator(this, edgeGenerator);
153
153
  this.customTrajectory = customTrajectory;
154
+ this.customTargetAnchor = customTargetAnchor;
154
155
  }
155
156
  Object.defineProperty(GraphModel.prototype, "nodesMap", {
156
157
  get: function () {
@@ -1096,6 +1097,7 @@ var GraphModel = /** @class */ (function () {
1096
1097
  var _a;
1097
1098
  this.selectElements.forEach(function (element) {
1098
1099
  element === null || element === void 0 ? void 0 : element.setSelected(false);
1100
+ element === null || element === void 0 ? void 0 : element.setHovered(false);
1099
1101
  });
1100
1102
  this.selectElements.clear();
1101
1103
  /**
@@ -549,7 +549,9 @@ var BaseNodeModel = /** @class */ (function () {
549
549
  * 手动连接边到节点时,需要连接的锚点
550
550
  */
551
551
  BaseNodeModel.prototype.getTargetAnchor = function (position) {
552
- return getClosestAnchor(position, this);
552
+ var _a;
553
+ var customTargetAnchor = this.graphModel.customTargetAnchor;
554
+ return ((_a = customTargetAnchor === null || customTargetAnchor === void 0 ? void 0 : customTargetAnchor(this, position)) !== null && _a !== void 0 ? _a : getClosestAnchor(position, this));
553
555
  };
554
556
  /**
555
557
  * 获取节点BBox
package/es/options.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { TransformModel } from './model';
1
+ import type { TransformModel, BaseNodeModel, Model } from './model';
2
2
  import { createElement as h } from 'preact/compat';
3
3
  import LogicFlow from './LogicFlow';
4
4
  import { KeyboardDef } from './keyboard';
@@ -21,6 +21,7 @@ export declare namespace Options {
21
21
  edge: boolean;
22
22
  };
23
23
  type EdgeGeneratorType = (sourceNode: LogicFlow.NodeData, targetNode: LogicFlow.NodeData, currentEdge?: Partial<LogicFlow.EdgeConfig>) => any;
24
+ type customTargetAnchorType = (nodeModel: BaseNodeModel, position: LogicFlow.Point) => Model.AnchorInfo | undefined;
24
25
  interface CustomAnchorLineProps {
25
26
  sourcePoint: LogicFlow.Point;
26
27
  targetPoint: LogicFlow.Point;
@@ -67,6 +68,7 @@ export declare namespace Options {
67
68
  disabledTools?: string[];
68
69
  idGenerator?: (type?: string) => string;
69
70
  edgeGenerator?: EdgeGeneratorType;
71
+ customTargetAnchor?: customTargetAnchorType;
70
72
  customTrajectory?: (props: CustomAnchorLineProps) => h.JSX.Element;
71
73
  themeMode?: 'radius' | 'dark' | 'colorful';
72
74
  parentTransform?: TransformModel;
@@ -5,7 +5,7 @@ export default class MultipleSelect extends Component<IToolProps> {
5
5
  static toolName: string;
6
6
  stepDrag: StepDrag;
7
7
  constructor(props: IToolProps);
8
- handleMouseDown: (ev: MouseEvent) => void;
8
+ handleMouseDown: (ev: PointerEvent) => void;
9
9
  handleWheelEvent: (ev: WheelEvent) => void;
10
10
  onDragging: ({ deltaX, deltaY }: IDragParams) => void;
11
11
  handleContextMenu: (ev: MouseEvent) => void;
@@ -147,7 +147,7 @@ var MultipleSelect = /** @class */ (function (_super) {
147
147
  height: "".concat(y1 - y + 20 * SCALE_Y, "px"),
148
148
  'border-width': "".concat(2 * SCALE_X, "px"),
149
149
  };
150
- return (_jsx("div", { className: "lf-multiple-select", style: style, onMouseDown: this.handleMouseDown, onContextMenu: this.handleContextMenu, onWheel: this.handleWheelEvent }));
150
+ return (_jsx("div", { className: "lf-multiple-select", style: style, onPointerDown: this.handleMouseDown, onContextMenu: this.handleContextMenu, onWheel: this.handleWheelEvent }));
151
151
  };
152
152
  MultipleSelect.toolName = 'multiple-select-tool';
153
153
  MultipleSelect = __decorate([
package/es/util/drag.d.ts CHANGED
@@ -3,7 +3,7 @@ import EventEmitter from '../event/eventEmitter';
3
3
  export type IDragParams = {
4
4
  deltaX: number;
5
5
  deltaY: number;
6
- event?: MouseEvent;
6
+ event?: PointerEvent;
7
7
  [key: string]: unknown;
8
8
  };
9
9
  export type ICreateDragParams = {
@@ -40,9 +40,9 @@ export declare class StepDrag {
40
40
  constructor({ onDragStart, onDragging, onDragEnd, eventType, eventCenter, step, isStopPropagation, model, data, }: IStepperDragProps);
41
41
  setStep(step: number): void;
42
42
  setModel(model: Model.BaseModel): void;
43
- handleMouseDown: (e: MouseEvent) => void;
44
- handleMouseMove: (e: MouseEvent) => void;
45
- handleMouseUp: (e: MouseEvent) => void;
43
+ handleMouseDown: (e: PointerEvent) => void;
44
+ handleMouseMove: (e: PointerEvent) => void;
45
+ handleMouseUp: (e: PointerEvent) => void;
46
46
  cancelDrag: () => void;
47
47
  destroy: () => void;
48
48
  }
package/es/util/drag.js CHANGED
@@ -26,8 +26,8 @@ var StepDrag = /** @class */ (function () {
26
26
  _this.isStartDragging = true;
27
27
  _this.startX = e.clientX;
28
28
  _this.startY = e.clientY;
29
- DOC.addEventListener('mousemove', _this.handleMouseMove, false);
30
- DOC.addEventListener('mouseup', _this.handleMouseUp, false);
29
+ DOC.addEventListener('pointermove', _this.handleMouseMove, false);
30
+ DOC.addEventListener('pointerup', _this.handleMouseUp, false);
31
31
  var elementData = (_a = _this.model) === null || _a === void 0 ? void 0 : _a.getData();
32
32
  (_b = _this.eventCenter) === null || _b === void 0 ? void 0 : _b.emit(EventType["".concat(_this.eventType, "_MOUSEDOWN")], {
33
33
  e: e,
@@ -39,6 +39,7 @@ var StepDrag = /** @class */ (function () {
39
39
  var _a, _b;
40
40
  if (_this.isStopPropagation)
41
41
  e.stopPropagation();
42
+ e.preventDefault();
42
43
  if (!_this.isStartDragging)
43
44
  return;
44
45
  _this.sumDeltaX += e.clientX - _this.startX;
@@ -94,11 +95,15 @@ var StepDrag = /** @class */ (function () {
94
95
  _this.isStartDragging = false;
95
96
  if (_this.isStopPropagation)
96
97
  e.stopPropagation();
98
+ var target = e.target;
99
+ if (target && typeof target.releasePointerCapture === 'function') {
100
+ target.releasePointerCapture(e.pointerId);
101
+ }
97
102
  // fix #568: 如果onDragging在下一个事件循环中触发,而drop在当前事件循环,会出现问题。
98
103
  Promise.resolve().then(function () {
99
104
  var _a, _b, _c;
100
- DOC.removeEventListener('mousemove', _this.handleMouseMove, false);
101
- DOC.removeEventListener('mouseup', _this.handleMouseUp, false);
105
+ DOC.removeEventListener('pointermove', _this.handleMouseMove, false);
106
+ DOC.removeEventListener('pointerup', _this.handleMouseUp, false);
102
107
  var elementData = (_a = _this.model) === null || _a === void 0 ? void 0 : _a.getData();
103
108
  (_b = _this.eventCenter) === null || _b === void 0 ? void 0 : _b.emit(EventType["".concat(_this.eventType, "_MOUSEUP")], {
104
109
  e: e,
@@ -116,8 +121,8 @@ var StepDrag = /** @class */ (function () {
116
121
  };
117
122
  this.cancelDrag = function () {
118
123
  var DOC = window === null || window === void 0 ? void 0 : window.document;
119
- DOC.removeEventListener('mousemove', _this.handleMouseMove, false);
120
- DOC.removeEventListener('mouseup', _this.handleMouseUp, false);
124
+ DOC.removeEventListener('pointermove', _this.handleMouseMove, false);
125
+ DOC.removeEventListener('pointerup', _this.handleMouseUp, false);
121
126
  _this.onDragEnd({ event: undefined });
122
127
  _this.isDragging = false;
123
128
  };
@@ -13,7 +13,7 @@ interface IProps {
13
13
  anchorIndex: number;
14
14
  graphModel: GraphModel;
15
15
  nodeModel: BaseNodeModel;
16
- setHoverOff: (e: MouseEvent) => void;
16
+ setHoverOff: (e: PointerEvent) => void;
17
17
  }
18
18
  interface IState {
19
19
  startX: number;
@@ -38,8 +38,9 @@ declare class Anchor extends Component<IProps, IState> {
38
38
  incomingEdgeList: import("../model").BaseEdgeModel<LogicFlow.PropertiesType>[];
39
39
  outgoingEdgeList: import("../model").BaseEdgeModel<LogicFlow.PropertiesType>[];
40
40
  };
41
- checkEnd: (event: MouseEvent | null | undefined) => import("../model").BaseEdgeModel<LogicFlow.PropertiesType> | null | undefined;
42
- moveAnchorEnd(endX: number, endY: number): void;
41
+ checkEnd: (event: PointerEvent | null | undefined) => import("../model").BaseEdgeModel<LogicFlow.PropertiesType> | null | undefined;
42
+ moveAnchorEnd(endX: number, endY: number, event?: PointerEvent): void;
43
+ validateAndSetState(targetNode: BaseNodeModel, anchorId: string | undefined, targetAnchor: AnchorConfig, nodeModel: BaseNodeModel, anchorData: AnchorConfig): void;
43
44
  isShowLine(): boolean;
44
45
  render(): import("preact/compat").JSX.Element;
45
46
  }
package/es/view/Anchor.js CHANGED
@@ -103,7 +103,7 @@ var Anchor = /** @class */ (function (_super) {
103
103
  endY: y1,
104
104
  dragging: true,
105
105
  });
106
- _this.moveAnchorEnd(x1, y1);
106
+ _this.moveAnchorEnd(x1, y1, event);
107
107
  if (nearBoundary.length > 0 && !stopMoveGraph && autoExpand) {
108
108
  _this.t = createRaf(function () {
109
109
  var _a = __read(nearBoundary, 2), translateX = _a[0], translateY = _a[1];
@@ -113,7 +113,7 @@ var Anchor = /** @class */ (function (_super) {
113
113
  endX: endX - translateX,
114
114
  endY: endY - translateY,
115
115
  });
116
- _this.moveAnchorEnd(endX - translateX, endY - translateY);
116
+ _this.moveAnchorEnd(endX - translateX, endY - translateY, event);
117
117
  });
118
118
  }
119
119
  eventCenter.emit(EventType.ANCHOR_DRAG, {
@@ -139,6 +139,11 @@ var Anchor = /** @class */ (function (_super) {
139
139
  _this.sourceRuleResults.clear();
140
140
  _this.targetRuleResults.clear();
141
141
  var _b = _this.props, graphModel = _b.graphModel, nodeModel = _b.nodeModel, anchorData = _b.anchorData;
142
+ // 拖拽结束清理:取消悬浮态
143
+ if (_this.preTargetNode) {
144
+ _this.preTargetNode.setHovered(false);
145
+ _this.preTargetNode = undefined;
146
+ }
142
147
  graphModel.eventCenter.emit(EventType.ANCHOR_DRAGEND, {
143
148
  data: anchorData,
144
149
  e: event,
@@ -242,9 +247,8 @@ var Anchor = /** @class */ (function (_super) {
242
247
  enumerable: false,
243
248
  configurable: true
244
249
  });
245
- Anchor.prototype.moveAnchorEnd = function (endX, endY) {
246
- var _a, _b;
247
- var _c = this.props, graphModel = _c.graphModel, nodeModel = _c.nodeModel, anchorData = _c.anchorData;
250
+ Anchor.prototype.moveAnchorEnd = function (endX, endY, event) {
251
+ var _a = this.props, graphModel = _a.graphModel, nodeModel = _a.nodeModel, anchorData = _a.anchorData;
248
252
  var info = targetNodeInfo({
249
253
  x: endX,
250
254
  y: endY,
@@ -260,30 +264,61 @@ var Anchor = /** @class */ (function (_super) {
260
264
  return;
261
265
  }
262
266
  this.preTargetNode = targetNode;
263
- // 支持节点的每个锚点单独设置是否可连接,因此规则key去nodeId + anchorId作为唯一值
264
- var targetInfoId = "".concat(nodeModel.id, "_").concat(targetNode.id, "_").concat(anchorId, "_").concat(anchorData.id);
265
- // 查看鼠标是否进入过target,若有检验结果,表示进入过, 就不重复计算了。
266
- if (!this.targetRuleResults.has(targetInfoId)) {
267
- var targetAnchor = info.anchor;
268
- var sourceRuleResult = nodeModel.isAllowConnectedAsSource(targetNode, anchorData, targetAnchor);
269
- var targetRuleResult = targetNode.isAllowConnectedAsTarget(nodeModel, anchorData, targetAnchor);
270
- this.sourceRuleResults.set(targetInfoId, formatAnchorConnectValidateData(sourceRuleResult));
271
- this.targetRuleResults.set(targetInfoId, formatAnchorConnectValidateData(targetRuleResult));
267
+ var anchorDist = distance(endX, endY, info.anchor.x, info.anchor.y);
268
+ var validateDistance = 10;
269
+ var editConfigModel = graphModel.editConfigModel;
270
+ if (!editConfigModel.anchorProximityValidate ||
271
+ anchorDist <= validateDistance) {
272
+ this.validateAndSetState(targetNode, anchorId, info.anchor, nodeModel, anchorData);
272
273
  }
273
- var isSourcePass = ((_a = this.sourceRuleResults.get(targetInfoId)) !== null && _a !== void 0 ? _a : {}).isAllPass;
274
- var isTargetPass = ((_b = this.targetRuleResults.get(targetInfoId)) !== null && _b !== void 0 ? _b : {}).isAllPass;
275
- // 实时提示出即将链接的锚点
276
- if (isSourcePass && isTargetPass) {
277
- targetNode.setElementState(ElementState.ALLOW_CONNECT);
278
- }
279
- else {
280
- targetNode.setElementState(ElementState.NOT_ALLOW_CONNECT);
274
+ // 人工触发进入目标节点事件,同步设置 hovered 以驱动锚点显隐和样式
275
+ if (!targetNode.isHovered) {
276
+ var nodeData = targetNode.getData();
277
+ if (event) {
278
+ graphModel.eventCenter.emit(EventType.NODE_MOUSEENTER, {
279
+ data: nodeData,
280
+ e: event,
281
+ });
282
+ }
283
+ targetNode.setHovered(true);
281
284
  }
282
285
  }
283
286
  else if (this.preTargetNode &&
284
287
  this.preTargetNode.state !== ElementState.DEFAULT) {
285
288
  // 为了保证鼠标离开的时候,将上一个节点状态重置为正常状态。
286
289
  this.preTargetNode.setElementState(ElementState.DEFAULT);
290
+ // 未命中任何节点:人工派发离开事件并取消悬浮,避免状态残留
291
+ var prevData = this.preTargetNode.getData();
292
+ if (event) {
293
+ graphModel.eventCenter.emit(EventType.NODE_MOUSELEAVE, {
294
+ data: prevData,
295
+ e: event,
296
+ });
297
+ }
298
+ this.preTargetNode.setHovered(false);
299
+ this.preTargetNode = undefined;
300
+ }
301
+ };
302
+ // 校验 source/target 连接规则并设置目标节点状态
303
+ Anchor.prototype.validateAndSetState = function (targetNode, anchorId, targetAnchor, nodeModel, anchorData) {
304
+ var _a, _b;
305
+ var targetInfoId = "".concat(nodeModel.id, "_").concat(targetNode.id, "_").concat(anchorId, "_").concat(anchorData.id);
306
+ if (!this.targetRuleResults.has(targetInfoId)) {
307
+ // 首次计算并缓存源/目标两侧的规则校验结果
308
+ var sourceRuleResult = nodeModel.isAllowConnectedAsSource(targetNode, anchorData, targetAnchor);
309
+ var targetRuleResult = targetNode.isAllowConnectedAsTarget(nodeModel, anchorData, targetAnchor);
310
+ this.sourceRuleResults.set(targetInfoId, formatAnchorConnectValidateData(sourceRuleResult));
311
+ this.targetRuleResults.set(targetInfoId, formatAnchorConnectValidateData(targetRuleResult));
312
+ }
313
+ // 读取缓存的校验结果
314
+ var isSourcePass = ((_a = this.sourceRuleResults.get(targetInfoId)) !== null && _a !== void 0 ? _a : {}).isAllPass;
315
+ var isTargetPass = ((_b = this.targetRuleResults.get(targetInfoId)) !== null && _b !== void 0 ? _b : {}).isAllPass;
316
+ // 两侧都通过则允许连接,否则标记为不允许连接
317
+ if (isSourcePass && isTargetPass) {
318
+ targetNode.setElementState(ElementState.ALLOW_CONNECT);
319
+ }
320
+ else {
321
+ targetNode.setElementState(ElementState.NOT_ALLOW_CONNECT);
287
322
  }
288
323
  };
289
324
  Anchor.prototype.isShowLine = function () {
@@ -305,7 +340,7 @@ var Anchor = /** @class */ (function (_super) {
305
340
  e: ev,
306
341
  nodeModel: nodeModel,
307
342
  });
308
- }, onMouseDown: function (ev) {
343
+ }, onPointerDown: function (ev) {
309
344
  graphModel.eventCenter.emit(EventType.ANCHOR_MOUSEDOWN, {
310
345
  data: anchorData,
311
346
  e: ev,
@@ -346,7 +346,7 @@ var ResizeControl = /** @class */ (function (_super) {
346
346
  ResizeControl.prototype.render = function () {
347
347
  var _a = this.props, x = _a.x, y = _a.y, direction = _a.direction, model = _a.model;
348
348
  var _b = model.getResizeControlStyle(), width = _b.width, height = _b.height, restStyle = __rest(_b, ["width", "height"]);
349
- return (_jsxs("g", { className: "lf-resize-control lf-resize-control-".concat(direction), children: [_jsx(Rect, __assign({ className: "lf-resize-control-content", x: x, y: y, width: width !== null && width !== void 0 ? width : 7, height: height !== null && height !== void 0 ? height : 7 }, restStyle)), _jsx(Rect, { className: "lf-resize-control-content", x: x, y: y, width: 25, height: 25, fill: "transparent", stroke: "transparent", onMouseDown: this.dragHandler.handleMouseDown })] }));
349
+ return (_jsxs("g", { className: "lf-resize-control lf-resize-control-".concat(direction), children: [_jsx(Rect, __assign({ className: "lf-resize-control-content", x: x, y: y, width: width !== null && width !== void 0 ? width : 7, height: height !== null && height !== void 0 ? height : 7 }, restStyle)), _jsx(Rect, { className: "lf-resize-control-content", x: x, y: y, width: 25, height: 25, fill: "transparent", stroke: "transparent", onPointerDown: this.dragHandler.handleMouseDown })] }));
350
350
  };
351
351
  return ResizeControl;
352
352
  }(Component));
package/es/view/Rotate.js CHANGED
@@ -99,7 +99,7 @@ var RotateControlPoint = /** @class */ (function (_super) {
99
99
  this.normal = new Vector(1, 0);
100
100
  this.defaultAngle = this.normal.angle(new Vector(cx - x, cy - y));
101
101
  nodeModel.defaultAngle = this.defaultAngle;
102
- return (_jsx("g", { className: "lf-rotate-control", children: _jsx("g", { onMouseDown: function (ev) {
102
+ return (_jsx("g", { className: "lf-rotate-control", children: _jsx("g", { onPointerDown: function (ev) {
103
103
  _this.stepperDrag.handleMouseDown(ev);
104
104
  }, children: _jsx(Circle, __assign({}, this.style, { cx: cx, cy: cy })) }) }));
105
105
  };
@@ -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;