@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.
Files changed (74) hide show
  1. package/.turbo/turbo-build$colon$dev.log +2 -2
  2. package/.turbo/turbo-build.log +6 -6
  3. package/CHANGELOG.md +6 -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 +3 -1
  7. package/es/model/EditConfigModel.js +5 -0
  8. package/es/model/GraphModel.js +1 -0
  9. package/es/tool/MultipleSelectTool.d.ts +1 -1
  10. package/es/tool/MultipleSelectTool.js +1 -1
  11. package/es/util/drag.d.ts +4 -4
  12. package/es/util/drag.js +12 -6
  13. package/es/view/Anchor.d.ts +3 -3
  14. package/es/view/Anchor.js +30 -4
  15. package/es/view/Control.js +1 -1
  16. package/es/view/Rotate.js +1 -1
  17. package/es/view/behavior/dnd.d.ts +4 -8
  18. package/es/view/behavior/dnd.js +50 -14
  19. package/es/view/edge/AdjustPoint.d.ts +1 -1
  20. package/es/view/edge/AdjustPoint.js +1 -1
  21. package/es/view/edge/BaseEdge.d.ts +2 -1
  22. package/es/view/edge/BaseEdge.js +18 -1
  23. package/es/view/edge/PolylineEdge.d.ts +1 -1
  24. package/es/view/edge/PolylineEdge.js +1 -1
  25. package/es/view/node/BaseNode.d.ts +2 -1
  26. package/es/view/node/BaseNode.js +17 -1
  27. package/es/view/overlay/BezierAdjustOverlay.js +1 -1
  28. package/es/view/overlay/CanvasOverlay.d.ts +12 -1
  29. package/es/view/overlay/CanvasOverlay.js +94 -15
  30. package/es/view/text/BaseText.d.ts +1 -1
  31. package/es/view/text/BaseText.js +1 -1
  32. package/lib/model/EditConfigModel.d.ts +3 -1
  33. package/lib/model/EditConfigModel.js +5 -0
  34. package/lib/model/GraphModel.js +1 -0
  35. package/lib/tool/MultipleSelectTool.d.ts +1 -1
  36. package/lib/tool/MultipleSelectTool.js +1 -1
  37. package/lib/util/drag.d.ts +4 -4
  38. package/lib/util/drag.js +12 -6
  39. package/lib/view/Anchor.d.ts +3 -3
  40. package/lib/view/Anchor.js +30 -4
  41. package/lib/view/Control.js +1 -1
  42. package/lib/view/Rotate.js +1 -1
  43. package/lib/view/behavior/dnd.d.ts +4 -8
  44. package/lib/view/behavior/dnd.js +50 -14
  45. package/lib/view/edge/AdjustPoint.d.ts +1 -1
  46. package/lib/view/edge/AdjustPoint.js +1 -1
  47. package/lib/view/edge/BaseEdge.d.ts +2 -1
  48. package/lib/view/edge/BaseEdge.js +18 -1
  49. package/lib/view/edge/PolylineEdge.d.ts +1 -1
  50. package/lib/view/edge/PolylineEdge.js +1 -1
  51. package/lib/view/node/BaseNode.d.ts +2 -1
  52. package/lib/view/node/BaseNode.js +17 -1
  53. package/lib/view/overlay/BezierAdjustOverlay.js +1 -1
  54. package/lib/view/overlay/CanvasOverlay.d.ts +12 -1
  55. package/lib/view/overlay/CanvasOverlay.js +94 -15
  56. package/lib/view/text/BaseText.d.ts +1 -1
  57. package/lib/view/text/BaseText.js +1 -1
  58. package/package.json +1 -1
  59. package/src/model/EditConfigModel.ts +3 -0
  60. package/src/model/GraphModel.ts +1 -0
  61. package/src/tool/MultipleSelectTool.tsx +2 -2
  62. package/src/util/drag.ts +16 -12
  63. package/src/view/Anchor.tsx +32 -6
  64. package/src/view/Control.tsx +1 -1
  65. package/src/view/Rotate.tsx +1 -1
  66. package/src/view/behavior/dnd.ts +55 -16
  67. package/src/view/edge/AdjustPoint.tsx +2 -2
  68. package/src/view/edge/BaseEdge.tsx +23 -3
  69. package/src/view/edge/PolylineEdge.tsx +2 -2
  70. package/src/view/node/BaseNode.tsx +21 -5
  71. package/src/view/overlay/BezierAdjustOverlay.tsx +1 -1
  72. package/src/view/overlay/CanvasOverlay.tsx +110 -4
  73. package/src/view/text/BaseText.tsx +5 -2
  74. package/stats.html +1 -1
