@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.
- package/.turbo/turbo-build$colon$dev.log +57 -2
- package/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +15 -0
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/es/model/EditConfigModel.d.ts +5 -1
- package/es/model/EditConfigModel.js +10 -0
- package/es/model/GraphModel.d.ts +1 -0
- package/es/model/GraphModel.js +3 -1
- package/es/model/node/BaseNodeModel.js +3 -1
- package/es/options.d.ts +3 -1
- package/es/tool/MultipleSelectTool.d.ts +1 -1
- package/es/tool/MultipleSelectTool.js +1 -1
- package/es/util/drag.d.ts +4 -4
- package/es/util/drag.js +11 -6
- package/es/view/Anchor.d.ts +4 -3
- package/es/view/Anchor.js +58 -23
- package/es/view/Control.js +1 -1
- package/es/view/Rotate.js +1 -1
- package/es/view/behavior/dnd.d.ts +4 -8
- package/es/view/behavior/dnd.js +50 -14
- package/es/view/edge/AdjustPoint.d.ts +1 -1
- package/es/view/edge/AdjustPoint.js +1 -1
- package/es/view/edge/BaseEdge.d.ts +2 -1
- package/es/view/edge/BaseEdge.js +18 -1
- package/es/view/edge/PolylineEdge.d.ts +1 -1
- package/es/view/edge/PolylineEdge.js +1 -1
- package/es/view/node/BaseNode.d.ts +2 -1
- package/es/view/node/BaseNode.js +17 -1
- package/es/view/overlay/BezierAdjustOverlay.js +1 -1
- package/es/view/overlay/CanvasOverlay.d.ts +12 -1
- package/es/view/overlay/CanvasOverlay.js +94 -15
- package/es/view/text/BaseText.d.ts +1 -1
- package/es/view/text/BaseText.js +1 -1
- package/lib/model/EditConfigModel.d.ts +5 -1
- package/lib/model/EditConfigModel.js +10 -0
- package/lib/model/GraphModel.d.ts +1 -0
- package/lib/model/GraphModel.js +3 -1
- package/lib/model/node/BaseNodeModel.js +3 -1
- package/lib/options.d.ts +3 -1
- package/lib/tool/MultipleSelectTool.d.ts +1 -1
- package/lib/tool/MultipleSelectTool.js +1 -1
- package/lib/util/drag.d.ts +4 -4
- package/lib/util/drag.js +11 -6
- package/lib/view/Anchor.d.ts +4 -3
- package/lib/view/Anchor.js +58 -23
- package/lib/view/Control.js +1 -1
- package/lib/view/Rotate.js +1 -1
- package/lib/view/behavior/dnd.d.ts +4 -8
- package/lib/view/behavior/dnd.js +50 -14
- package/lib/view/edge/AdjustPoint.d.ts +1 -1
- package/lib/view/edge/AdjustPoint.js +1 -1
- package/lib/view/edge/BaseEdge.d.ts +2 -1
- package/lib/view/edge/BaseEdge.js +18 -1
- package/lib/view/edge/PolylineEdge.d.ts +1 -1
- package/lib/view/edge/PolylineEdge.js +1 -1
- package/lib/view/node/BaseNode.d.ts +2 -1
- package/lib/view/node/BaseNode.js +17 -1
- package/lib/view/overlay/BezierAdjustOverlay.js +1 -1
- package/lib/view/overlay/CanvasOverlay.d.ts +12 -1
- package/lib/view/overlay/CanvasOverlay.js +94 -15
- package/lib/view/text/BaseText.d.ts +1 -1
- package/lib/view/text/BaseText.js +1 -1
- package/package.json +1 -1
- package/src/model/EditConfigModel.ts +6 -0
- package/src/model/GraphModel.ts +5 -0
- package/src/model/node/BaseNodeModel.ts +4 -1
- package/src/options.ts +6 -1
- package/src/tool/MultipleSelectTool.tsx +2 -2
- package/src/util/drag.ts +15 -12
- package/src/view/Anchor.tsx +84 -35
- package/src/view/Control.tsx +1 -1
- package/src/view/Rotate.tsx +1 -1
- package/src/view/behavior/dnd.ts +55 -16
- package/src/view/edge/AdjustPoint.tsx +2 -2
- package/src/view/edge/BaseEdge.tsx +23 -3
- package/src/view/edge/PolylineEdge.tsx +2 -2
- package/src/view/node/BaseNode.tsx +21 -5
- package/src/view/overlay/BezierAdjustOverlay.tsx +1 -1
- package/src/view/overlay/CanvasOverlay.tsx +110 -4
- package/src/view/text/BaseText.tsx +5 -2
- package/stats.html +1 -1
package/lib/view/Control.js
CHANGED
|
@@ -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",
|
|
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));
|
package/lib/view/Rotate.js
CHANGED
|
@@ -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", {
|
|
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:
|
|
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;
|
package/lib/view/behavior/dnd.js
CHANGED
|
@@ -22,7 +22,12 @@ var Dnd = /** @class */ (function () {
|
|
|
22
22
|
this.fakeNode = null;
|
|
23
23
|
this.stopDrag = function () {
|
|
24
24
|
_this.nodeConfig = null;
|
|
25
|
-
|
|
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 (
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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:
|
|
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' : '',
|
|
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:
|
|
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(' '),
|
|
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;
|
|
@@ -34,7 +34,7 @@ export declare class PolylineEdge extends BaseEdge<IPolylineEdgeProps> {
|
|
|
34
34
|
/**
|
|
35
35
|
* 不支持重写
|
|
36
36
|
*/
|
|
37
|
-
beforeDragStart: (e:
|
|
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
|
|
@@ -263,7 +263,7 @@ var PolylineEdge = /** @class */ (function (_super) {
|
|
|
263
263
|
}
|
|
264
264
|
appendInfo.direction = constant_1.SegmentDirection.HORIZONTAL;
|
|
265
265
|
}
|
|
266
|
-
append = ((0, jsx_runtime_1.jsx)("g", { className: this_1.isDragging ? 'lf-dragging' : 'lf-drag-able',
|
|
266
|
+
append = ((0, jsx_runtime_1.jsx)("g", { className: this_1.isDragging ? 'lf-dragging' : 'lf-drag-able', onPointerDown: function (e) { return _this.beforeDragStart(e, appendInfo); }, children: (0, jsx_runtime_1.jsx)("g", { className: className, children: this_1.getAppendShape(appendInfo) }) }));
|
|
267
267
|
}
|
|
268
268
|
LineAppendList.push(append);
|
|
269
269
|
};
|
|
@@ -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:
|
|
41
|
+
handleMouseDown: (ev: PointerEvent) => void;
|
|
41
42
|
handleFocus: () => void;
|
|
42
43
|
handleBlur: () => void;
|
|
43
44
|
setHoverOn: (ev: MouseEvent) => void;
|
|
@@ -172,6 +172,10 @@ var BaseNode = /** @class */ (function (_super) {
|
|
|
172
172
|
_this.handleMouseUp = function () {
|
|
173
173
|
var model = _this.props.model;
|
|
174
174
|
_this.mouseUpDrag = model.isDragging;
|
|
175
|
+
if (_this.longPressTimer) {
|
|
176
|
+
clearTimeout(_this.longPressTimer);
|
|
177
|
+
_this.longPressTimer = undefined;
|
|
178
|
+
}
|
|
175
179
|
};
|
|
176
180
|
_this.handleClick = function (e) {
|
|
177
181
|
// 节点拖拽进画布之后,不触发click事件相关emit
|
|
@@ -272,6 +276,16 @@ var BaseNode = /** @class */ (function (_super) {
|
|
|
272
276
|
if (editConfigModel.adjustNodePosition && model.draggable) {
|
|
273
277
|
_this.stepDrag && _this.stepDrag.handleMouseDown(ev);
|
|
274
278
|
}
|
|
279
|
+
if (_this.longPressTimer) {
|
|
280
|
+
clearTimeout(_this.longPressTimer);
|
|
281
|
+
}
|
|
282
|
+
if (ev.pointerType === 'touch') {
|
|
283
|
+
_this.longPressTimer = window.setTimeout(function () {
|
|
284
|
+
if (!_this.props.model.isDragging) {
|
|
285
|
+
_this.handleContextMenu(ev);
|
|
286
|
+
}
|
|
287
|
+
}, 500);
|
|
288
|
+
}
|
|
275
289
|
};
|
|
276
290
|
_this.handleFocus = function () {
|
|
277
291
|
var _a = _this.props, model = _a.model, graphModel = _a.graphModel;
|
|
@@ -453,7 +467,9 @@ var BaseNode = /** @class */ (function (_super) {
|
|
|
453
467
|
if (adjustNodePosition && draggable) {
|
|
454
468
|
this.stepDrag.setStep(gridSize * SCALE_X);
|
|
455
469
|
}
|
|
456
|
-
nodeShape = ((0, jsx_runtime_1.jsx)("g", __assign({ className: "".concat(this.getStateClassName(), " ").concat(className),
|
|
470
|
+
nodeShape = ((0, jsx_runtime_1.jsx)("g", __assign({ className: "".concat(this.getStateClassName(), " ").concat(className), onPointerDown: this.handleMouseDown, onPointerUp: this.handleMouseUp, onClick: this.handleClick,
|
|
471
|
+
//因为移动端点击操作完成会按顺序触发enter、leave、click事件,所以会造成节点的闪烁,所以在这里没有统一状态为Pointer
|
|
472
|
+
onMouseEnter: this.setHoverOn, onMouseOver: this.setHoverOn, onMouseLeave: this.setHoverOff, onMouseOut: this.onMouseOut, onContextMenu: this.handleContextMenu, onFocus: this.handleFocus, onBlur: this.handleBlur }, restAttributes, { children: nodeShapeInner })));
|
|
457
473
|
}
|
|
458
474
|
return nodeShape;
|
|
459
475
|
};
|
|
@@ -91,7 +91,7 @@ var BezierAdjustAnchor = /** @class */ (function (_super) {
|
|
|
91
91
|
var x = position.x, y = position.y;
|
|
92
92
|
var bezierModel = this.props.bezierModel;
|
|
93
93
|
var adjustAnchor = bezierModel.getEdgeStyle().adjustAnchor;
|
|
94
|
-
return ((0, jsx_runtime_1.jsx)(shape_1.Circle, __assign({ className: "lf-bezier-adjust-anchor", x: x, y: y }, adjustAnchor, {
|
|
94
|
+
return ((0, jsx_runtime_1.jsx)(shape_1.Circle, __assign({ className: "lf-bezier-adjust-anchor", x: x, y: y }, adjustAnchor, { onPointerDown: function (ev) {
|
|
95
95
|
// if (edgeAddable !== false) {
|
|
96
96
|
_this.dragHandler.handleMouseDown(ev);
|
|
97
97
|
// }
|
|
@@ -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
|
-
|
|
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;
|
|
@@ -14,17 +14,6 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
14
14
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
15
|
};
|
|
16
16
|
})();
|
|
17
|
-
var __assign = (this && this.__assign) || function () {
|
|
18
|
-
__assign = Object.assign || function(t) {
|
|
19
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
20
|
-
s = arguments[i];
|
|
21
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
22
|
-
t[p] = s[p];
|
|
23
|
-
}
|
|
24
|
-
return t;
|
|
25
|
-
};
|
|
26
|
-
return __assign.apply(this, arguments);
|
|
27
|
-
};
|
|
28
17
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
29
18
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
30
19
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -44,11 +33,16 @@ var CanvasOverlay = /** @class */ (function (_super) {
|
|
|
44
33
|
var _this = _super.call(this) || this;
|
|
45
34
|
_this.stepScrollX = 0;
|
|
46
35
|
_this.stepScrollY = 0;
|
|
36
|
+
_this.pointers = new Map();
|
|
47
37
|
// get InjectedProps() {
|
|
48
38
|
// return this.props as InjectedProps;
|
|
49
39
|
// }
|
|
50
40
|
_this.onDragging = function (_a) {
|
|
51
41
|
var deltaX = _a.deltaX, deltaY = _a.deltaY;
|
|
42
|
+
if (_this.longPressTimer) {
|
|
43
|
+
clearTimeout(_this.longPressTimer);
|
|
44
|
+
_this.longPressTimer = undefined;
|
|
45
|
+
}
|
|
52
46
|
_this.setState({
|
|
53
47
|
isDragging: true,
|
|
54
48
|
});
|
|
@@ -126,8 +120,36 @@ var CanvasOverlay = /** @class */ (function (_super) {
|
|
|
126
120
|
}
|
|
127
121
|
};
|
|
128
122
|
// 鼠标、触摸板 按下
|
|
129
|
-
_this.
|
|
123
|
+
_this.pointerDownHandler = function (ev) {
|
|
130
124
|
var _a = _this.props.graphModel, eventCenter = _a.eventCenter, editConfigModel = _a.editConfigModel, SCALE_X = _a.transformModel.SCALE_X, gridSize = _a.gridSize;
|
|
125
|
+
_this.pointers.set(ev.pointerId, { x: ev.clientX, y: ev.clientY });
|
|
126
|
+
if (_this.longPressTimer) {
|
|
127
|
+
clearTimeout(_this.longPressTimer);
|
|
128
|
+
}
|
|
129
|
+
if (ev.pointerType === 'touch') {
|
|
130
|
+
_this.longPressTimer = window.setTimeout(function () {
|
|
131
|
+
_this.handleContextMenu(ev);
|
|
132
|
+
}, 500);
|
|
133
|
+
}
|
|
134
|
+
// 检测双指触摸,初始化捏合缩放
|
|
135
|
+
if (_this.pointers.size === 2) {
|
|
136
|
+
var _b = _this.props.graphModel, transformModel = _b.transformModel, editConfigModel_1 = _b.editConfigModel;
|
|
137
|
+
// 记录两指当前位置用于计算初始距离
|
|
138
|
+
var pts = Array.from(_this.pointers.values());
|
|
139
|
+
var dx = pts[0].x - pts[1].x;
|
|
140
|
+
var dy = pts[0].y - pts[1].y;
|
|
141
|
+
var cx = (pts[0].x + pts[1].x) / 2;
|
|
142
|
+
var cy = (pts[0].y + pts[1].y) / 2;
|
|
143
|
+
// 记录捏合起始距离与当前缩放,后续按比例计算缩放
|
|
144
|
+
_this.pinchStartDistance = Math.hypot(dx, dy);
|
|
145
|
+
_this.pinchStartScale = transformModel.SCALE_X;
|
|
146
|
+
// 双指操作下取消画布拖拽,避免与捏合缩放冲突
|
|
147
|
+
_this.stepDrag.cancelDrag();
|
|
148
|
+
_this.pinchLastCenterX = cx;
|
|
149
|
+
_this.pinchLastCenterY = cy;
|
|
150
|
+
editConfigModel_1.updateEditConfig({ isPinching: true });
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
131
153
|
var adjustEdge = editConfigModel.adjustEdge, adjustNodePosition = editConfigModel.adjustNodePosition, stopMoveGraph = editConfigModel.stopMoveGraph;
|
|
132
154
|
var target = ev.target;
|
|
133
155
|
var isFrozenElement = !adjustEdge && !adjustNodePosition;
|
|
@@ -143,6 +165,63 @@ var CanvasOverlay = /** @class */ (function (_super) {
|
|
|
143
165
|
_this.clickHandler(ev);
|
|
144
166
|
}
|
|
145
167
|
};
|
|
168
|
+
_this.pointerMoveHandler = function (ev) {
|
|
169
|
+
var _a;
|
|
170
|
+
// 记录当前指针位置(按 pointerId)
|
|
171
|
+
_this.pointers.set(ev.pointerId, { x: ev.clientX, y: ev.clientY });
|
|
172
|
+
// 当已记录初始捏合距离且存在两指时,执行捏合缩放
|
|
173
|
+
if (_this.pinchStartDistance && _this.pointers.size >= 2) {
|
|
174
|
+
var _b = _this.props, graphModel = _b.graphModel, _c = _b.graphModel, editConfigModel = _c.editConfigModel, transformModel = _c.transformModel;
|
|
175
|
+
if (editConfigModel.stopZoomGraph)
|
|
176
|
+
return;
|
|
177
|
+
// 取消触摸长按计时,避免捏合过程中误触发上下文菜单
|
|
178
|
+
if (_this.longPressTimer) {
|
|
179
|
+
clearTimeout(_this.longPressTimer);
|
|
180
|
+
}
|
|
181
|
+
// 计算两指间当前距离
|
|
182
|
+
var pts = Array.from(_this.pointers.values());
|
|
183
|
+
var dx = pts[0].x - pts[1].x;
|
|
184
|
+
var dy = pts[0].y - pts[1].y;
|
|
185
|
+
var dist = Math.hypot(dx, dy);
|
|
186
|
+
// 以初始缩放为基准,根据距离比例得到新的缩放比例
|
|
187
|
+
var scale = ((_a = _this.pinchStartScale) !== null && _a !== void 0 ? _a : transformModel.SCALE_X) *
|
|
188
|
+
(dist / _this.pinchStartDistance);
|
|
189
|
+
// 取两指中心作为缩放原点,并转换为画布坐标系
|
|
190
|
+
var cx = (pts[0].x + pts[1].x) / 2;
|
|
191
|
+
var cy = (pts[0].y + pts[1].y) / 2;
|
|
192
|
+
var pos = graphModel.getPointByClient({ x: cx, y: cy });
|
|
193
|
+
var _d = pos.canvasOverlayPosition, x = _d.x, y = _d.y;
|
|
194
|
+
transformModel.zoom(scale, [x, y]);
|
|
195
|
+
// 双指中心位移驱动画布平移,配合缩放实现捏合移动;
|
|
196
|
+
if (!editConfigModel.stopMoveGraph || editConfigModel.isPinching) {
|
|
197
|
+
var deltaX = _this.pinchLastCenterX === undefined ? 0 : cx - _this.pinchLastCenterX;
|
|
198
|
+
var deltaY = _this.pinchLastCenterY === undefined ? 0 : cy - _this.pinchLastCenterY;
|
|
199
|
+
transformModel.translate(deltaX, deltaY);
|
|
200
|
+
_this.pinchLastCenterX = cx;
|
|
201
|
+
_this.pinchLastCenterY = cy;
|
|
202
|
+
}
|
|
203
|
+
ev.preventDefault();
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
_this.pointerUpHandler = function (ev) {
|
|
207
|
+
_this.pointers.delete(ev.pointerId);
|
|
208
|
+
if (_this.longPressTimer) {
|
|
209
|
+
clearTimeout(_this.longPressTimer);
|
|
210
|
+
_this.longPressTimer = undefined;
|
|
211
|
+
}
|
|
212
|
+
// 双指松开或仅剩一指:结束捏合手势并清理临时状态
|
|
213
|
+
if (_this.pointers.size < 2) {
|
|
214
|
+
// 清空捏合距离与缩放起始值
|
|
215
|
+
_this.pinchStartDistance = undefined;
|
|
216
|
+
_this.pinchStartScale = undefined;
|
|
217
|
+
// 清空上一帧的双指中心
|
|
218
|
+
_this.pinchLastCenterX = undefined;
|
|
219
|
+
_this.pinchLastCenterY = undefined;
|
|
220
|
+
var editConfigModel = _this.props.graphModel.editConfigModel;
|
|
221
|
+
// 标记退出捏合,框选等交互可恢复
|
|
222
|
+
editConfigModel.updateEditConfig({ isPinching: false });
|
|
223
|
+
}
|
|
224
|
+
};
|
|
146
225
|
var _a = props.graphModel, gridSize = _a.gridSize, eventCenter = _a.eventCenter;
|
|
147
226
|
_this.stepDrag = new util_1.StepDrag({
|
|
148
227
|
onDragging: _this.onDragging,
|
|
@@ -162,11 +241,11 @@ var CanvasOverlay = /** @class */ (function (_super) {
|
|
|
162
241
|
CanvasOverlay.prototype.render = function () {
|
|
163
242
|
var transformModel = this.props.graphModel.transformModel;
|
|
164
243
|
var transform = transformModel.getTransformStyle().transform;
|
|
165
|
-
var
|
|
244
|
+
var children = this.props.children;
|
|
166
245
|
var isDragging = this.state.isDragging;
|
|
167
|
-
return ((0, jsx_runtime_1.jsx)("svg",
|
|
246
|
+
return ((0, jsx_runtime_1.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
|
|
168
247
|
? 'lf-canvas-overlay lf-dragging'
|
|
169
|
-
: 'lf-canvas-overlay lf-drag-able'
|
|
248
|
+
: 'lf-canvas-overlay lf-drag-able', children: (0, jsx_runtime_1.jsx)("g", { transform: transform, children: children }) }));
|
|
170
249
|
};
|
|
171
250
|
CanvasOverlay = __decorate([
|
|
172
251
|
__1.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:
|
|
17
|
+
mouseDownHandler: (e: PointerEvent) => void;
|
|
18
18
|
onDragging: ({ deltaX, deltaY }: IDragParams) => void;
|
|
19
19
|
dbClickHandler: () => void;
|
|
20
20
|
render(): h.JSX.Element | undefined;
|
|
@@ -125,7 +125,7 @@ var BaseText = /** @class */ (function (_super) {
|
|
|
125
125
|
BaseText.prototype.render = function () {
|
|
126
126
|
var text = this.props.model.text;
|
|
127
127
|
if (text) {
|
|
128
|
-
return ((0, jsx_runtime_1.jsx)("g", {
|
|
128
|
+
return ((0, jsx_runtime_1.jsx)("g", { onPointerDown: this.mouseDownHandler, onDblClick: this.dbClickHandler, children: this.getShape() }));
|
|
129
129
|
}
|
|
130
130
|
};
|
|
131
131
|
return BaseText;
|
package/package.json
CHANGED
|
@@ -125,6 +125,8 @@ export interface IEditConfigType {
|
|
|
125
125
|
edgeTextMode: TextMode
|
|
126
126
|
// 开启网格对齐
|
|
127
127
|
snapGrid: boolean
|
|
128
|
+
isPinching: boolean
|
|
129
|
+
anchorProximityValidate: boolean
|
|
128
130
|
}
|
|
129
131
|
|
|
130
132
|
export type IConfigKeys = keyof IEditConfigType
|
|
@@ -186,6 +188,8 @@ const allKeys = [
|
|
|
186
188
|
'edgeTextMultiple', // 是否支持多个边文本
|
|
187
189
|
'nodeTextVertical', // 节点文本是否纵向显示
|
|
188
190
|
'edgeTextVertical', // 边文本是否纵向显示
|
|
191
|
+
'isPinching', //是否是双指捏合态
|
|
192
|
+
'anchorProximityValidate', // 仅在靠近锚点时触发连接校验
|
|
189
193
|
] as const
|
|
190
194
|
|
|
191
195
|
/**
|
|
@@ -202,6 +206,7 @@ export class EditConfigModel {
|
|
|
202
206
|
@observable stopMoveGraph = false
|
|
203
207
|
@observable stopScrollGraph = false
|
|
204
208
|
@observable snapGrid = false
|
|
209
|
+
@observable isPinching = false
|
|
205
210
|
/*********************************************************
|
|
206
211
|
* 文本相关配置(全局)
|
|
207
212
|
********************************************************/
|
|
@@ -220,6 +225,7 @@ export class EditConfigModel {
|
|
|
220
225
|
@observable edgeTextDraggable = false
|
|
221
226
|
@observable edgeTextMultiple = false // 是否支持多个边文本
|
|
222
227
|
@observable edgeTextVertical = false // 边文本朝向是否是纵向
|
|
228
|
+
@observable anchorProximityValidate = false // 仅在靠近锚点时触发连接校验
|
|
223
229
|
/*********************************************************
|
|
224
230
|
* 节点相关配置
|
|
225
231
|
********************************************************/
|
package/src/model/GraphModel.ts
CHANGED
|
@@ -89,6 +89,8 @@ export class GraphModel {
|
|
|
89
89
|
idGenerator?: (type?: string) => string | undefined
|
|
90
90
|
// 节点间连线、连线变更时的边的生成规则
|
|
91
91
|
edgeGenerator: LFOptions.Definition['edgeGenerator']
|
|
92
|
+
// 自定义目标锚点连接规则
|
|
93
|
+
customTargetAnchor?: LFOptions.Definition['customTargetAnchor']
|
|
92
94
|
|
|
93
95
|
// Remind:用于记录当前画布上所有节点和边的 model 的 Map
|
|
94
96
|
// 现在的处理方式,用 this.nodes.map 生成的方式,如果在 new Model 的过程中依赖于其它节点的 model,会出现找不到的情况
|
|
@@ -163,6 +165,7 @@ export class GraphModel {
|
|
|
163
165
|
edgeGenerator,
|
|
164
166
|
animation,
|
|
165
167
|
customTrajectory,
|
|
168
|
+
customTargetAnchor,
|
|
166
169
|
} = options
|
|
167
170
|
this.rootEl = container
|
|
168
171
|
this.partial = !!partial
|
|
@@ -216,6 +219,7 @@ export class GraphModel {
|
|
|
216
219
|
this.idGenerator = idGenerator
|
|
217
220
|
this.edgeGenerator = createEdgeGenerator(this, edgeGenerator)
|
|
218
221
|
this.customTrajectory = customTrajectory
|
|
222
|
+
this.customTargetAnchor = customTargetAnchor
|
|
219
223
|
}
|
|
220
224
|
|
|
221
225
|
@computed get nodesMap(): GraphModel.NodesMapType {
|
|
@@ -1248,6 +1252,7 @@ export class GraphModel {
|
|
|
1248
1252
|
clearSelectElements() {
|
|
1249
1253
|
this.selectElements.forEach((element) => {
|
|
1250
1254
|
element?.setSelected(false)
|
|
1255
|
+
element?.setHovered(false)
|
|
1251
1256
|
})
|
|
1252
1257
|
this.selectElements.clear()
|
|
1253
1258
|
/**
|
|
@@ -635,7 +635,10 @@ export class BaseNodeModel<P extends PropertiesType = PropertiesType>
|
|
|
635
635
|
* 手动连接边到节点时,需要连接的锚点
|
|
636
636
|
*/
|
|
637
637
|
public getTargetAnchor(position: Point): Model.AnchorInfo {
|
|
638
|
-
|
|
638
|
+
const { customTargetAnchor } = this.graphModel
|
|
639
|
+
return (
|
|
640
|
+
customTargetAnchor?.(this, position) ?? getClosestAnchor(position, this)
|
|
641
|
+
)
|
|
639
642
|
}
|
|
640
643
|
|
|
641
644
|
/**
|
package/src/options.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TransformModel } from './model'
|
|
1
|
+
import type { TransformModel, BaseNodeModel, Model } from './model'
|
|
2
2
|
|
|
3
3
|
import { assign } from 'lodash-es'
|
|
4
4
|
import { createElement as h } from 'preact/compat'
|
|
@@ -41,6 +41,10 @@ export namespace Options {
|
|
|
41
41
|
currentEdge?: Partial<LogicFlow.EdgeConfig>,
|
|
42
42
|
) => any
|
|
43
43
|
|
|
44
|
+
export type customTargetAnchorType = (
|
|
45
|
+
nodeModel: BaseNodeModel,
|
|
46
|
+
position: LogicFlow.Point,
|
|
47
|
+
) => Model.AnchorInfo | undefined
|
|
44
48
|
export interface CustomAnchorLineProps {
|
|
45
49
|
sourcePoint: LogicFlow.Point
|
|
46
50
|
targetPoint: LogicFlow.Point
|
|
@@ -104,6 +108,7 @@ export namespace Options {
|
|
|
104
108
|
idGenerator?: (type?: string) => string
|
|
105
109
|
edgeGenerator?: EdgeGeneratorType
|
|
106
110
|
|
|
111
|
+
customTargetAnchor?: customTargetAnchorType
|
|
107
112
|
customTrajectory?: (props: CustomAnchorLineProps) => h.JSX.Element
|
|
108
113
|
themeMode?: 'radius' | 'dark' | 'colorful' // 主题模式
|
|
109
114
|
|
|
@@ -26,7 +26,7 @@ export default class MultipleSelect extends Component<IToolProps> {
|
|
|
26
26
|
})
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
handleMouseDown = (ev:
|
|
29
|
+
handleMouseDown = (ev: PointerEvent) => {
|
|
30
30
|
this.stepDrag.handleMouseDown(ev)
|
|
31
31
|
}
|
|
32
32
|
// 使多选区域的滚轮事件可以触发画布的滚轮事件
|
|
@@ -123,7 +123,7 @@ export default class MultipleSelect extends Component<IToolProps> {
|
|
|
123
123
|
<div
|
|
124
124
|
className="lf-multiple-select"
|
|
125
125
|
style={style}
|
|
126
|
-
|
|
126
|
+
onPointerDown={this.handleMouseDown}
|
|
127
127
|
onContextMenu={this.handleContextMenu}
|
|
128
128
|
onWheel={this.handleWheelEvent}
|
|
129
129
|
/>
|