@logicflow/core 2.0.5 → 2.0.6

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.
@@ -42,6 +42,15 @@ export declare namespace Model {
42
42
  * deltaY: 移动的 Y 轴距离
43
43
  */
44
44
  type NodeMoveRule = (model: BaseNodeModel, deltaX: number, deltaY: number) => boolean | IsAllowMove;
45
+ /**
46
+ * 限制节点resize规则
47
+ * model: 移动节点的 model
48
+ * deltaX: 中心点移动的 X 轴距离
49
+ * deltaY: 中心点移动的 Y 轴距离
50
+ * width: 中心点新的width
51
+ * height: 中心点新的height
52
+ */
53
+ type NodeResizeRule = (model: BaseNodeModel, deltaX: number, deltaY: number, width: number, height: number) => boolean;
45
54
  type AdjustEdgeStartAndEndParams = {
46
55
  startPoint: LogicFlow.Point;
47
56
  endPoint: LogicFlow.Point;
@@ -32,9 +32,14 @@ export declare class GraphModel {
32
32
  elementsModelMap: Map<string, BaseNodeModel | BaseEdgeModel>;
33
33
  /**
34
34
  * 节点移动规则判断
35
- * 在节点移动的时候,会出发此数组中的所有规则判断
35
+ * 在节点移动的时候,会触发此数组中的所有规则判断
36
36
  */
37
37
  nodeMoveRules: Model.NodeMoveRule[];
38
+ /**
39
+ * 节点resize规则判断
40
+ * 在节点resize的时候,会触发此数组中的所有规则判断
41
+ */
42
+ nodeResizeRules: Model.NodeResizeRule[];
38
43
  /**
39
44
  * 获取自定义连线轨迹
40
45
  */
@@ -330,6 +335,7 @@ export declare class GraphModel {
330
335
  *
331
336
  */
332
337
  addNodeMoveRules(fn: Model.NodeMoveRule): void;
338
+ addNodeResizeRules(fn: Model.NodeResizeRule): void;
333
339
  /**
334
340
  * 设置默认的边类型
335
341
  * 也就是设置在节点直接有用户手动绘制的连线类型。
@@ -64,9 +64,14 @@ var GraphModel = /** @class */ (function () {
64
64
  this.elementsModelMap = new Map();
65
65
  /**
66
66
  * 节点移动规则判断
67
- * 在节点移动的时候,会出发此数组中的所有规则判断
67
+ * 在节点移动的时候,会触发此数组中的所有规则判断
68
68
  */
69
69
  this.nodeMoveRules = [];
70
+ /**
71
+ * 节点resize规则判断
72
+ * 在节点resize的时候,会触发此数组中的所有规则判断
73
+ */
74
+ this.nodeResizeRules = [];
70
75
  // 当前图上所有节点的model
71
76
  this.nodes = [];
72
77
  // 当前图上所有边的model
@@ -1087,6 +1092,11 @@ var GraphModel = /** @class */ (function () {
1087
1092
  this.nodeMoveRules.push(fn);
1088
1093
  }
1089
1094
  };
1095
+ GraphModel.prototype.addNodeResizeRules = function (fn) {
1096
+ if (!this.nodeResizeRules.includes(fn)) {
1097
+ this.nodeResizeRules.push(fn);
1098
+ }
1099
+ };
1090
1100
  /**
1091
1101
  * 设置默认的边类型
1092
1102
  * 也就是设置在节点直接有用户手动绘制的连线类型。
@@ -72,6 +72,7 @@ export declare class BaseNodeModel<P extends PropertiesType = PropertiesType> im
72
72
  targetRules: Model.ConnectRule[];
73
73
  sourceRules: Model.ConnectRule[];
74
74
  moveRules: Model.NodeMoveRule[];
75
+ resizeRules: Model.NodeResizeRule[];
75
76
  hasSetTargetRules: boolean;
76
77
  hasSetSourceRules: boolean;
77
78
  [propName: string]: any;
@@ -264,6 +265,12 @@ export declare class BaseNodeModel<P extends PropertiesType = PropertiesType> im
264
265
  moveTo(x: number, y: number, isIgnoreRule?: boolean): boolean;
265
266
  moveText(deltaX: number, deltaY: number): void;
266
267
  updateText(value: string): void;
268
+ addNodeResizeRules(fn: Model.NodeResizeRule): void;
269
+ /**
270
+ * 内部方法
271
+ * 是否允许resize节点到新的位置
272
+ */
273
+ isAllowResizeNode(deltaX: number, deltaY: number, width: number, height: number): boolean;
267
274
  setSelected(flag?: boolean): void;
268
275
  setHovered(flag?: boolean): void;
269
276
  setIsShowAnchor(flag?: boolean): void;
@@ -98,6 +98,7 @@ var BaseNodeModel = /** @class */ (function () {
98
98
  this.targetRules = [];
99
99
  this.sourceRules = [];
100
100
  this.moveRules = []; // 节点移动之前的hook
101
+ this.resizeRules = []; // 节点resize之前的hook
101
102
  this.hasSetTargetRules = false; // 用来限制rules的重复值
102
103
  this.hasSetSourceRules = false; // 用来限制rules的重复值
103
104
  this.graphModel = graphModel;
@@ -243,7 +244,7 @@ var BaseNodeModel = /** @class */ (function () {
243
244
  textConfig.draggable = text.draggable;
244
245
  }
245
246
  if (!(0, lodash_es_1.isUndefined)(text.editable)) {
246
- textConfig.draggable = text.draggable;
247
+ textConfig.editable = text.editable;
247
248
  }
248
249
  }
249
250
  }
@@ -255,6 +256,10 @@ var BaseNodeModel = /** @class */ (function () {
255
256
  */
256
257
  BaseNodeModel.prototype.resize = function (resizeInfo) {
257
258
  var width = resizeInfo.width, height = resizeInfo.height, deltaX = resizeInfo.deltaX, deltaY = resizeInfo.deltaY;
259
+ var isAllowResize = this.isAllowResizeNode(deltaX, deltaY, width, height);
260
+ if (!isAllowResize) {
261
+ return this.getData();
262
+ }
258
263
  // 移动节点以及文本内容
259
264
  this.move(deltaX / 2, deltaY / 2);
260
265
  this.width = width;
@@ -277,6 +282,18 @@ var BaseNodeModel = /** @class */ (function () {
277
282
  if ((0, mobx_1.isObservable)(properties)) {
278
283
  properties = (0, mobx_1.toJS)(properties);
279
284
  }
285
+ if ((0, lodash_es_1.isNil)(properties.width)) {
286
+ // resize()的时候会触发this.setProperties({width,height})
287
+ // 然后返回getData(),可以从properties拿到width
288
+ // 但是初始化如果没有在properties传入width,那么getData()就一直无法从properties拿到width
289
+ properties.width = this.width;
290
+ }
291
+ if ((0, lodash_es_1.isNil)(properties.height)) {
292
+ // resize()的时候会触发this.setProperties({width,height})
293
+ // 然后返回getData(),可以从properties拿到height
294
+ // 但是初始化如果没有在properties传入height,那么getData()就一直无法从properties拿到width
295
+ properties.height = this.height;
296
+ }
280
297
  var data = {
281
298
  id: this.id,
282
299
  type: this.type,
@@ -609,6 +626,10 @@ var BaseNodeModel = /** @class */ (function () {
609
626
  this.y = this.y + deltaY;
610
627
  this.text && this.moveText(0, deltaY);
611
628
  }
629
+ if (isAllowMoveX || isAllowMoveY) {
630
+ // 更新x和y的同时也要更新对应的transform旋转矩阵(依赖x、y)
631
+ this.rotate = this._rotate;
632
+ }
612
633
  return isAllowMoveX || isAllowMoveY;
613
634
  };
614
635
  BaseNodeModel.prototype.getMoveDistance = function (deltaX, deltaY, isIgnoreRule) {
@@ -652,6 +673,35 @@ var BaseNodeModel = /** @class */ (function () {
652
673
  BaseNodeModel.prototype.updateText = function (value) {
653
674
  this.text = __assign(__assign({}, (0, mobx_1.toJS)(this.text)), { value: value });
654
675
  };
676
+ BaseNodeModel.prototype.addNodeResizeRules = function (fn) {
677
+ if (!this.resizeRules.includes(fn)) {
678
+ this.resizeRules.push(fn);
679
+ }
680
+ };
681
+ /**
682
+ * 内部方法
683
+ * 是否允许resize节点到新的位置
684
+ */
685
+ BaseNodeModel.prototype.isAllowResizeNode = function (deltaX, deltaY, width, height) {
686
+ var e_2, _a;
687
+ var rules = this.resizeRules.concat(this.graphModel.nodeResizeRules);
688
+ try {
689
+ for (var rules_2 = __values(rules), rules_2_1 = rules_2.next(); !rules_2_1.done; rules_2_1 = rules_2.next()) {
690
+ var rule = rules_2_1.value;
691
+ var r = rule(this, deltaX, deltaY, width, height);
692
+ if (!r)
693
+ return false;
694
+ }
695
+ }
696
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
697
+ finally {
698
+ try {
699
+ if (rules_2_1 && !rules_2_1.done && (_a = rules_2.return)) _a.call(rules_2);
700
+ }
701
+ finally { if (e_2) throw e_2.error; }
702
+ }
703
+ return true;
704
+ };
655
705
  BaseNodeModel.prototype.setSelected = function (flag) {
656
706
  if (flag === void 0) { flag = true; }
657
707
  this.isSelected = flag;
@@ -842,6 +892,9 @@ var BaseNodeModel = /** @class */ (function () {
842
892
  __decorate([
843
893
  mobx_1.action
844
894
  ], BaseNodeModel.prototype, "updateText", null);
895
+ __decorate([
896
+ mobx_1.action
897
+ ], BaseNodeModel.prototype, "addNodeResizeRules", null);
845
898
  __decorate([
846
899
  mobx_1.action
847
900
  ], BaseNodeModel.prototype, "setSelected", null);
@@ -1,5 +1,5 @@
1
1
  import LogicFlow from '..';
2
- import { EditConfigModel } from 'src/model';
2
+ import { EditConfigModel } from '..';
3
3
  /**
4
4
  * 判断一个点是否在指定区域
5
5
  * @param point 当前点
@@ -2,6 +2,7 @@ import { ResizeControl, ResizeControlIndex } from '../view/Control';
2
2
  import { BaseNodeModel, GraphModel } from '../model';
3
3
  import ResizeInfo = ResizeControl.ResizeInfo;
4
4
  import ResizeNodeData = ResizeControl.ResizeNodeData;
5
+ import type { SimplePoint } from '../algorithm/rotate';
5
6
  /**
6
7
  * 计算 Control 拖动后,节点的高度信息
7
8
  * @param index
@@ -10,11 +11,23 @@ import ResizeNodeData = ResizeControl.ResizeNodeData;
10
11
  * @param freezeWidth
11
12
  * @param freezeHeight
12
13
  */
13
- export declare const recalcResizeInfo: (index: ResizeControlIndex, resizeInfo: ResizeInfo, pct?: number, freezeWidth?: boolean, freezeHeight?: boolean) => ResizeInfo;
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;
14
15
  export declare const updateEdgePointByAnchors: (nodeModel: BaseNodeModel, graphModel: GraphModel) => void;
15
16
  export declare const triggerResizeEvent: (preNodeData: ResizeNodeData, curNodeData: ResizeNodeData, deltaX: number, deltaY: number, index: number, nodeModel: BaseNodeModel, graphModel: GraphModel) => void;
17
+ export type IHandleResizeParams = {
18
+ x?: number;
19
+ y?: number;
20
+ deltaX: number;
21
+ deltaY: number;
22
+ index: ResizeControlIndex;
23
+ nodeModel: BaseNodeModel;
24
+ graphModel: GraphModel;
25
+ cancelCallback?: () => void;
26
+ };
16
27
  /**
17
28
  * 处理节点的 resize 事件,提出来放到 utils 中,方便在外面(extension)中使用
29
+ * @param x
30
+ * @param y
18
31
  * @param deltaX
19
32
  * @param deltaY
20
33
  * @param index
@@ -22,11 +35,12 @@ export declare const triggerResizeEvent: (preNodeData: ResizeNodeData, curNodeDa
22
35
  * @param graphModel
23
36
  * @param cancelCallback
24
37
  */
25
- export declare const handleResize: ({ deltaX, deltaY, index, nodeModel, graphModel, cancelCallback, }: {
26
- deltaX: any;
27
- deltaY: any;
28
- index: any;
29
- nodeModel: any;
30
- graphModel: any;
31
- cancelCallback: any;
32
- }) => void;
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
+ };
@@ -1,9 +1,39 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handleResize = exports.triggerResizeEvent = exports.updateEdgePointByAnchors = exports.recalcResizeInfo = void 0;
3
+ exports.calculateWidthAndHeight = exports.handleResize = exports.triggerResizeEvent = exports.updateEdgePointByAnchors = exports.recalcResizeInfo = 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
+ var rotate_1 = require("../algorithm/rotate");
8
+ function recalcRotatedResizeInfo(pct, resizeInfo, rotate, controlX, controlY, oldCenterX, oldCenterY, freezeWidth, freezeHeight) {
9
+ if (freezeWidth === void 0) { freezeWidth = false; }
10
+ if (freezeHeight === void 0) { freezeHeight = false; }
11
+ // 假设我们触摸的点是右下角的control
12
+ var deltaX = resizeInfo.deltaX, deltaY = resizeInfo.deltaY, oldWidth = resizeInfo.width, oldHeight = resizeInfo.height;
13
+ var angle = (0, rotate_1.radianToAngle)(rotate);
14
+ // 右下角的control
15
+ var startZeroTouchControlPoint = {
16
+ x: controlX, // control锚点的坐标x
17
+ y: controlY, // control锚点的坐标y
18
+ };
19
+ var oldCenter = { x: oldCenterX, y: oldCenterY };
20
+ // 右下角的control坐标(transform后的-touchStartPoint)
21
+ var startRotatedTouchControlPoint = (0, rotate_1.calculatePointAfterRotateAngle)(startZeroTouchControlPoint, oldCenter, angle);
22
+ // 右下角的control坐标(transform后的-touchEndPoint)
23
+ var endRotatedTouchControlPoint = {
24
+ x: startRotatedTouchControlPoint.x + deltaX,
25
+ y: startRotatedTouchControlPoint.y + deltaY,
26
+ };
27
+ // 计算出新的宽度和高度以及新的中心点
28
+ var _a = calculateWidthAndHeight(startRotatedTouchControlPoint, endRotatedTouchControlPoint, oldCenter, angle, freezeWidth, freezeHeight, oldWidth, oldHeight), newWidth = _a.width, newHeight = _a.height, newCenter = _a.center;
29
+ // calculateWidthAndHeight()得到的是整个宽度,比如圆pct=0.5,此时newWidth等于整个圆直径
30
+ resizeInfo.width = newWidth * pct;
31
+ resizeInfo.height = newHeight * pct;
32
+ // BaseNodeModel.resize(deltaX/2, deltaY/2),因此这里要*2
33
+ resizeInfo.deltaX = (newCenter.x - oldCenter.x) * 2;
34
+ resizeInfo.deltaY = (newCenter.y - oldCenter.y) * 2;
35
+ return resizeInfo;
36
+ }
7
37
  /**
8
38
  * 计算 Control 拖动后,节点的高度信息
9
39
  * @param index
@@ -12,10 +42,11 @@ var constant_1 = require("../constant");
12
42
  * @param freezeWidth
13
43
  * @param freezeHeight
14
44
  */
15
- var recalcResizeInfo = function (index, resizeInfo, pct, freezeWidth, freezeHeight) {
45
+ var recalcResizeInfo = function (index, resizeInfo, pct, freezeWidth, freezeHeight, rotate, controlX, controlY, oldCenterX, oldCenterY) {
16
46
  if (pct === void 0) { pct = 1; }
17
47
  if (freezeWidth === void 0) { freezeWidth = false; }
18
48
  if (freezeHeight === void 0) { freezeHeight = false; }
49
+ if (rotate === void 0) { rotate = 0; }
19
50
  var nextResizeInfo = (0, lodash_es_1.cloneDeep)(resizeInfo);
20
51
  var deltaX = nextResizeInfo.deltaX, deltaY = nextResizeInfo.deltaY;
21
52
  var width = nextResizeInfo.width, height = nextResizeInfo.height, PCTResizeInfo = nextResizeInfo.PCTResizeInfo;
@@ -73,6 +104,14 @@ var recalcResizeInfo = function (index, resizeInfo, pct, freezeWidth, freezeHeig
73
104
  }
74
105
  return nextResizeInfo;
75
106
  }
107
+ if (rotate % (2 * Math.PI) !== 0 &&
108
+ controlX !== undefined &&
109
+ controlY !== undefined) {
110
+ // 角度rotate不为0,则触发另外的计算修正resize的deltaX和deltaY
111
+ // 因为rotate不为0的时候,左上角的坐标一直在变化
112
+ // 角度rotate不为0得到的resizeInfo.deltaX仅仅代表中心点的变化,而不是宽度的变化
113
+ return recalcRotatedResizeInfo(pct, nextResizeInfo, rotate, controlX, controlY, oldCenterX, oldCenterY, freezeWidth, freezeHeight);
114
+ }
76
115
  // 如果限制了宽/高不变,对应的 width/height 保持一致
77
116
  switch (index) {
78
117
  case Control_1.ResizeControlIndex.LEFT_TOP:
@@ -146,17 +185,10 @@ var triggerResizeEvent = function (preNodeData, curNodeData, deltaX, deltaY, ind
146
185
  });
147
186
  };
148
187
  exports.triggerResizeEvent = triggerResizeEvent;
149
- // TODO:确认 handleResize 函数的类型定义
150
- // export type IHandleResizeParams = {
151
- // deltaX: number
152
- // deltaY: number
153
- // index: ResizeControlIndex
154
- // nodeModel: BaseNodeModel
155
- // graphModel: GraphModel
156
- // cancelCallback?: () => void
157
- // }
158
188
  /**
159
189
  * 处理节点的 resize 事件,提出来放到 utils 中,方便在外面(extension)中使用
190
+ * @param x
191
+ * @param y
160
192
  * @param deltaX
161
193
  * @param deltaY
162
194
  * @param index
@@ -165,11 +197,11 @@ exports.triggerResizeEvent = triggerResizeEvent;
165
197
  * @param cancelCallback
166
198
  */
167
199
  var handleResize = function (_a) {
168
- var deltaX = _a.deltaX, deltaY = _a.deltaY, index = _a.index, nodeModel = _a.nodeModel, graphModel = _a.graphModel, cancelCallback = _a.cancelCallback;
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;
169
201
  var r = nodeModel.r, // circle
170
202
  rx = nodeModel.rx, // ellipse/diamond
171
203
  ry = nodeModel.ry, width = nodeModel.width, // rect/html
172
- height = nodeModel.height, PCTResizeInfo = nodeModel.PCTResizeInfo, minWidth = nodeModel.minWidth, minHeight = nodeModel.minHeight, maxWidth = nodeModel.maxWidth, maxHeight = nodeModel.maxHeight;
204
+ height = nodeModel.height, PCTResizeInfo = nodeModel.PCTResizeInfo, minWidth = nodeModel.minWidth, minHeight = nodeModel.minHeight, maxWidth = nodeModel.maxWidth, maxHeight = nodeModel.maxHeight, rotate = nodeModel.rotate, oldCenterX = nodeModel.x, oldCenterY = nodeModel.y;
173
205
  var isFreezeWidth = minWidth === maxWidth;
174
206
  var isFreezeHeight = minHeight === maxHeight;
175
207
  var resizeInfo = {
@@ -180,7 +212,9 @@ var handleResize = function (_a) {
180
212
  PCTResizeInfo: PCTResizeInfo,
181
213
  };
182
214
  var pct = r || (rx && ry) ? 1 / 2 : 1;
183
- var nextSize = (0, exports.recalcResizeInfo)(index, resizeInfo, pct, isFreezeWidth, isFreezeHeight);
215
+ var controlX = x;
216
+ var controlY = y;
217
+ var nextSize = (0, exports.recalcResizeInfo)(index, resizeInfo, pct, isFreezeWidth, isFreezeHeight, rotate, controlX, controlY, oldCenterX, oldCenterY);
184
218
  // 限制放大缩小的最大最小范围
185
219
  if (nextSize.width < minWidth ||
186
220
  nextSize.width > maxWidth ||
@@ -190,14 +224,104 @@ var handleResize = function (_a) {
190
224
  cancelCallback === null || cancelCallback === void 0 ? void 0 : cancelCallback();
191
225
  return;
192
226
  }
193
- // 如果限制了宽高不变,对应的 x/y 不产生位移
194
- nextSize.deltaX = isFreezeWidth ? 0 : nextSize.deltaX;
195
- nextSize.deltaY = isFreezeWidth ? 0 : nextSize.deltaY;
227
+ if (rotate % (2 * Math.PI) == 0 ||
228
+ PCTResizeInfo ||
229
+ controlX === undefined ||
230
+ controlY === undefined) {
231
+ // rotate!==0并且不是PCTResizeInfo时,即使是isFreezeWidth||isFreezeHeight
232
+ // recalcRotatedResizeInfo()计算出来的中心点会发生变化
233
+ // 如果限制了宽高不变,对应的 x/y 不产生位移
234
+ nextSize.deltaX = isFreezeWidth ? 0 : nextSize.deltaX;
235
+ nextSize.deltaY = isFreezeHeight ? 0 : nextSize.deltaY;
236
+ }
196
237
  var preNodeData = nodeModel.getData();
197
238
  var curNodeData = nodeModel.resize(nextSize);
239
+ // 检测preNodeData和curNodeData是否没变化
240
+ if (preNodeData.x === curNodeData.x && preNodeData.y === curNodeData.y) {
241
+ // 中心点x和y都没有变化,说明无法resize,阻止下面边的更新以及resize事件的emit
242
+ return;
243
+ }
198
244
  // 更新边
199
245
  (0, exports.updateEdgePointByAnchors)(nodeModel, graphModel);
200
246
  // 触发 resize 事件
201
247
  (0, exports.triggerResizeEvent)(preNodeData, curNodeData, deltaX, deltaY, index, nodeModel, graphModel);
202
248
  };
203
249
  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;
@@ -30,6 +30,7 @@ export declare class ResizeControl extends Component<IResizeControlProps, IResiz
30
30
  readonly graphModel: GraphModel;
31
31
  readonly dragHandler: StepDrag;
32
32
  constructor(props: IResizeControlProps);
33
+ componentWillUnmount(): void;
33
34
  updateEdgePointByAnchors: () => void;
34
35
  triggerResizeEvent: (preNodeData: ResizeNodeData, curNodeData: ResizeNodeData, deltaX: any, deltaY: any, index: any, nodeModel: BaseNodeModel) => void;
35
36
  /**
@@ -213,9 +213,11 @@ var ResizeControl = /** @class */ (function (_super) {
213
213
  _this.resizeNode = function (_a) {
214
214
  var deltaX = _a.deltaX, deltaY = _a.deltaY;
215
215
  var index = _this.index;
216
- var _b = _this.props, model = _b.model, graphModel = _b.graphModel;
216
+ var _b = _this.props, model = _b.model, graphModel = _b.graphModel, x = _b.x, y = _b.y;
217
217
  // DONE: 调用每个节点中更新缩放时的方法 updateNode 函数,用来各节点缩放的方法
218
218
  (0, util_1.handleResize)({
219
+ x: x,
220
+ y: y,
219
221
  deltaX: deltaX,
220
222
  deltaY: deltaY,
221
223
  index: index,
@@ -316,6 +318,9 @@ var ResizeControl = /** @class */ (function (_super) {
316
318
  });
317
319
  return _this;
318
320
  }
321
+ ResizeControl.prototype.componentWillUnmount = function () {
322
+ this.dragHandler.cancelDrag();
323
+ };
319
324
  ResizeControl.prototype.render = function () {
320
325
  var _a = this.props, x = _a.x, y = _a.y, direction = _a.direction, model = _a.model;
321
326
  var _b = model.getResizeControlStyle(), width = _b.width, height = _b.height, restStyle = __rest(_b, ["width", "height"]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logicflow/core",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "description": "LogicFlow, help you quickly create flowcharts",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -56,6 +56,22 @@ export namespace Model {
56
56
  deltaY: number,
57
57
  ) => boolean | IsAllowMove
58
58
 
59
+ /**
60
+ * 限制节点resize规则
61
+ * model: 移动节点的 model
62
+ * deltaX: 中心点移动的 X 轴距离
63
+ * deltaY: 中心点移动的 Y 轴距离
64
+ * width: 中心点新的width
65
+ * height: 中心点新的height
66
+ */
67
+ export type NodeResizeRule = (
68
+ model: BaseNodeModel,
69
+ deltaX: number,
70
+ deltaY: number,
71
+ width: number,
72
+ height: number,
73
+ ) => boolean
74
+
59
75
  export type AdjustEdgeStartAndEndParams = {
60
76
  startPoint: LogicFlow.Point
61
77
  endPoint: LogicFlow.Point
@@ -81,10 +81,15 @@ export class GraphModel {
81
81
 
82
82
  /**
83
83
  * 节点移动规则判断
84
- * 在节点移动的时候,会出发此数组中的所有规则判断
84
+ * 在节点移动的时候,会触发此数组中的所有规则判断
85
85
  */
86
-
87
86
  nodeMoveRules: Model.NodeMoveRule[] = []
87
+ /**
88
+ * 节点resize规则判断
89
+ * 在节点resize的时候,会触发此数组中的所有规则判断
90
+ */
91
+ nodeResizeRules: Model.NodeResizeRule[] = []
92
+
88
93
  /**
89
94
  * 获取自定义连线轨迹
90
95
  */
@@ -1230,6 +1235,12 @@ export class GraphModel {
1230
1235
  }
1231
1236
  }
1232
1237
 
1238
+ addNodeResizeRules(fn: Model.NodeResizeRule) {
1239
+ if (!this.nodeResizeRules.includes(fn)) {
1240
+ this.nodeResizeRules.push(fn)
1241
+ }
1242
+ }
1243
+
1233
1244
  /**
1234
1245
  * 设置默认的边类型
1235
1246
  * 也就是设置在节点直接有用户手动绘制的连线类型。
@@ -148,6 +148,7 @@ export class BaseNodeModel<P extends PropertiesType = PropertiesType>
148
148
  targetRules: Model.ConnectRule[] = []
149
149
  sourceRules: Model.ConnectRule[] = []
150
150
  moveRules: Model.NodeMoveRule[] = [] // 节点移动之前的hook
151
+ resizeRules: Model.NodeResizeRule[] = [] // 节点resize之前的hook
151
152
  hasSetTargetRules = false // 用来限制rules的重复值
152
153
  hasSetSourceRules = false; // 用来限制rules的重复值
153
154
  [propName: string]: any // 支持用户自定义属性
@@ -281,6 +282,13 @@ export class BaseNodeModel<P extends PropertiesType = PropertiesType>
281
282
  */
282
283
  resize(resizeInfo: ResizeInfo): ResizeNodeData {
283
284
  const { width, height, deltaX, deltaY } = resizeInfo
285
+
286
+ const isAllowResize = this.isAllowResizeNode(deltaX, deltaY, width, height)
287
+
288
+ if (!isAllowResize) {
289
+ return this.getData()
290
+ }
291
+
284
292
  // 移动节点以及文本内容
285
293
  this.move(deltaX / 2, deltaY / 2)
286
294
 
@@ -761,6 +769,30 @@ export class BaseNodeModel<P extends PropertiesType = PropertiesType>
761
769
  }
762
770
  }
763
771
 
772
+ @action addNodeResizeRules(fn: Model.NodeResizeRule) {
773
+ if (!this.resizeRules.includes(fn)) {
774
+ this.resizeRules.push(fn)
775
+ }
776
+ }
777
+
778
+ /**
779
+ * 内部方法
780
+ * 是否允许resize节点到新的位置
781
+ */
782
+ isAllowResizeNode(
783
+ deltaX: number,
784
+ deltaY: number,
785
+ width: number,
786
+ height: number,
787
+ ): boolean {
788
+ const rules = this.resizeRules.concat(this.graphModel.nodeResizeRules)
789
+ for (const rule of rules) {
790
+ const r = rule(this, deltaX, deltaY, width, height)
791
+ if (!r) return false
792
+ }
793
+ return true
794
+ }
795
+
764
796
  @action setSelected(flag = true): void {
765
797
  this.isSelected = flag
766
798
  }
@@ -386,6 +386,12 @@ export const handleResize = ({
386
386
  const preNodeData = nodeModel.getData()
387
387
  const curNodeData = nodeModel.resize(nextSize)
388
388
 
389
+ // 检测preNodeData和curNodeData是否没变化
390
+ if (preNodeData.x === curNodeData.x && preNodeData.y === curNodeData.y) {
391
+ // 中心点x和y都没有变化,说明无法resize,阻止下面边的更新以及resize事件的emit
392
+ return
393
+ }
394
+
389
395
  // 更新边
390
396
  updateEdgePointByAnchors(nodeModel, graphModel)
391
397
  // 触发 resize 事件
@@ -417,7 +423,7 @@ export function calculateWidthAndHeight(
417
423
  y: oldCenter.y - (startRotatedTouchControlPoint.y - oldCenter.y),
418
424
  }
419
425
  // 【touchEndPoint】右下角 + freezePoint左上角 计算出新的中心点
420
- let newCenter = getNewCenter(freezePoint, endRotatedTouchControlPoint)
426
+ const newCenter = getNewCenter(freezePoint, endRotatedTouchControlPoint)
421
427
 
422
428
  // 得到【touchEndPoint】右下角-没有transform的坐标
423
429
  let endZeroTouchControlPoint: SimplePoint = calculatePointAfterRotateAngle(