@logicflow/core 2.0.15 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build$colon$dev.log +2 -2
- package/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +22 -0
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/es/LogicFlow.js +2 -2
- package/es/keyboard/shortcut.js +7 -0
- package/es/model/GraphModel.js +2 -0
- package/es/model/SnaplineModel.d.ts +2 -1
- package/es/model/SnaplineModel.js +26 -11
- package/es/options.d.ts +1 -0
- package/es/util/resize.d.ts +12 -10
- package/es/util/resize.js +160 -81
- package/es/view/Control.d.ts +5 -1
- package/es/view/Control.js +23 -2
- package/es/view/node/BaseNode.js +1 -0
- package/lib/LogicFlow.js +2 -2
- package/lib/keyboard/shortcut.js +7 -0
- package/lib/model/GraphModel.js +2 -0
- package/lib/model/SnaplineModel.d.ts +2 -1
- package/lib/model/SnaplineModel.js +26 -11
- package/lib/options.d.ts +1 -0
- package/lib/util/resize.d.ts +12 -10
- package/lib/util/resize.js +162 -83
- package/lib/view/Control.d.ts +5 -1
- package/lib/view/Control.js +22 -1
- package/lib/view/node/BaseNode.js +1 -0
- package/package.json +1 -1
- package/src/LogicFlow.tsx +8 -3
- package/src/constant/index.ts +2 -0
- package/src/keyboard/shortcut.ts +6 -0
- package/src/model/GraphModel.ts +2 -0
- package/src/model/SnaplineModel.ts +29 -11
- package/src/options.ts +1 -0
- package/src/util/resize.ts +200 -112
- package/src/view/Control.tsx +29 -5
- package/src/view/behavior/dnd.ts +3 -0
- package/src/view/node/BaseNode.tsx +1 -0
- package/stats.html +1 -1
|
@@ -21,7 +21,8 @@ exports.SnaplineModel = void 0;
|
|
|
21
21
|
var mobx_1 = require("mobx");
|
|
22
22
|
var util_1 = require("../util");
|
|
23
23
|
var SnaplineModel = /** @class */ (function () {
|
|
24
|
-
function SnaplineModel(graphModel) {
|
|
24
|
+
function SnaplineModel(graphModel, epsilon) {
|
|
25
|
+
if (epsilon === void 0) { epsilon = 1; }
|
|
25
26
|
this.isShowHorizontal = false;
|
|
26
27
|
this.isShowVertical = false;
|
|
27
28
|
this.position = {
|
|
@@ -29,6 +30,7 @@ var SnaplineModel = /** @class */ (function () {
|
|
|
29
30
|
y: 0,
|
|
30
31
|
};
|
|
31
32
|
this.graphModel = graphModel;
|
|
33
|
+
this.epsilon = epsilon;
|
|
32
34
|
}
|
|
33
35
|
SnaplineModel.prototype.getStyle = function () {
|
|
34
36
|
return __assign({}, this.graphModel.theme.snapline);
|
|
@@ -42,10 +44,10 @@ var SnaplineModel = /** @class */ (function () {
|
|
|
42
44
|
var item = nodes[i];
|
|
43
45
|
// 排除当前节点
|
|
44
46
|
if (item.id !== draggingNode.id) {
|
|
45
|
-
if (x
|
|
47
|
+
if (equal(x, item.x, this.epsilon)) {
|
|
46
48
|
isShowVertical = true;
|
|
47
49
|
}
|
|
48
|
-
if (y
|
|
50
|
+
if (equal(y, item.y, this.epsilon)) {
|
|
49
51
|
isShowHorizontal = true;
|
|
50
52
|
}
|
|
51
53
|
// 如果水平垂直都显示,则停止循环。减少不必要的遍历
|
|
@@ -87,15 +89,15 @@ var SnaplineModel = /** @class */ (function () {
|
|
|
87
89
|
if (item.id !== draggingNode.id) {
|
|
88
90
|
var itemData = (0, util_1.getNodeBBox)(item);
|
|
89
91
|
// 如果节点的最大最小Y轴坐标与节点的最大最小Y轴坐标相等,展示水平线
|
|
90
|
-
if (itemData.minY
|
|
91
|
-
itemData.maxY
|
|
92
|
+
if (equal(itemData.minY, draggingData === null || draggingData === void 0 ? void 0 : draggingData.minY, this.epsilon) ||
|
|
93
|
+
equal(itemData.maxY, draggingData === null || draggingData === void 0 ? void 0 : draggingData.minY, this.epsilon)) {
|
|
92
94
|
// 找到则停止循环。减少不必要的遍历
|
|
93
95
|
isShowHorizontal = true;
|
|
94
96
|
horizontalY = draggingData.minY;
|
|
95
97
|
break;
|
|
96
98
|
}
|
|
97
|
-
if (itemData.minY
|
|
98
|
-
itemData.maxY
|
|
99
|
+
if (equal(itemData.minY, draggingData === null || draggingData === void 0 ? void 0 : draggingData.maxY, this.epsilon) ||
|
|
100
|
+
equal(itemData.maxY, draggingData === null || draggingData === void 0 ? void 0 : draggingData.maxY, this.epsilon)) {
|
|
99
101
|
isShowHorizontal = true;
|
|
100
102
|
horizontalY = draggingData.maxY;
|
|
101
103
|
break;
|
|
@@ -132,15 +134,20 @@ var SnaplineModel = /** @class */ (function () {
|
|
|
132
134
|
if (item.id !== draggingNode.id) {
|
|
133
135
|
var itemData = (0, util_1.getNodeBBox)(item);
|
|
134
136
|
// 如果节点的最大最小X轴坐标与节点的最大最小X轴坐标相等,展示垂直线
|
|
135
|
-
if (itemData.minX
|
|
136
|
-
|
|
137
|
+
if (equal(itemData.minX, draggingData === null || draggingData === void 0 ? void 0 : draggingData.minX, this.epsilon)) {
|
|
138
|
+
isShowVertical = true;
|
|
139
|
+
verticalX = draggingData.minX;
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
if (equal(itemData.minX, draggingData === null || draggingData === void 0 ? void 0 : draggingData.minX, this.epsilon) ||
|
|
143
|
+
equal(itemData.maxX, draggingData === null || draggingData === void 0 ? void 0 : draggingData.minX, this.epsilon)) {
|
|
137
144
|
// 找到则停止循环。减少不必要的遍历
|
|
138
145
|
isShowVertical = true;
|
|
139
146
|
verticalX = draggingData.minX;
|
|
140
147
|
break;
|
|
141
148
|
}
|
|
142
|
-
if (itemData.minX
|
|
143
|
-
itemData.maxX
|
|
149
|
+
if (equal(itemData.minX, draggingData === null || draggingData === void 0 ? void 0 : draggingData.maxX, this.epsilon) ||
|
|
150
|
+
equal(itemData.maxX, draggingData === null || draggingData === void 0 ? void 0 : draggingData.maxX, this.epsilon)) {
|
|
144
151
|
isShowVertical = true;
|
|
145
152
|
verticalX = draggingData.maxX;
|
|
146
153
|
break;
|
|
@@ -216,4 +223,12 @@ var SnaplineModel = /** @class */ (function () {
|
|
|
216
223
|
return SnaplineModel;
|
|
217
224
|
}());
|
|
218
225
|
exports.SnaplineModel = SnaplineModel;
|
|
226
|
+
function equal(num1, num2, epsilon) {
|
|
227
|
+
if (Math.abs(num1 - num2) <= epsilon) {
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
219
234
|
exports.default = SnaplineModel;
|
package/lib/options.d.ts
CHANGED
package/lib/util/resize.d.ts
CHANGED
|
@@ -3,6 +3,14 @@ import { BaseNodeModel, GraphModel } from '../model';
|
|
|
3
3
|
import ResizeInfo = ResizeControl.ResizeInfo;
|
|
4
4
|
import ResizeNodeData = ResizeControl.ResizeNodeData;
|
|
5
5
|
import type { SimplePoint } from '../algorithm/rotate';
|
|
6
|
+
export declare function calculateWidthAndHeight(startRotatedTouchControlPoint: SimplePoint, endRotatedTouchControlPoint: SimplePoint, oldCenter: SimplePoint, angle: number, freezeWidth: boolean | undefined, freezeHeight: boolean | undefined, oldWidth: number, oldHeight: number): {
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
center: {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
6
14
|
/**
|
|
7
15
|
* 计算 Control 拖动后,节点的高度信息
|
|
8
16
|
* @param index
|
|
@@ -11,7 +19,7 @@ import type { SimplePoint } from '../algorithm/rotate';
|
|
|
11
19
|
* @param freezeWidth
|
|
12
20
|
* @param freezeHeight
|
|
13
21
|
*/
|
|
14
|
-
export declare const recalcResizeInfo: (index: ResizeControlIndex, resizeInfo: ResizeInfo, pct: number | undefined, freezeWidth: boolean | undefined, freezeHeight: boolean | undefined, rotate: number | undefined, controlX: number | undefined, controlY: number | undefined, oldCenterX: number, oldCenterY: number) => ResizeInfo;
|
|
22
|
+
export declare const recalcResizeInfo: (index: ResizeControlIndex, resizeInfo: ResizeInfo, pct: number | undefined, freezeWidth: boolean | undefined, freezeHeight: boolean | undefined, rotate: number | undefined, controlX: number | undefined, controlY: number | undefined, oldCenterX: number, oldCenterY: number, forceProportional?: boolean) => ResizeInfo;
|
|
15
23
|
export declare const updateEdgePointByAnchors: (nodeModel: BaseNodeModel, graphModel: GraphModel) => void;
|
|
16
24
|
export declare const triggerResizeEvent: (preNodeData: ResizeNodeData, curNodeData: ResizeNodeData, deltaX: number, deltaY: number, index: number, nodeModel: BaseNodeModel, graphModel: GraphModel) => void;
|
|
17
25
|
export type IHandleResizeParams = {
|
|
@@ -23,6 +31,7 @@ export type IHandleResizeParams = {
|
|
|
23
31
|
nodeModel: BaseNodeModel;
|
|
24
32
|
graphModel: GraphModel;
|
|
25
33
|
cancelCallback?: () => void;
|
|
34
|
+
forceProportional?: boolean;
|
|
26
35
|
};
|
|
27
36
|
/**
|
|
28
37
|
* 处理节点的 resize 事件,提出来放到 utils 中,方便在外面(extension)中使用
|
|
@@ -34,13 +43,6 @@ export type IHandleResizeParams = {
|
|
|
34
43
|
* @param nodeModel
|
|
35
44
|
* @param graphModel
|
|
36
45
|
* @param cancelCallback
|
|
46
|
+
* @param forceProportional
|
|
37
47
|
*/
|
|
38
|
-
export declare const handleResize: ({ x, y, deltaX, deltaY, index, nodeModel, graphModel, cancelCallback, }: IHandleResizeParams) => void;
|
|
39
|
-
export declare function calculateWidthAndHeight(startRotatedTouchControlPoint: SimplePoint, endRotatedTouchControlPoint: SimplePoint, oldCenter: SimplePoint, angle: number, freezeWidth: boolean | undefined, freezeHeight: boolean | undefined, oldWidth: number, oldHeight: number): {
|
|
40
|
-
width: number;
|
|
41
|
-
height: number;
|
|
42
|
-
center: {
|
|
43
|
-
x: number;
|
|
44
|
-
y: number;
|
|
45
|
-
};
|
|
46
|
-
};
|
|
48
|
+
export declare const handleResize: ({ x, y, deltaX, deltaY, index, nodeModel, graphModel, cancelCallback, forceProportional, }: IHandleResizeParams) => void;
|
package/lib/util/resize.js
CHANGED
|
@@ -1,10 +1,88 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.handleResize = exports.triggerResizeEvent = exports.updateEdgePointByAnchors = exports.recalcResizeInfo = exports.calculateWidthAndHeight = void 0;
|
|
4
4
|
var Control_1 = require("../view/Control");
|
|
5
5
|
var lodash_es_1 = require("lodash-es");
|
|
6
6
|
var constant_1 = require("../constant");
|
|
7
7
|
var rotate_1 = require("../algorithm/rotate");
|
|
8
|
+
function calculateWidthAndHeight(startRotatedTouchControlPoint, endRotatedTouchControlPoint, oldCenter, angle, freezeWidth, freezeHeight, oldWidth, oldHeight) {
|
|
9
|
+
if (freezeWidth === void 0) { freezeWidth = false; }
|
|
10
|
+
if (freezeHeight === void 0) { freezeHeight = false; }
|
|
11
|
+
// 假设目前触摸的是右下角的control点
|
|
12
|
+
// 计算出来左上角的control坐标,resize过程左上角的control坐标保持不变
|
|
13
|
+
var freezePoint = {
|
|
14
|
+
x: oldCenter.x - (startRotatedTouchControlPoint.x - oldCenter.x),
|
|
15
|
+
y: oldCenter.y - (startRotatedTouchControlPoint.y - oldCenter.y),
|
|
16
|
+
};
|
|
17
|
+
// 【touchEndPoint】右下角 + freezePoint左上角 计算出新的中心点
|
|
18
|
+
var newCenter = (0, rotate_1.getNewCenter)(freezePoint, endRotatedTouchControlPoint);
|
|
19
|
+
// 得到【touchEndPoint】右下角-没有transform的坐标
|
|
20
|
+
var endZeroTouchControlPoint = (0, rotate_1.calculatePointAfterRotateAngle)(endRotatedTouchControlPoint, newCenter, -angle);
|
|
21
|
+
// ---------- 使用transform之前的坐标计算出新的width和height ----------
|
|
22
|
+
// 得到左上角---没有transform的坐标
|
|
23
|
+
var zeroFreezePoint = (0, rotate_1.calculatePointAfterRotateAngle)(freezePoint, newCenter, -angle);
|
|
24
|
+
if (freezeWidth) {
|
|
25
|
+
// 如果固定width,那么不能单纯使用endZeroTouchControlPoint.x=startZeroTouchControlPoint.x
|
|
26
|
+
// 因为去掉transform的左上角不一定是重合的,我们要保证的是transform后的左上角重合
|
|
27
|
+
var newWidth = Math.abs(endZeroTouchControlPoint.x - zeroFreezePoint.x);
|
|
28
|
+
var widthDx = newWidth - oldWidth;
|
|
29
|
+
// 点击的是左边锚点,是+widthDx/2,点击是右边锚点,是-widthDx/2
|
|
30
|
+
if (newCenter.x > endZeroTouchControlPoint.x) {
|
|
31
|
+
// 当前触摸的是左边锚点
|
|
32
|
+
newCenter.x = newCenter.x + widthDx / 2;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// 当前触摸的是右边锚点
|
|
36
|
+
newCenter.x = newCenter.x - widthDx / 2;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (freezeHeight) {
|
|
40
|
+
var newHeight = Math.abs(endZeroTouchControlPoint.y - zeroFreezePoint.y);
|
|
41
|
+
var heightDy = newHeight - oldHeight;
|
|
42
|
+
if (newCenter.y > endZeroTouchControlPoint.y) {
|
|
43
|
+
// 当前触摸的是上边锚点
|
|
44
|
+
newCenter.y = newCenter.y + heightDy / 2;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
newCenter.y = newCenter.y - heightDy / 2;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (freezeWidth || freezeHeight) {
|
|
51
|
+
// 如果调整过transform之前的坐标,那么transform后的坐标也会改变,那么算出来的newCenter也得调整
|
|
52
|
+
// 由于无论如何rotate,中心点都是不变的,因此我们可以使用transform之前的坐标算出新的中心点
|
|
53
|
+
var nowFreezePoint = (0, rotate_1.calculatePointAfterRotateAngle)(zeroFreezePoint, newCenter, angle);
|
|
54
|
+
// 得到当前新rect的左上角与实际上transform后的左上角的偏移量
|
|
55
|
+
var dx = nowFreezePoint.x - freezePoint.x;
|
|
56
|
+
var dy = nowFreezePoint.y - freezePoint.y;
|
|
57
|
+
// 修正不使用transform的坐标: 左上角、右下角、center
|
|
58
|
+
newCenter.x = newCenter.x - dx;
|
|
59
|
+
newCenter.y = newCenter.y - dy;
|
|
60
|
+
zeroFreezePoint = (0, rotate_1.calculatePointAfterRotateAngle)(freezePoint, newCenter, -angle);
|
|
61
|
+
endZeroTouchControlPoint = {
|
|
62
|
+
x: newCenter.x - (zeroFreezePoint.x - newCenter.x),
|
|
63
|
+
y: newCenter.y - (zeroFreezePoint.y - newCenter.y),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// transform之前的坐标的左上角+右下角计算出宽度和高度
|
|
67
|
+
var width = Math.abs(endZeroTouchControlPoint.x - zeroFreezePoint.x);
|
|
68
|
+
var height = Math.abs(endZeroTouchControlPoint.y - zeroFreezePoint.y);
|
|
69
|
+
// ---------- 使用transform之前的坐标计算出新的width和height ----------
|
|
70
|
+
if (freezeWidth) {
|
|
71
|
+
// 理论计算出来的width应该等于oldWidth
|
|
72
|
+
// 但是有误差,比如oldWidth = 100; newWidth=100.000000000001
|
|
73
|
+
// 会在handleResize()限制放大缩小的最大最小范围中被阻止滑动
|
|
74
|
+
width = oldWidth;
|
|
75
|
+
}
|
|
76
|
+
if (freezeHeight) {
|
|
77
|
+
height = oldHeight;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
width: width,
|
|
81
|
+
height: height,
|
|
82
|
+
center: newCenter,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
exports.calculateWidthAndHeight = calculateWidthAndHeight;
|
|
8
86
|
function recalcRotatedResizeInfo(pct, resizeInfo, rotate, controlX, controlY, oldCenterX, oldCenterY, freezeWidth, freezeHeight) {
|
|
9
87
|
if (freezeWidth === void 0) { freezeWidth = false; }
|
|
10
88
|
if (freezeHeight === void 0) { freezeHeight = false; }
|
|
@@ -42,11 +120,12 @@ function recalcRotatedResizeInfo(pct, resizeInfo, rotate, controlX, controlY, ol
|
|
|
42
120
|
* @param freezeWidth
|
|
43
121
|
* @param freezeHeight
|
|
44
122
|
*/
|
|
45
|
-
var recalcResizeInfo = function (index, resizeInfo, pct, freezeWidth, freezeHeight, rotate, controlX, controlY, oldCenterX, oldCenterY) {
|
|
123
|
+
var recalcResizeInfo = function (index, resizeInfo, pct, freezeWidth, freezeHeight, rotate, controlX, controlY, oldCenterX, oldCenterY, forceProportional) {
|
|
46
124
|
if (pct === void 0) { pct = 1; }
|
|
47
125
|
if (freezeWidth === void 0) { freezeWidth = false; }
|
|
48
126
|
if (freezeHeight === void 0) { freezeHeight = false; }
|
|
49
127
|
if (rotate === void 0) { rotate = 0; }
|
|
128
|
+
if (forceProportional === void 0) { forceProportional = false; }
|
|
50
129
|
var nextResizeInfo = (0, lodash_es_1.cloneDeep)(resizeInfo);
|
|
51
130
|
var deltaX = nextResizeInfo.deltaX, deltaY = nextResizeInfo.deltaY;
|
|
52
131
|
var width = nextResizeInfo.width, height = nextResizeInfo.height, PCTResizeInfo = nextResizeInfo.PCTResizeInfo;
|
|
@@ -112,7 +191,84 @@ var recalcResizeInfo = function (index, resizeInfo, pct, freezeWidth, freezeHeig
|
|
|
112
191
|
// 角度rotate不为0得到的resizeInfo.deltaX仅仅代表中心点的变化,而不是宽度的变化
|
|
113
192
|
return recalcRotatedResizeInfo(pct, nextResizeInfo, rotate, controlX, controlY, oldCenterX, oldCenterY, freezeWidth, freezeHeight);
|
|
114
193
|
}
|
|
115
|
-
//
|
|
194
|
+
//Shift键等比缩放逻辑
|
|
195
|
+
if (forceProportional) {
|
|
196
|
+
// 计算当前的宽高比
|
|
197
|
+
var aspectRatio = width / height;
|
|
198
|
+
// 根据拖拽方向确定主要的缩放参考
|
|
199
|
+
var primaryDelta = 0;
|
|
200
|
+
var newWidth = width;
|
|
201
|
+
var newHeight = height;
|
|
202
|
+
switch (index) {
|
|
203
|
+
case Control_1.ResizeControlIndex.LEFT_TOP:
|
|
204
|
+
// 取绝对值较大的delta作为主要缩放参考
|
|
205
|
+
primaryDelta = Math.abs(deltaX) > Math.abs(deltaY) ? -deltaX : -deltaY;
|
|
206
|
+
if (aspectRatio >= 1) {
|
|
207
|
+
// 宽度大于等于高度,以宽度为基准
|
|
208
|
+
newWidth = width + primaryDelta;
|
|
209
|
+
newHeight = newWidth / aspectRatio;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
// 高度大于宽度,以高度为基准
|
|
213
|
+
newHeight = height + primaryDelta;
|
|
214
|
+
newWidth = newHeight * aspectRatio;
|
|
215
|
+
}
|
|
216
|
+
nextResizeInfo.width = newWidth;
|
|
217
|
+
nextResizeInfo.height = newHeight;
|
|
218
|
+
nextResizeInfo.deltaX = width - newWidth;
|
|
219
|
+
nextResizeInfo.deltaY = height - newHeight;
|
|
220
|
+
break;
|
|
221
|
+
case Control_1.ResizeControlIndex.RIGHT_TOP:
|
|
222
|
+
primaryDelta = Math.abs(deltaX) > Math.abs(deltaY) ? deltaX : -deltaY;
|
|
223
|
+
if (aspectRatio >= 1) {
|
|
224
|
+
newWidth = width + primaryDelta;
|
|
225
|
+
newHeight = newWidth / aspectRatio;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
newHeight = height - primaryDelta;
|
|
229
|
+
newWidth = newHeight * aspectRatio;
|
|
230
|
+
}
|
|
231
|
+
nextResizeInfo.width = newWidth;
|
|
232
|
+
nextResizeInfo.height = newHeight;
|
|
233
|
+
nextResizeInfo.deltaX = newWidth - width;
|
|
234
|
+
nextResizeInfo.deltaY = height - newHeight;
|
|
235
|
+
break;
|
|
236
|
+
case Control_1.ResizeControlIndex.RIGHT_BOTTOM:
|
|
237
|
+
primaryDelta = Math.abs(deltaX) > Math.abs(deltaY) ? deltaX : deltaY;
|
|
238
|
+
if (aspectRatio >= 1) {
|
|
239
|
+
newWidth = width + primaryDelta;
|
|
240
|
+
newHeight = newWidth / aspectRatio;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
newHeight = height + primaryDelta;
|
|
244
|
+
newWidth = newHeight * aspectRatio;
|
|
245
|
+
}
|
|
246
|
+
nextResizeInfo.width = newWidth;
|
|
247
|
+
nextResizeInfo.height = newHeight;
|
|
248
|
+
nextResizeInfo.deltaX = newWidth - width;
|
|
249
|
+
nextResizeInfo.deltaY = newHeight - height;
|
|
250
|
+
break;
|
|
251
|
+
case Control_1.ResizeControlIndex.LEFT_BOTTOM:
|
|
252
|
+
primaryDelta = Math.abs(deltaX) > Math.abs(deltaY) ? -deltaX : deltaY;
|
|
253
|
+
if (aspectRatio >= 1) {
|
|
254
|
+
newWidth = width - primaryDelta;
|
|
255
|
+
newHeight = newWidth / aspectRatio;
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
newHeight = height + primaryDelta;
|
|
259
|
+
newWidth = newHeight * aspectRatio;
|
|
260
|
+
}
|
|
261
|
+
nextResizeInfo.width = newWidth;
|
|
262
|
+
nextResizeInfo.height = newHeight;
|
|
263
|
+
nextResizeInfo.deltaX = width - newWidth;
|
|
264
|
+
nextResizeInfo.deltaY = newHeight - height;
|
|
265
|
+
break;
|
|
266
|
+
default:
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
return nextResizeInfo;
|
|
270
|
+
}
|
|
271
|
+
// 原有的非等比缩放逻辑保持不变
|
|
116
272
|
switch (index) {
|
|
117
273
|
case Control_1.ResizeControlIndex.LEFT_TOP:
|
|
118
274
|
nextResizeInfo.width = freezeWidth ? width : width - deltaX * pct;
|
|
@@ -195,9 +351,10 @@ exports.triggerResizeEvent = triggerResizeEvent;
|
|
|
195
351
|
* @param nodeModel
|
|
196
352
|
* @param graphModel
|
|
197
353
|
* @param cancelCallback
|
|
354
|
+
* @param forceProportional
|
|
198
355
|
*/
|
|
199
356
|
var handleResize = function (_a) {
|
|
200
|
-
var x = _a.x, y = _a.y, deltaX = _a.deltaX, deltaY = _a.deltaY, index = _a.index, nodeModel = _a.nodeModel, graphModel = _a.graphModel, cancelCallback = _a.cancelCallback;
|
|
357
|
+
var x = _a.x, y = _a.y, deltaX = _a.deltaX, deltaY = _a.deltaY, index = _a.index, nodeModel = _a.nodeModel, graphModel = _a.graphModel, cancelCallback = _a.cancelCallback, _b = _a.forceProportional, forceProportional = _b === void 0 ? false : _b;
|
|
201
358
|
var r = nodeModel.r, // circle
|
|
202
359
|
rx = nodeModel.rx, // ellipse/diamond
|
|
203
360
|
ry = nodeModel.ry, width = nodeModel.width, // rect/html
|
|
@@ -214,7 +371,7 @@ var handleResize = function (_a) {
|
|
|
214
371
|
var pct = r || (rx && ry) ? 1 / 2 : 1;
|
|
215
372
|
var controlX = x;
|
|
216
373
|
var controlY = y;
|
|
217
|
-
var nextSize = (0, exports.recalcResizeInfo)(index, resizeInfo, pct, isFreezeWidth, isFreezeHeight, rotate, controlX, controlY, oldCenterX, oldCenterY);
|
|
374
|
+
var nextSize = (0, exports.recalcResizeInfo)(index, resizeInfo, pct, isFreezeWidth, isFreezeHeight, rotate, controlX, controlY, oldCenterX, oldCenterY, forceProportional);
|
|
218
375
|
// 限制放大缩小的最大最小范围
|
|
219
376
|
if (nextSize.width < minWidth ||
|
|
220
377
|
nextSize.width > maxWidth ||
|
|
@@ -247,81 +404,3 @@ var handleResize = function (_a) {
|
|
|
247
404
|
(0, exports.triggerResizeEvent)(preNodeData, curNodeData, deltaX, deltaY, index, nodeModel, graphModel);
|
|
248
405
|
};
|
|
249
406
|
exports.handleResize = handleResize;
|
|
250
|
-
function calculateWidthAndHeight(startRotatedTouchControlPoint, endRotatedTouchControlPoint, oldCenter, angle, freezeWidth, freezeHeight, oldWidth, oldHeight) {
|
|
251
|
-
if (freezeWidth === void 0) { freezeWidth = false; }
|
|
252
|
-
if (freezeHeight === void 0) { freezeHeight = false; }
|
|
253
|
-
// 假设目前触摸的是右下角的control点
|
|
254
|
-
// 计算出来左上角的control坐标,resize过程左上角的control坐标保持不变
|
|
255
|
-
var freezePoint = {
|
|
256
|
-
x: oldCenter.x - (startRotatedTouchControlPoint.x - oldCenter.x),
|
|
257
|
-
y: oldCenter.y - (startRotatedTouchControlPoint.y - oldCenter.y),
|
|
258
|
-
};
|
|
259
|
-
// 【touchEndPoint】右下角 + freezePoint左上角 计算出新的中心点
|
|
260
|
-
var newCenter = (0, rotate_1.getNewCenter)(freezePoint, endRotatedTouchControlPoint);
|
|
261
|
-
// 得到【touchEndPoint】右下角-没有transform的坐标
|
|
262
|
-
var endZeroTouchControlPoint = (0, rotate_1.calculatePointAfterRotateAngle)(endRotatedTouchControlPoint, newCenter, -angle);
|
|
263
|
-
// ---------- 使用transform之前的坐标计算出新的width和height ----------
|
|
264
|
-
// 得到左上角---没有transform的坐标
|
|
265
|
-
var zeroFreezePoint = (0, rotate_1.calculatePointAfterRotateAngle)(freezePoint, newCenter, -angle);
|
|
266
|
-
if (freezeWidth) {
|
|
267
|
-
// 如果固定width,那么不能单纯使用endZeroTouchControlPoint.x=startZeroTouchControlPoint.x
|
|
268
|
-
// 因为去掉transform的左上角不一定是重合的,我们要保证的是transform后的左上角重合
|
|
269
|
-
var newWidth = Math.abs(endZeroTouchControlPoint.x - zeroFreezePoint.x);
|
|
270
|
-
var widthDx = newWidth - oldWidth;
|
|
271
|
-
// 点击的是左边锚点,是+widthDx/2,点击是右边锚点,是-widthDx/2
|
|
272
|
-
if (newCenter.x > endZeroTouchControlPoint.x) {
|
|
273
|
-
// 当前触摸的是左边锚点
|
|
274
|
-
newCenter.x = newCenter.x + widthDx / 2;
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
// 当前触摸的是右边锚点
|
|
278
|
-
newCenter.x = newCenter.x - widthDx / 2;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
if (freezeHeight) {
|
|
282
|
-
var newHeight = Math.abs(endZeroTouchControlPoint.y - zeroFreezePoint.y);
|
|
283
|
-
var heightDy = newHeight - oldHeight;
|
|
284
|
-
if (newCenter.y > endZeroTouchControlPoint.y) {
|
|
285
|
-
// 当前触摸的是上边锚点
|
|
286
|
-
newCenter.y = newCenter.y + heightDy / 2;
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
newCenter.y = newCenter.y - heightDy / 2;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
if (freezeWidth || freezeHeight) {
|
|
293
|
-
// 如果调整过transform之前的坐标,那么transform后的坐标也会改变,那么算出来的newCenter也得调整
|
|
294
|
-
// 由于无论如何rotate,中心点都是不变的,因此我们可以使用transform之前的坐标算出新的中心点
|
|
295
|
-
var nowFreezePoint = (0, rotate_1.calculatePointAfterRotateAngle)(zeroFreezePoint, newCenter, angle);
|
|
296
|
-
// 得到当前新rect的左上角与实际上transform后的左上角的偏移量
|
|
297
|
-
var dx = nowFreezePoint.x - freezePoint.x;
|
|
298
|
-
var dy = nowFreezePoint.y - freezePoint.y;
|
|
299
|
-
// 修正不使用transform的坐标: 左上角、右下角、center
|
|
300
|
-
newCenter.x = newCenter.x - dx;
|
|
301
|
-
newCenter.y = newCenter.y - dy;
|
|
302
|
-
zeroFreezePoint = (0, rotate_1.calculatePointAfterRotateAngle)(freezePoint, newCenter, -angle);
|
|
303
|
-
endZeroTouchControlPoint = {
|
|
304
|
-
x: newCenter.x - (zeroFreezePoint.x - newCenter.x),
|
|
305
|
-
y: newCenter.y - (zeroFreezePoint.y - newCenter.y),
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
|
-
// transform之前的坐标的左上角+右下角计算出宽度和高度
|
|
309
|
-
var width = Math.abs(endZeroTouchControlPoint.x - zeroFreezePoint.x);
|
|
310
|
-
var height = Math.abs(endZeroTouchControlPoint.y - zeroFreezePoint.y);
|
|
311
|
-
// ---------- 使用transform之前的坐标计算出新的width和height ----------
|
|
312
|
-
if (freezeWidth) {
|
|
313
|
-
// 理论计算出来的width应该等于oldWidth
|
|
314
|
-
// 但是有误差,比如oldWidth = 100; newWidth=100.000000000001
|
|
315
|
-
// 会在handleResize()限制放大缩小的最大最小范围中被阻止滑动
|
|
316
|
-
width = oldWidth;
|
|
317
|
-
}
|
|
318
|
-
if (freezeHeight) {
|
|
319
|
-
height = oldHeight;
|
|
320
|
-
}
|
|
321
|
-
return {
|
|
322
|
-
width: width,
|
|
323
|
-
height: height,
|
|
324
|
-
center: newCenter,
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
exports.calculateWidthAndHeight = calculateWidthAndHeight;
|
package/lib/view/Control.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { IDragParams, StepDrag } from '../util';
|
|
|
4
4
|
import { BaseNodeModel, GraphModel } from '../model';
|
|
5
5
|
import NodeData = LogicFlow.NodeData;
|
|
6
6
|
import VectorData = LogicFlow.VectorData;
|
|
7
|
-
import ResizeInfo = ResizeControl.ResizeInfo;
|
|
8
7
|
import ResizeNodeData = ResizeControl.ResizeNodeData;
|
|
8
|
+
import ResizeInfo = ResizeControl.ResizeInfo;
|
|
9
9
|
import ControlItemProps = ResizeControl.ControlItemProps;
|
|
10
10
|
export declare enum ResizeControlIndex {
|
|
11
11
|
LEFT_TOP = 0,
|
|
@@ -29,7 +29,11 @@ export declare class ResizeControl extends Component<IResizeControlProps, IResiz
|
|
|
29
29
|
readonly nodeModel: BaseNodeModel;
|
|
30
30
|
readonly graphModel: GraphModel;
|
|
31
31
|
readonly dragHandler: StepDrag;
|
|
32
|
+
private isShiftPressed;
|
|
32
33
|
constructor(props: IResizeControlProps);
|
|
34
|
+
bindKeyboardEvents: () => void;
|
|
35
|
+
handleKeyDown: (event: KeyboardEvent) => void;
|
|
36
|
+
handleKeyUp: (event: KeyboardEvent) => void;
|
|
33
37
|
componentWillUnmount(): void;
|
|
34
38
|
updateEdgePointByAnchors: () => void;
|
|
35
39
|
triggerResizeEvent: (preNodeData: ResizeNodeData, curNodeData: ResizeNodeData, deltaX: any, deltaY: any, index: any, nodeModel: BaseNodeModel) => void;
|
package/lib/view/Control.js
CHANGED
|
@@ -71,6 +71,24 @@ var ResizeControl = /** @class */ (function (_super) {
|
|
|
71
71
|
__extends(ResizeControl, _super);
|
|
72
72
|
function ResizeControl(props) {
|
|
73
73
|
var _this = _super.call(this) || this;
|
|
74
|
+
//判断Shift键状态
|
|
75
|
+
_this.isShiftPressed = false;
|
|
76
|
+
//绑定键盘事件监听
|
|
77
|
+
_this.bindKeyboardEvents = function () {
|
|
78
|
+
document.addEventListener('keydown', _this.handleKeyDown);
|
|
79
|
+
document.addEventListener('keyup', _this.handleKeyUp);
|
|
80
|
+
};
|
|
81
|
+
//处理键盘按下事件
|
|
82
|
+
_this.handleKeyDown = function (event) {
|
|
83
|
+
if (event.key === 'Shift') {
|
|
84
|
+
_this.isShiftPressed = true;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
_this.handleKeyUp = function (event) {
|
|
88
|
+
if (event.key === 'Shift') {
|
|
89
|
+
_this.isShiftPressed = false;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
74
92
|
_this.updateEdgePointByAnchors = function () {
|
|
75
93
|
// https://github.com/didi/LogicFlow/issues/807
|
|
76
94
|
// https://github.com/didi/LogicFlow/issues/875
|
|
@@ -223,6 +241,7 @@ var ResizeControl = /** @class */ (function (_super) {
|
|
|
223
241
|
index: index,
|
|
224
242
|
nodeModel: model,
|
|
225
243
|
graphModel: graphModel,
|
|
244
|
+
forceProportional: _this.isShiftPressed,
|
|
226
245
|
cancelCallback: function () {
|
|
227
246
|
_this.dragHandler.cancelDrag();
|
|
228
247
|
},
|
|
@@ -313,17 +332,19 @@ var ResizeControl = /** @class */ (function (_super) {
|
|
|
313
332
|
_this.index = index;
|
|
314
333
|
_this.nodeModel = model;
|
|
315
334
|
_this.graphModel = graphModel;
|
|
316
|
-
// 初始化拖拽工具
|
|
317
335
|
_this.dragHandler = new util_1.StepDrag({
|
|
318
336
|
onDragStart: _this.onDragStart,
|
|
319
337
|
onDragging: _this.onDragging,
|
|
320
338
|
onDragEnd: _this.onDragEnd,
|
|
321
339
|
step: graphModel.gridSize,
|
|
322
340
|
});
|
|
341
|
+
_this.bindKeyboardEvents();
|
|
323
342
|
return _this;
|
|
324
343
|
}
|
|
325
344
|
ResizeControl.prototype.componentWillUnmount = function () {
|
|
326
345
|
this.dragHandler.destroy();
|
|
346
|
+
document.removeEventListener('keydown', this.handleKeyDown);
|
|
347
|
+
document.removeEventListener('keyup', this.handleKeyUp);
|
|
327
348
|
};
|
|
328
349
|
ResizeControl.prototype.render = function () {
|
|
329
350
|
var _a = this.props, x = _a.x, y = _a.y, direction = _a.direction, model = _a.model;
|
|
@@ -261,6 +261,7 @@ var BaseNode = /** @class */ (function (_super) {
|
|
|
261
261
|
var _a = _this.props, model = _a.model, graphModel = _a.graphModel;
|
|
262
262
|
_this.startTime = new Date().getTime();
|
|
263
263
|
var editConfigModel = graphModel.editConfigModel;
|
|
264
|
+
model.setSelected(true);
|
|
264
265
|
if (editConfigModel.adjustNodePosition && model.draggable) {
|
|
265
266
|
_this.stepDrag && _this.stepDrag.handleMouseDown(ev);
|
|
266
267
|
}
|
package/package.json
CHANGED
package/src/LogicFlow.tsx
CHANGED
|
@@ -133,7 +133,10 @@ export class LogicFlow {
|
|
|
133
133
|
})
|
|
134
134
|
|
|
135
135
|
if (initOptions.snapline !== false) {
|
|
136
|
-
this.snaplineModel = new SnaplineModel(
|
|
136
|
+
this.snaplineModel = new SnaplineModel(
|
|
137
|
+
this.graphModel,
|
|
138
|
+
initOptions.snaplineEpsilon,
|
|
139
|
+
)
|
|
137
140
|
snapline(eventCenter, this.snaplineModel)
|
|
138
141
|
}
|
|
139
142
|
if (!initOptions.isSilentMode) {
|
|
@@ -900,7 +903,6 @@ export class LogicFlow {
|
|
|
900
903
|
updateEditConfig(config: Partial<IEditConfigType>) {
|
|
901
904
|
const { editConfigModel, transformModel } = this.graphModel
|
|
902
905
|
const currentSnapGrid = editConfigModel.snapGrid
|
|
903
|
-
|
|
904
906
|
editConfigModel.updateEditConfig(config)
|
|
905
907
|
if (config?.stopMoveGraph !== undefined) {
|
|
906
908
|
transformModel.updateTranslateLimits(config.stopMoveGraph)
|
|
@@ -916,6 +918,9 @@ export class LogicFlow {
|
|
|
916
918
|
} = this.graphModel
|
|
917
919
|
this.graphModel.updateGridSize(config.snapGrid ? size : 1)
|
|
918
920
|
}
|
|
921
|
+
this.emit(EventType.EDIT_CONFIG_CHANGED, {
|
|
922
|
+
data: editConfigModel.getConfig(),
|
|
923
|
+
})
|
|
919
924
|
}
|
|
920
925
|
|
|
921
926
|
/**
|
|
@@ -1432,7 +1437,7 @@ export class LogicFlow {
|
|
|
1432
1437
|
this.graphModel.destroy()
|
|
1433
1438
|
this.tool.destroy()
|
|
1434
1439
|
this.history.destroy()
|
|
1435
|
-
|
|
1440
|
+
clearThemeMode()
|
|
1436
1441
|
for (const extensionName in this.extension) {
|
|
1437
1442
|
const extensionInstance = this.extension[extensionName]
|
|
1438
1443
|
if ('destroy' in extensionInstance) {
|
package/src/constant/index.ts
CHANGED
|
@@ -101,6 +101,7 @@ export enum EventType {
|
|
|
101
101
|
BLANK_DRAG = 'blank:drag',
|
|
102
102
|
BLANK_DROP = 'blank:drop',
|
|
103
103
|
BLANK_MOUSEMOVE = 'blank:mousemove',
|
|
104
|
+
BLANK_CANVAS_MOUSEMOVE = 'blank:canvas-mousemove',
|
|
104
105
|
BLANK_MOUSEUP = 'blank:mouseup',
|
|
105
106
|
BLANK_CLICK = 'blank:click',
|
|
106
107
|
BLANK_CONTEXTMENU = 'blank:contextmenu',
|
|
@@ -157,6 +158,7 @@ export enum EventType {
|
|
|
157
158
|
GRAPH_TRANSFORM = 'graph:transform',
|
|
158
159
|
GRAPH_RENDERED = 'graph:rendered',
|
|
159
160
|
GRAPH_UPDATED = 'graph:updated',
|
|
161
|
+
EDIT_CONFIG_CHANGED = 'editConfig:changed',
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
export enum OverlapMode {
|
package/src/keyboard/shortcut.ts
CHANGED
|
@@ -19,6 +19,12 @@ export function translateNodeData(nodeData: NodeData, distance: number) {
|
|
|
19
19
|
nodeData.text.y += distance
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
if (!isEmpty(nodeData.properties?._label)) {
|
|
23
|
+
nodeData.properties?._label.forEach((label) => {
|
|
24
|
+
label.x += distance
|
|
25
|
+
label.y += distance
|
|
26
|
+
})
|
|
27
|
+
}
|
|
22
28
|
return nodeData
|
|
23
29
|
}
|
|
24
30
|
|
package/src/model/GraphModel.ts
CHANGED
|
@@ -984,6 +984,8 @@ export class GraphModel {
|
|
|
984
984
|
}
|
|
985
985
|
if (edgeOriginData.id && this.edgesMap[edgeOriginData.id]) {
|
|
986
986
|
delete edgeOriginData.id
|
|
987
|
+
delete edgeOriginData.sourceAnchorId
|
|
988
|
+
delete edgeOriginData.targetAnchorId
|
|
987
989
|
}
|
|
988
990
|
const Model = this.getModel(type) as BaseEdgeModelCtor
|
|
989
991
|
if (!Model) {
|