@@ -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;
@@ -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);
@@ -1102,6 +1102,7 @@ var GraphModel = /** @class */ (function () {
1102
1102
  var _a;
1103
1103
  this.selectElements.forEach(function (element) {
1104
1104
  element === null || element === void 0 ? void 0 : element.setSelected(false);
1105
+ element === null || element === void 0 ? void 0 : element.setHovered(false);
1105
1106
  });
1106
1107
  this.selectElements.clear();
1107
1108
  /**
@@ -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;
@@ -149,7 +149,7 @@ var MultipleSelect = /** @class */ (function (_super) {
149
149
  height: "".concat(y1 - y + 20 * SCALE_Y, "px"),
150
150
  'border-width': "".concat(2 * SCALE_X, "px"),
151
151
  };
152
- return ((0, jsx_runtime_1.jsx)("div", { className: "lf-multiple-select", style: style, onMouseDown: this.handleMouseDown, onContextMenu: this.handleContextMenu, onWheel: this.handleWheelEvent }));
152
+ return ((0, jsx_runtime_1.jsx)("div", { className: "lf-multiple-select", style: style, onPointerDown: this.handleMouseDown, onContextMenu: this.handleContextMenu, onWheel: this.handleWheelEvent }));
153
153
  };
154
154
  MultipleSelect.toolName = 'multiple-select-tool';
155
155
  MultipleSelect = __decorate([
@@ -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/lib/util/drag.js CHANGED
@@ -26,11 +26,12 @@ var StepDrag = /** @class */ (function () {
26
26
  return;
27
27
  if (_this.isStopPropagation)
28
28
  e.stopPropagation();
29
+ e.preventDefault();
29
30
  _this.isStartDragging = true;
30
31
  _this.startX = e.clientX;
31
32
  _this.startY = e.clientY;
32
- DOC.addEventListener('mousemove', _this.handleMouseMove, false);
33
- DOC.addEventListener('mouseup', _this.handleMouseUp, false);
33
+ DOC.addEventListener('pointermove', _this.handleMouseMove, false);
34
+ DOC.addEventListener('pointerup', _this.handleMouseUp, false);
34
35
  var elementData = (_a = _this.model) === null || _a === void 0 ? void 0 : _a.getData();
35
36
  (_b = _this.eventCenter) === null || _b === void 0 ? void 0 : _b.emit(constant_1.EventType["".concat(_this.eventType, "_MOUSEDOWN")], {
36
37
  e: e,
@@ -42,6 +43,7 @@ var StepDrag = /** @class */ (function () {
42
43
  var _a, _b;
43
44
  if (_this.isStopPropagation)
44
45
  e.stopPropagation();
46
+ e.preventDefault();
45
47
  if (!_this.isStartDragging)
46
48
  return;
47
49
  _this.sumDeltaX += e.clientX - _this.startX;
@@ -97,11 +99,15 @@ var StepDrag = /** @class */ (function () {
97
99
  _this.isStartDragging = false;
98
100
  if (_this.isStopPropagation)
99
101
  e.stopPropagation();
102
+ var target = e.target;
103
+ if (target && typeof target.releasePointerCapture === 'function') {
104
+ target.releasePointerCapture(e.pointerId);
105
+ }
100
106
  // fix #568: 如果onDragging在下一个事件循环中触发,而drop在当前事件循环,会出现问题。
101
107
  Promise.resolve().then(function () {
102
108
  var _a, _b, _c;
103
- DOC.removeEventListener('mousemove', _this.handleMouseMove, false);
104
- DOC.removeEventListener('mouseup', _this.handleMouseUp, false);
109
+ DOC.removeEventListener('pointermove', _this.handleMouseMove, false);
110
+ DOC.removeEventListener('pointerup', _this.handleMouseUp, false);
105
111
  var elementData = (_a = _this.model) === null || _a === void 0 ? void 0 : _a.getData();
106
112
  (_b = _this.eventCenter) === null || _b === void 0 ? void 0 : _b.emit(constant_1.EventType["".concat(_this.eventType, "_MOUSEUP")], {
107
113
  e: e,
@@ -119,8 +125,8 @@ var StepDrag = /** @class */ (function () {
119
125
  };
120
126
  this.cancelDrag = function () {
121
127
  var DOC = window === null || window === void 0 ? void 0 : window.document;
122
- DOC.removeEventListener('mousemove', _this.handleMouseMove, false);
123
- DOC.removeEventListener('mouseup', _this.handleMouseUp, false);
128
+ DOC.removeEventListener('pointermove', _this.handleMouseMove, false);
129
+ DOC.removeEventListener('pointerup', _this.handleMouseUp, false);
124
130
  _this.onDragEnd({ event: undefined });
125
131
  _this.isDragging = false;
126
132
  };
@@ -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,8 @@ 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
43
  isShowLine(): boolean;
44
44
  render(): import("preact/compat").JSX.Element;
45
45
  }
@@ -105,7 +105,7 @@ var Anchor = /** @class */ (function (_super) {
105
105
  endY: y1,
106
106
  dragging: true,
107
107
  });
108
- _this.moveAnchorEnd(x1, y1);
108
+ _this.moveAnchorEnd(x1, y1, event);
109
109
  if (nearBoundary.length > 0 && !stopMoveGraph && autoExpand) {
110
110
  _this.t = (0, util_1.createRaf)(function () {
111
111
  var _a = __read(nearBoundary, 2), translateX = _a[0], translateY = _a[1];
@@ -115,7 +115,7 @@ var Anchor = /** @class */ (function (_super) {
115
115
  endX: endX - translateX,
116
116
  endY: endY - translateY,
117
117
  });
118
- _this.moveAnchorEnd(endX - translateX, endY - translateY);
118
+ _this.moveAnchorEnd(endX - translateX, endY - translateY, event);
119
119
  });
120
120
  }
121
121
  eventCenter.emit(constant_1.EventType.ANCHOR_DRAG, {
@@ -141,6 +141,11 @@ var Anchor = /** @class */ (function (_super) {
141
141
  _this.sourceRuleResults.clear();
142
142
  _this.targetRuleResults.clear();
143
143
  var _b = _this.props, graphModel = _b.graphModel, nodeModel = _b.nodeModel, anchorData = _b.anchorData;
144
+ // 拖拽结束清理:取消悬浮态
145
+ if (_this.preTargetNode) {
146
+ _this.preTargetNode.setHovered(false);
147
+ _this.preTargetNode = undefined;
148
+ }
144
149
  graphModel.eventCenter.emit(constant_1.EventType.ANCHOR_DRAGEND, {
145
150
  data: anchorData,
146
151
  e: event,
@@ -244,7 +249,7 @@ var Anchor = /** @class */ (function (_super) {
244
249
  enumerable: false,
245
250
  configurable: true
246
251
  });
247
- Anchor.prototype.moveAnchorEnd = function (endX, endY) {
252
+ Anchor.prototype.moveAnchorEnd = function (endX, endY, event) {
248
253
  var _a, _b;
249
254
  var _c = this.props, graphModel = _c.graphModel, nodeModel = _c.nodeModel, anchorData = _c.anchorData;
250
255
  var info = (0, util_1.targetNodeInfo)({
@@ -281,11 +286,32 @@ var Anchor = /** @class */ (function (_super) {
281
286
  else {
282
287
  targetNode.setElementState(constant_1.ElementState.NOT_ALLOW_CONNECT);
283
288
  }
289
+ // 人工触发进入目标节点事件,同步设置 hovered 以驱动锚点显隐和样式
290
+ if (!targetNode.isHovered) {
291
+ var nodeData = targetNode.getData();
292
+ if (event) {
293
+ graphModel.eventCenter.emit(constant_1.EventType.NODE_MOUSEENTER, {
294
+ data: nodeData,
295
+ e: event,
296
+ });
297
+ }
298
+ targetNode.setHovered(true);
299
+ }
284
300
  }
285
301
  else if (this.preTargetNode &&
286
302
  this.preTargetNode.state !== constant_1.ElementState.DEFAULT) {
287
303
  // 为了保证鼠标离开的时候,将上一个节点状态重置为正常状态。
288
304
  this.preTargetNode.setElementState(constant_1.ElementState.DEFAULT);
305
+ // 未命中任何节点:人工派发离开事件并取消悬浮,避免状态残留
306
+ var prevData = this.preTargetNode.getData();
307
+ if (event) {
308
+ graphModel.eventCenter.emit(constant_1.EventType.NODE_MOUSELEAVE, {
309
+ data: prevData,
310
+ e: event,
311
+ });
312
+ }
313
+ this.preTargetNode.setHovered(false);
314
+ this.preTargetNode = undefined;
289
315
  }
290
316
  };
291
317
  Anchor.prototype.isShowLine = function () {
@@ -307,7 +333,7 @@ var Anchor = /** @class */ (function (_super) {
307
333
  e: ev,
308
334
  nodeModel: nodeModel,
309
335
  });
310
- }, onMouseDown: function (ev) {
336
+ }, onPointerDown: function (ev) {
311
337
  graphModel.eventCenter.emit(constant_1.EventType.ANCHOR_MOUSEDOWN, {
312
338
  data: anchorData,
313
339
  e: ev,
@@ -349,7 +349,7 @@ var ResizeControl = /** @class */ (function (_super) {
349
349
  ResizeControl.prototype.render = function () {
350
350
  var _a = this.props, x = _a.x, y = _a.y, direction = _a.direction, model = _a.model;
351
351
  var _b = model.getResizeControlStyle(), width = _b.width, height = _b.height, restStyle = __rest(_b, ["width", "height"]);
352
- return ((0, jsx_runtime_1.jsxs)("g", { className: "lf-resize-control lf-resize-control-".concat(direction), children: [(0, jsx_runtime_1.jsx)(shape_1.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)), (0, jsx_runtime_1.jsx)(shape_1.Rect, { className: "lf-resize-control-content", x: x, y: y, width: 25, height: 25, fill: "transparent", stroke: "transparent", onMouseDown: this.dragHandler.handleMouseDown })] }));
352
+ return ((0, jsx_runtime_1.jsxs)("g", { className: "lf-resize-control lf-resize-control-".concat(direction), children: [(0, jsx_runtime_1.jsx)(shape_1.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)), (0, jsx_runtime_1.jsx)(shape_1.Rect, { className: "lf-resize-control-content", x: x, y: y, width: 25, height: 25, fill: "transparent", stroke: "transparent", onPointerDown: this.dragHandler.handleMouseDown })] }));
353
353
  };
354
354
  return ResizeControl;
355
355
  }(compat_1.Component));
@@ -104,7 +104,7 @@ var RotateControlPoint = /** @class */ (function (_super) {
104
104
  this.normal = new util_1.Vector(1, 0);
105
105
  this.defaultAngle = this.normal.angle(new util_1.Vector(cx - x, cy - y));
106
106
  nodeModel.defaultAngle = this.defaultAngle;
107
- return ((0, jsx_runtime_1.jsx)("g", { className: "lf-rotate-control", children: (0, jsx_runtime_1.jsx)("g", { onMouseDown: function (ev) {
107
+ return ((0, jsx_runtime_1.jsx)("g", { className: "lf-rotate-control", children: (0, jsx_runtime_1.jsx)("g", { onPointerDown: function (ev) {
108
108
  _this.stepperDrag.handleMouseDown(ev);
109
109
  }, children: (0, jsx_runtime_1.jsx)(Circle_1.default, __assign({}, this.style, { cx: cx, cy: cy })) }) }));
110
110
  };
@@ -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;
@@ -22,7 +22,12 @@ var Dnd = /** @class */ (function () {
22
22
  this.fakeNode = null;
23
23
  this.stopDrag = function () {
24
24
  _this.nodeConfig = null;
25
- window.document.removeEventListener('mouseup', _this.stopDrag);
25
+ if (_this.docPointerMove) {
26
+ window.document.removeEventListener('pointermove', _this.docPointerMove);
27
+ }
28
+ if (_this.docPointerUp) {
29
+ window.document.removeEventListener('pointerup', _this.docPointerUp);
30
+ }
26
31
  };
27
32
  this.dragEnter = function (e) {
28
33
  if (!_this.nodeConfig || _this.fakeNode)
@@ -94,22 +99,53 @@ var Dnd = /** @class */ (function () {
94
99
  y: (0, util_1.snapToGrid)(y1, gridSize, snapGrid),
95
100
  };
96
101
  };
102
+ Dnd.prototype.isInsideCanvas = function (e) {
103
+ var overlay = this.lf.graphModel.rootEl.querySelector('[name="canvas-overlay"]');
104
+ var topEl = window.document.elementFromPoint(e.clientX, e.clientY);
105
+ return (topEl === overlay ||
106
+ (topEl !== null && !!overlay && overlay.contains(topEl)));
107
+ };
97
108
  Dnd.prototype.startDrag = function (nodeConfig) {
109
+ var _this = this;
98
110
  var editConfigModel = this.lf.graphModel.editConfigModel;
99
- if (!(editConfigModel === null || editConfigModel === void 0 ? void 0 : editConfigModel.isSilentMode)) {
100
- this.nodeConfig = nodeConfig;
101
- window.document.addEventListener('mouseup', this.stopDrag);
102
- }
103
- };
104
- Dnd.prototype.eventMap = function () {
105
- return {
106
- onMouseEnter: this.dragEnter,
107
- onMouseOver: this.dragEnter, // IE11
108
- onMouseMove: this.onDragOver,
109
- onMouseLeave: this.onDragLeave,
110
- // onMouseOut: this.onDragLeave, // IE11
111
- onMouseUp: this.onDrop,
111
+ if (editConfigModel === null || editConfigModel === void 0 ? void 0 : editConfigModel.isSilentMode)
112
+ return;
113
+ this.nodeConfig = nodeConfig;
114
+ // 指针移动:根据命中结果判断是否在画布覆盖层上,驱动假节点创建/移动或清理
115
+ this.docPointerMove = function (e) {
116
+ if (!_this.nodeConfig)
117
+ return;
118
+ // 离开画布:清理吸附线与假节点
119
+ if (!_this.isInsideCanvas(e)) {
120
+ _this.onDragLeave();
121
+ return;
122
+ }
123
+ // 首次进入画布:创建假节点并初始化位置
124
+ if (!_this.fakeNode) {
125
+ _this.dragEnter(e);
126
+ return;
127
+ }
128
+ // 在画布内移动:更新假节点位置与吸附线
129
+ _this.onDragOver(e);
130
+ };
131
+ // 指针抬起:在画布内落点生成节点,否则清理假节点
132
+ this.docPointerUp = function (e) {
133
+ if (!_this.nodeConfig)
134
+ return;
135
+ if (_this.isInsideCanvas(e)) {
136
+ _this.onDrop(e);
137
+ }
138
+ else {
139
+ _this.onDragLeave();
140
+ }
141
+ // 阻止默认行为与冒泡,避免滚动/点击穿透
142
+ e.preventDefault();
143
+ e.stopPropagation();
144
+ // 结束拖拽并移除监听
145
+ _this.stopDrag();
112
146
  };
147
+ window.document.addEventListener('pointermove', this.docPointerMove);
148
+ window.document.addEventListener('pointerup', this.docPointerUp);
113
149
  };
114
150
  return Dnd;
115
151
  }());
@@ -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;
@@ -351,7 +351,7 @@ var AdjustPoint = /** @class */ (function (_super) {
351
351
  AdjustPoint.prototype.render = function () {
352
352
  var _a = this.props, x = _a.x, y = _a.y, getAdjustPointShape = _a.getAdjustPointShape, edgeModel = _a.edgeModel;
353
353
  var dragging = this.state.dragging;
354
- return ((0, jsx_runtime_1.jsx)("g", { pointerEvents: dragging ? 'none' : '', onMouseDown: this.handleMouseDown, children: !dragging ? getAdjustPointShape(x, y, edgeModel) : '' }));
354
+ return ((0, jsx_runtime_1.jsx)("g", { pointerEvents: dragging ? 'none' : '', onPointerDown: this.handleMouseDown, children: !dragging ? getAdjustPointShape(x, y, edgeModel) : '' }));
355
355
  };
356
356
  return AdjustPoint;
357
357
  }(compat_1.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
  * 不支持重写
@@ -152,10 +152,24 @@ var BaseEdge = /** @class */ (function (_super) {
152
152
  _this.handleMouseDown = function (e) {
153
153
  e.stopPropagation();
154
154
  _this.startTime = new Date().getTime();
155
+ if (_this.longPressTimer) {
156
+ clearTimeout(_this.longPressTimer);
157
+ }
158
+ if (e.pointerType === 'touch') {
159
+ _this.longPressTimer = window.setTimeout(function () {
160
+ if (!_this.props.model.isDragging) {
161
+ _this.handleContextMenu(e);
162
+ }
163
+ }, 500);
164
+ }
155
165
  };
156
166
  _this.handleMouseUp = function () {
157
167
  var model = _this.props.model;
158
168
  _this.mouseUpDrag = model.isDragging;
169
+ if (_this.longPressTimer) {
170
+ clearTimeout(_this.longPressTimer);
171
+ _this.longPressTimer = undefined;
172
+ }
159
173
  };
160
174
  /**
161
175
  * 不支持重写
@@ -478,7 +492,10 @@ var BaseEdge = /** @class */ (function (_super) {
478
492
  isSelected && 'lf-edge-selected',
479
493
  ]
480
494
  .filter(Boolean)
481
- .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() : ''] }));
495
+ .join(' '), style: {
496
+ touchAction: 'none',
497
+ WebkitTouchCallout: 'none',
498
+ }, 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() : ''] }));
482
499
  };
483
500
  BaseEdge.isObserved = false;
484
501
  return BaseEdge;