@logicflow/core 2.2.0-alpha.7 → 2.2.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/package.json +6 -1
- package/.turbo/turbo-build$colon$dev.log +0 -10
- package/.turbo/turbo-build.log +0 -33
- package/CHANGELOG.md +0 -1901
- package/__tests__/algorithm/egde.test.ts +0 -131
- package/__tests__/algorithm/index.test.ts +0 -74
- package/__tests__/algorithm/outline.test.ts +0 -43
- package/__tests__/bugs/1545-spec.test.ts +0 -42
- package/__tests__/event/event.test.ts +0 -22
- package/__tests__/history/history.test.ts +0 -28
- package/__tests__/logicflow.test.ts +0 -575
- package/__tests__/model/graphmodel.test.ts +0 -87
- package/__tests__/util/compatible.test.ts +0 -48
- package/__tests__/util/edge.test.ts +0 -224
- package/__tests__/util/geometry.test.ts +0 -14
- package/__tests__/util/graph.test.ts +0 -16
- package/__tests__/util/matrix.test.ts +0 -41
- package/__tests__/util/node.test.ts +0 -68
- package/__tests__/util/sampling.test.ts +0 -12
- package/__tests__/util/vector.test.ts +0 -50
- package/__tests__/util/zIndex.test.ts +0 -10
- package/src/LogicFlow.tsx +0 -2017
- package/src/algorithm/edge.ts +0 -67
- package/src/algorithm/index.ts +0 -70
- package/src/algorithm/outline.ts +0 -77
- package/src/algorithm/rotate.ts +0 -55
- package/src/common/drag.ts +0 -219
- package/src/common/history.ts +0 -108
- package/src/common/index.ts +0 -6
- package/src/common/keyboard.ts +0 -108
- package/src/common/matrix.ts +0 -122
- package/src/common/vector.ts +0 -93
- package/src/constant/index.ts +0 -179
- package/src/constant/theme.ts +0 -708
- package/src/event/event.md +0 -66
- package/src/event/eventArgs.ts +0 -643
- package/src/event/eventEmitter.ts +0 -156
- package/src/history/index.ts +0 -119
- package/src/index.less +0 -1
- package/src/index.ts +0 -26
- package/src/keyboard/index.ts +0 -112
- package/src/keyboard/shortcut.ts +0 -200
- package/src/model/BaseModel.ts +0 -250
- package/src/model/EditConfigModel.ts +0 -334
- package/src/model/GraphModel.ts +0 -1824
- package/src/model/NestedTransformModel.ts +0 -121
- package/src/model/SnaplineModel.ts +0 -256
- package/src/model/TransformModel.ts +0 -258
- package/src/model/edge/BaseEdgeModel.ts +0 -785
- package/src/model/edge/BezierEdgeModel.ts +0 -197
- package/src/model/edge/LineEdgeModel.ts +0 -36
- package/src/model/edge/PolylineEdgeModel.ts +0 -817
- package/src/model/edge/index.ts +0 -4
- package/src/model/index.ts +0 -9
- package/src/model/node/BaseNodeModel.ts +0 -959
- package/src/model/node/CircleNodeModel.ts +0 -91
- package/src/model/node/DiamondNodeModel.ts +0 -132
- package/src/model/node/EllipseNodeModel.ts +0 -98
- package/src/model/node/HtmlNodeModel.ts +0 -64
- package/src/model/node/PolygonNodeModel.ts +0 -152
- package/src/model/node/RectNodeModel.ts +0 -69
- package/src/model/node/TextNodeModel.ts +0 -54
- package/src/model/node/index.ts +0 -8
- package/src/options.ts +0 -150
- package/src/style/index.less +0 -262
- package/src/style/raw.ts +0 -221
- package/src/tool/MultipleSelectTool.tsx +0 -140
- package/src/tool/TextEditTool.tsx +0 -193
- package/src/tool/index.ts +0 -101
- package/src/typings.d.ts +0 -5
- package/src/util/animation.ts +0 -29
- package/src/util/browser.ts +0 -4
- package/src/util/compatible.ts +0 -15
- package/src/util/drag.ts +0 -219
- package/src/util/edge.ts +0 -1094
- package/src/util/geometry.ts +0 -154
- package/src/util/graph.ts +0 -46
- package/src/util/index.ts +0 -17
- package/src/util/matrix.ts +0 -129
- package/src/util/mobx.ts +0 -23
- package/src/util/node.ts +0 -543
- package/src/util/raf.ts +0 -28
- package/src/util/resize.ts +0 -606
- package/src/util/sampling.ts +0 -85
- package/src/util/theme.ts +0 -84
- package/src/util/uuid.ts +0 -26
- package/src/util/vector.ts +0 -93
- package/src/util/zIndex.ts +0 -6
- package/src/view/Anchor.tsx +0 -462
- package/src/view/Control.tsx +0 -510
- package/src/view/Graph.tsx +0 -141
- package/src/view/Rotate.tsx +0 -113
- package/src/view/behavior/dnd.ts +0 -162
- package/src/view/behavior/index.ts +0 -2
- package/src/view/behavior/snapline.ts +0 -16
- package/src/view/edge/AdjustPoint.tsx +0 -425
- package/src/view/edge/Arrow.tsx +0 -54
- package/src/view/edge/BaseEdge.tsx +0 -660
- package/src/view/edge/BezierEdge.tsx +0 -101
- package/src/view/edge/LineEdge.tsx +0 -81
- package/src/view/edge/PolylineEdge.tsx +0 -311
- package/src/view/edge/index.ts +0 -6
- package/src/view/index.ts +0 -8
- package/src/view/node/BaseNode.tsx +0 -585
- package/src/view/node/CircleNode.tsx +0 -21
- package/src/view/node/DiamondNode.tsx +0 -24
- package/src/view/node/EllipseNode.tsx +0 -22
- package/src/view/node/HtmlNode.tsx +0 -112
- package/src/view/node/PolygonNode.tsx +0 -28
- package/src/view/node/RectNode.tsx +0 -30
- package/src/view/node/TextNode.tsx +0 -39
- package/src/view/node/index.ts +0 -8
- package/src/view/overlay/BackgroundOverlay.tsx +0 -34
- package/src/view/overlay/BezierAdjustOverlay.tsx +0 -150
- package/src/view/overlay/CanvasOverlay.tsx +0 -290
- package/src/view/overlay/Grid.tsx +0 -319
- package/src/view/overlay/ModificationOverlay.tsx +0 -31
- package/src/view/overlay/OutlineOverlay.tsx +0 -158
- package/src/view/overlay/SnaplineOverlay.tsx +0 -44
- package/src/view/overlay/ToolOverlay.tsx +0 -65
- package/src/view/overlay/getTransformHoc.tsx +0 -50
- package/src/view/overlay/gridConfig.ts +0 -103
- package/src/view/overlay/index.ts +0 -8
- package/src/view/shape/Circle.tsx +0 -41
- package/src/view/shape/Ellipse.tsx +0 -42
- package/src/view/shape/Line.tsx +0 -39
- package/src/view/shape/Path.tsx +0 -22
- package/src/view/shape/Polygon.tsx +0 -54
- package/src/view/shape/Polyline.tsx +0 -31
- package/src/view/shape/Rect.tsx +0 -44
- package/src/view/shape/Text.tsx +0 -168
- package/src/view/shape/index.ts +0 -8
- package/src/view/text/BaseText.tsx +0 -134
- package/src/view/text/LineText.tsx +0 -168
- package/src/view/text/index.ts +0 -2
- package/stats.html +0 -4842
- package/tsconfig.json +0 -18
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import LogicFlow from '../LogicFlow'
|
|
2
|
-
import { TransformModel } from './TransformModel'
|
|
3
|
-
import { Options as LFOptions } from '../options'
|
|
4
|
-
import EventEmitter from '../event/eventEmitter'
|
|
5
|
-
type PointTuple = LogicFlow.PointTuple
|
|
6
|
-
|
|
7
|
-
export class NestedTransformModel extends TransformModel {
|
|
8
|
-
parentTransform?: TransformModel
|
|
9
|
-
|
|
10
|
-
constructor(eventCenter: EventEmitter, options: LFOptions.Common) {
|
|
11
|
-
super(eventCenter, options)
|
|
12
|
-
this.parentTransform = options.parentTransform
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* 设置父级变换
|
|
17
|
-
* @param parentTransform 父级变换模型
|
|
18
|
-
*/
|
|
19
|
-
setParentTransform(parentTransform: TransformModel) {
|
|
20
|
-
this.parentTransform = parentTransform
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* 获取累积的缩放值
|
|
25
|
-
* 计算包括所有父级的累积缩放
|
|
26
|
-
*/
|
|
27
|
-
private getCumulativeScale(): { scaleX: number; scaleY: number } {
|
|
28
|
-
let scaleX = this.SCALE_X
|
|
29
|
-
let scaleY = this.SCALE_Y
|
|
30
|
-
|
|
31
|
-
if (this.parentTransform) {
|
|
32
|
-
if (this.parentTransform instanceof NestedTransformModel) {
|
|
33
|
-
const parentScale = this.parentTransform.getCumulativeScale()
|
|
34
|
-
scaleX *= parentScale.scaleX
|
|
35
|
-
scaleY *= parentScale.scaleY
|
|
36
|
-
} else {
|
|
37
|
-
scaleX *= this.parentTransform.SCALE_X
|
|
38
|
-
scaleY *= this.parentTransform.SCALE_Y
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return { scaleX, scaleY }
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* 获取累积的平移值
|
|
47
|
-
* 计算包括所有父级的累积平移
|
|
48
|
-
*/
|
|
49
|
-
private getCumulativeTranslate(): { translateX: number; translateY: number } {
|
|
50
|
-
let translateX = this.TRANSLATE_X
|
|
51
|
-
let translateY = this.TRANSLATE_Y
|
|
52
|
-
|
|
53
|
-
if (
|
|
54
|
-
this.parentTransform &&
|
|
55
|
-
this.parentTransform instanceof NestedTransformModel
|
|
56
|
-
) {
|
|
57
|
-
const { scaleX, scaleY } = this.parentTransform.getCumulativeScale()
|
|
58
|
-
translateX = scaleX * translateX
|
|
59
|
-
translateY = scaleY * translateY
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return { translateX, translateY }
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* 将最外层graph上的点基于缩放转换为canvasOverlay层上的点。
|
|
67
|
-
* 重写以支持嵌套变换
|
|
68
|
-
* @param point HTML点
|
|
69
|
-
*/
|
|
70
|
-
HtmlPointToCanvasPoint(point: PointTuple): PointTuple {
|
|
71
|
-
const [x, y] = point
|
|
72
|
-
const { scaleX, scaleY } = this.getCumulativeScale()
|
|
73
|
-
const { translateX, translateY } = this.getCumulativeTranslate()
|
|
74
|
-
|
|
75
|
-
return [(x - translateX) / scaleX, (y - translateY) / scaleY]
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* 将最外层canvasOverlay层上的点基于缩放转换为graph上的点。
|
|
80
|
-
* 重写以支持嵌套变换
|
|
81
|
-
* @param point Canvas点
|
|
82
|
-
*/
|
|
83
|
-
CanvasPointToHtmlPoint(point: PointTuple): PointTuple {
|
|
84
|
-
const [x, y] = point
|
|
85
|
-
const { scaleX, scaleY } = this.getCumulativeScale()
|
|
86
|
-
const { translateX, translateY } = this.getCumulativeTranslate()
|
|
87
|
-
|
|
88
|
-
return [x * scaleX + translateX, y * scaleY + translateY]
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* 将一个在canvas上的点,向x轴方向移动directionX距离,向y轴方向移动directionY距离。
|
|
93
|
-
* 重写以支持嵌套变换
|
|
94
|
-
* @param point 点
|
|
95
|
-
* @param directionX x轴距离
|
|
96
|
-
* @param directionY y轴距离
|
|
97
|
-
*/
|
|
98
|
-
moveCanvasPointByHtml(
|
|
99
|
-
point: PointTuple,
|
|
100
|
-
directionX: number,
|
|
101
|
-
directionY: number,
|
|
102
|
-
): PointTuple {
|
|
103
|
-
const [x, y] = point
|
|
104
|
-
const { scaleX, scaleY } = this.getCumulativeScale()
|
|
105
|
-
|
|
106
|
-
return [x + directionX / scaleX, y + directionY / scaleY]
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* 根据缩放情况,获取缩放后的delta距离
|
|
111
|
-
* 重写以支持嵌套变换
|
|
112
|
-
* @param deltaX x轴距离变化
|
|
113
|
-
* @param deltaY y轴距离变化
|
|
114
|
-
*/
|
|
115
|
-
fixDeltaXY(deltaX: number, deltaY: number): PointTuple {
|
|
116
|
-
const { scaleX, scaleY } = this.getCumulativeScale()
|
|
117
|
-
return [deltaX / scaleX, deltaY / scaleY]
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export default NestedTransformModel
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import { action, observable } from 'mobx'
|
|
2
|
-
import { GraphModel, BaseNodeModel } from '.'
|
|
3
|
-
import LogicFlow from '../LogicFlow'
|
|
4
|
-
import { getNodeBBox } from '../util'
|
|
5
|
-
import Position = LogicFlow.Position
|
|
6
|
-
import NodeData = LogicFlow.NodeData
|
|
7
|
-
|
|
8
|
-
export type ISnaplineInfo = {
|
|
9
|
-
isShowHorizontal: boolean
|
|
10
|
-
isShowVertical: boolean
|
|
11
|
-
position: Position
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class SnaplineModel {
|
|
15
|
-
graphModel: GraphModel
|
|
16
|
-
// 是否展示水平对齐线
|
|
17
|
-
@observable isShowHorizontal: boolean
|
|
18
|
-
// 是否展示垂直对齐线
|
|
19
|
-
@observable isShowVertical: boolean
|
|
20
|
-
// 对齐线的中心位置,目前仅展示中心对齐的情况,后面可以考虑多种对齐策略
|
|
21
|
-
@observable position: Position
|
|
22
|
-
// 对齐线显示的阈值距离
|
|
23
|
-
epsilon: number
|
|
24
|
-
|
|
25
|
-
constructor(graphModel: GraphModel, epsilon: number = 1) {
|
|
26
|
-
this.isShowHorizontal = false
|
|
27
|
-
this.isShowVertical = false
|
|
28
|
-
this.position = {
|
|
29
|
-
x: 0,
|
|
30
|
-
y: 0,
|
|
31
|
-
}
|
|
32
|
-
this.graphModel = graphModel
|
|
33
|
-
this.epsilon = epsilon
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
getStyle() {
|
|
37
|
-
return {
|
|
38
|
-
...this.graphModel.theme.snapline,
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// 计算节点中心线与其他节点的对齐信息
|
|
43
|
-
private getCenterSnapLine(
|
|
44
|
-
draggingNode: NodeData,
|
|
45
|
-
nodes: BaseNodeModel[],
|
|
46
|
-
): ISnaplineInfo {
|
|
47
|
-
const { x, y } = draggingNode
|
|
48
|
-
let isShowVertical = false
|
|
49
|
-
let isShowHorizontal = false
|
|
50
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
51
|
-
const item = nodes[i]
|
|
52
|
-
// 排除当前节点
|
|
53
|
-
if (item.id !== draggingNode.id) {
|
|
54
|
-
if (equal(x, item.x, this.epsilon)) {
|
|
55
|
-
isShowVertical = true
|
|
56
|
-
}
|
|
57
|
-
if (equal(y, item.y, this.epsilon)) {
|
|
58
|
-
isShowHorizontal = true
|
|
59
|
-
}
|
|
60
|
-
// 如果水平垂直都显示,则停止循环。减少不必要的遍历
|
|
61
|
-
if (isShowVertical && isShowHorizontal) {
|
|
62
|
-
break
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return {
|
|
67
|
-
isShowVertical,
|
|
68
|
-
isShowHorizontal,
|
|
69
|
-
position: {
|
|
70
|
-
x,
|
|
71
|
-
y,
|
|
72
|
-
},
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// 计算节点上下边框与其他节点的上下边框的对齐信息
|
|
77
|
-
private getHorizontalSnapline(
|
|
78
|
-
draggingNode: NodeData,
|
|
79
|
-
nodes: BaseNodeModel[],
|
|
80
|
-
): ISnaplineInfo {
|
|
81
|
-
let isShowHorizontal = false
|
|
82
|
-
let horizontalY: number = 0
|
|
83
|
-
const { id } = draggingNode
|
|
84
|
-
let draggingData
|
|
85
|
-
if (id) {
|
|
86
|
-
const { fakeNode } = this.graphModel
|
|
87
|
-
if (fakeNode && fakeNode.id === id) {
|
|
88
|
-
draggingData = getNodeBBox(fakeNode)
|
|
89
|
-
} else {
|
|
90
|
-
const nodeModel = this.graphModel.getNodeModelById(id)
|
|
91
|
-
if (nodeModel) {
|
|
92
|
-
draggingData = getNodeBBox(nodeModel)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
97
|
-
const item = nodes[i]
|
|
98
|
-
// 排除当前节点
|
|
99
|
-
if (item.id !== draggingNode.id) {
|
|
100
|
-
const itemData = getNodeBBox(item)
|
|
101
|
-
|
|
102
|
-
// 如果节点的最大最小Y轴坐标与节点的最大最小Y轴坐标相等,展示水平线
|
|
103
|
-
if (
|
|
104
|
-
equal(itemData.minY, draggingData?.minY, this.epsilon) ||
|
|
105
|
-
equal(itemData.maxY, draggingData?.minY, this.epsilon)
|
|
106
|
-
) {
|
|
107
|
-
// 找到则停止循环。减少不必要的遍历
|
|
108
|
-
isShowHorizontal = true
|
|
109
|
-
horizontalY = draggingData.minY
|
|
110
|
-
break
|
|
111
|
-
}
|
|
112
|
-
if (
|
|
113
|
-
equal(itemData.minY, draggingData?.maxY, this.epsilon) ||
|
|
114
|
-
equal(itemData.maxY, draggingData?.maxY, this.epsilon)
|
|
115
|
-
) {
|
|
116
|
-
isShowHorizontal = true
|
|
117
|
-
horizontalY = draggingData.maxY
|
|
118
|
-
break
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return {
|
|
123
|
-
isShowHorizontal,
|
|
124
|
-
isShowVertical: this.isShowVertical,
|
|
125
|
-
position: {
|
|
126
|
-
...this.position,
|
|
127
|
-
y: horizontalY,
|
|
128
|
-
},
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// 计算节点左右边框与其他节点的左右边框的对齐信息
|
|
133
|
-
private getVerticalSnapline(
|
|
134
|
-
draggingNode: NodeData,
|
|
135
|
-
nodes: BaseNodeModel[],
|
|
136
|
-
): ISnaplineInfo {
|
|
137
|
-
let isShowVertical: boolean = false
|
|
138
|
-
let verticalX: number = 0
|
|
139
|
-
const { id } = draggingNode
|
|
140
|
-
let draggingData
|
|
141
|
-
if (id) {
|
|
142
|
-
const { fakeNode } = this.graphModel
|
|
143
|
-
if (fakeNode && fakeNode.id === id) {
|
|
144
|
-
draggingData = getNodeBBox(fakeNode)
|
|
145
|
-
} else {
|
|
146
|
-
const nodeModel = this.graphModel.getNodeModelById(id)
|
|
147
|
-
if (nodeModel) {
|
|
148
|
-
draggingData = getNodeBBox(nodeModel)
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
154
|
-
const item = nodes[i]
|
|
155
|
-
// 排除当前节点
|
|
156
|
-
if (item.id !== draggingNode.id) {
|
|
157
|
-
const itemData = getNodeBBox(item)
|
|
158
|
-
// 如果节点的最大最小X轴坐标与节点的最大最小X轴坐标相等,展示垂直线
|
|
159
|
-
if (equal(itemData.minX, draggingData?.minX, this.epsilon)) {
|
|
160
|
-
isShowVertical = true
|
|
161
|
-
verticalX = draggingData.minX
|
|
162
|
-
break
|
|
163
|
-
}
|
|
164
|
-
if (
|
|
165
|
-
equal(itemData.minX, draggingData?.minX, this.epsilon) ||
|
|
166
|
-
equal(itemData.maxX, draggingData?.minX, this.epsilon)
|
|
167
|
-
) {
|
|
168
|
-
// 找到则停止循环。减少不必要的遍历
|
|
169
|
-
isShowVertical = true
|
|
170
|
-
verticalX = draggingData.minX
|
|
171
|
-
break
|
|
172
|
-
}
|
|
173
|
-
if (
|
|
174
|
-
equal(itemData.minX, draggingData?.maxX, this.epsilon) ||
|
|
175
|
-
equal(itemData.maxX, draggingData?.maxX, this.epsilon)
|
|
176
|
-
) {
|
|
177
|
-
isShowVertical = true
|
|
178
|
-
verticalX = draggingData.maxX
|
|
179
|
-
break
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return {
|
|
184
|
-
isShowHorizontal: this.isShowHorizontal,
|
|
185
|
-
isShowVertical,
|
|
186
|
-
position: {
|
|
187
|
-
...this.position,
|
|
188
|
-
x: verticalX,
|
|
189
|
-
},
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// 计算节点与其他节点的对齐信息
|
|
194
|
-
getSnapLinePosition(
|
|
195
|
-
draggingNode: NodeData,
|
|
196
|
-
nodes: BaseNodeModel[],
|
|
197
|
-
): ISnaplineInfo {
|
|
198
|
-
const snaplineInfo = this.getCenterSnapLine(draggingNode, nodes)
|
|
199
|
-
const { isShowHorizontal, isShowVertical } = snaplineInfo
|
|
200
|
-
// 中心对齐优先级最高
|
|
201
|
-
// 如果没有中心坐标的水平对齐,计算上下边框的对齐
|
|
202
|
-
if (!isShowHorizontal) {
|
|
203
|
-
const horizontalSnapline = this.getHorizontalSnapline(draggingNode, nodes)
|
|
204
|
-
if (horizontalSnapline.isShowHorizontal) {
|
|
205
|
-
snaplineInfo.isShowHorizontal = horizontalSnapline.isShowHorizontal
|
|
206
|
-
snaplineInfo.position.y = horizontalSnapline.position.y
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
// 如果没有中心坐标的垂直对齐,计算左右边框的对齐
|
|
210
|
-
if (!isShowVertical) {
|
|
211
|
-
const verticalSnapline = this.getVerticalSnapline(draggingNode, nodes)
|
|
212
|
-
if (verticalSnapline.isShowVertical) {
|
|
213
|
-
snaplineInfo.isShowVertical = verticalSnapline.isShowVertical
|
|
214
|
-
snaplineInfo.position.x = verticalSnapline.position.x
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return snaplineInfo
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// 设置对齐信息
|
|
221
|
-
private setSnaplineInfo(snaplineInfo: ISnaplineInfo): void {
|
|
222
|
-
const { isShowHorizontal, isShowVertical, position } = snaplineInfo
|
|
223
|
-
this.position = position
|
|
224
|
-
this.isShowHorizontal = isShowHorizontal
|
|
225
|
-
this.isShowVertical = isShowVertical
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// 清空对齐信息,对齐线消失
|
|
229
|
-
@action
|
|
230
|
-
clearSnapline(): void {
|
|
231
|
-
this.position = {
|
|
232
|
-
x: 0,
|
|
233
|
-
y: 0,
|
|
234
|
-
}
|
|
235
|
-
this.isShowHorizontal = false
|
|
236
|
-
this.isShowVertical = false
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// 设置节点对齐线
|
|
240
|
-
@action
|
|
241
|
-
setNodeSnapLine(nodeData: NodeData): void {
|
|
242
|
-
const { nodes } = this.graphModel
|
|
243
|
-
const info = this.getSnapLinePosition(nodeData, nodes)
|
|
244
|
-
this.setSnaplineInfo(info)
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
function equal(num1: number, num2: number, epsilon: number) {
|
|
249
|
-
if (Math.abs(num1 - num2) <= epsilon) {
|
|
250
|
-
return true
|
|
251
|
-
} else {
|
|
252
|
-
return false
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
export default SnaplineModel
|
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
import { observable, action } from 'mobx'
|
|
2
|
-
import LogicFlow from '../LogicFlow'
|
|
3
|
-
import { EventType } from '../constant'
|
|
4
|
-
import { Options as LFOptions } from '../options'
|
|
5
|
-
import EventEmitter from '../event/eventEmitter'
|
|
6
|
-
|
|
7
|
-
import PointTuple = LogicFlow.PointTuple
|
|
8
|
-
|
|
9
|
-
export type ZoomParamType = boolean | number
|
|
10
|
-
|
|
11
|
-
export type TransformData = Record<
|
|
12
|
-
'SCALE_X' | 'SCALE_Y' | 'SKEW_Y' | 'SKEW_X' | 'TRANSLATE_X' | 'TRANSLATE_Y',
|
|
13
|
-
number
|
|
14
|
-
>
|
|
15
|
-
|
|
16
|
-
export type TransformType = 'zoom' | 'resetZoom' | 'translate' | 'focusOn'
|
|
17
|
-
|
|
18
|
-
export interface TransformInterface {
|
|
19
|
-
SCALE_X: number
|
|
20
|
-
SCALE_Y: number
|
|
21
|
-
SKEW_Y: number
|
|
22
|
-
SKEW_X: number
|
|
23
|
-
TRANSLATE_X: number
|
|
24
|
-
TRANSLATE_Y: number
|
|
25
|
-
ZOOM_SIZE: number
|
|
26
|
-
MINI_SCALE_SIZE: number // 缩小的最小值
|
|
27
|
-
MAX_SCALE_SIZE: number // 放大的最大值
|
|
28
|
-
|
|
29
|
-
translateLimitMinX: number
|
|
30
|
-
translateLimitMinY: number
|
|
31
|
-
translateLimitMaxX: number
|
|
32
|
-
translateLimitMaxY: number
|
|
33
|
-
|
|
34
|
-
zoom: (isZoomOut: ZoomParamType, point?: PointTuple) => string
|
|
35
|
-
HtmlPointToCanvasPoint: (point: PointTuple) => PointTuple
|
|
36
|
-
CanvasPointToHtmlPoint: (point: PointTuple) => PointTuple
|
|
37
|
-
moveCanvasPointByHtml: (point: PointTuple, x: number, y: number) => PointTuple
|
|
38
|
-
getTransformStyle: () => { transform: string }
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const translateLimitsMap = {
|
|
42
|
-
false: [-Infinity, -Infinity, Infinity, Infinity],
|
|
43
|
-
true: [-Infinity, -Infinity, Infinity, Infinity],
|
|
44
|
-
vertical: [-Infinity, 0, Infinity, 0],
|
|
45
|
-
horizontal: [0, -Infinity, 0, Infinity],
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export class TransformModel implements TransformInterface {
|
|
49
|
-
MINI_SCALE_SIZE = 0.2 // 缩小的最小值
|
|
50
|
-
MAX_SCALE_SIZE = 16 // 放大的最大值
|
|
51
|
-
@observable SCALE_X = 1 // x轴缩放比例
|
|
52
|
-
@observable SKEW_Y = 0 // y轴倾斜角度
|
|
53
|
-
@observable SKEW_X = 0 // x轴倾斜角度
|
|
54
|
-
@observable SCALE_Y = 1 // y轴缩放比例
|
|
55
|
-
@observable TRANSLATE_X = 0 // x轴平移距离
|
|
56
|
-
@observable TRANSLATE_Y = 0 // y轴平移距离
|
|
57
|
-
@observable ZOOM_SIZE = 0.04 // 缩放比例变化量
|
|
58
|
-
eventCenter: EventEmitter
|
|
59
|
-
|
|
60
|
-
// 限制画布可移动区域
|
|
61
|
-
translateLimitMinX: number = -Infinity
|
|
62
|
-
translateLimitMinY: number = -Infinity
|
|
63
|
-
translateLimitMaxX: number = Infinity
|
|
64
|
-
translateLimitMaxY: number = Infinity
|
|
65
|
-
|
|
66
|
-
constructor(eventCenter: EventEmitter, options: LFOptions.Common) {
|
|
67
|
-
this.eventCenter = eventCenter
|
|
68
|
-
const { stopMoveGraph = false } = options
|
|
69
|
-
this.updateTranslateLimits(stopMoveGraph)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
setZoomMiniSize(size: number): void {
|
|
73
|
-
this.MINI_SCALE_SIZE = size
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
setZoomMaxSize(size: number): void {
|
|
77
|
-
this.MAX_SCALE_SIZE = size
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* 将最外层graph上的点基于缩放转换为canvasOverlay层上的点。
|
|
82
|
-
* @param point HTML点
|
|
83
|
-
*/
|
|
84
|
-
HtmlPointToCanvasPoint(point: PointTuple): PointTuple {
|
|
85
|
-
const [x, y] = point
|
|
86
|
-
return [
|
|
87
|
-
(x - this.TRANSLATE_X) / this.SCALE_X,
|
|
88
|
-
(y - this.TRANSLATE_Y) / this.SCALE_Y,
|
|
89
|
-
]
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* 将最外层canvasOverlay层上的点基于缩放转换为graph上的点。
|
|
94
|
-
* @param point HTML点
|
|
95
|
-
*/
|
|
96
|
-
CanvasPointToHtmlPoint(point: PointTuple): PointTuple {
|
|
97
|
-
const [x, y] = point
|
|
98
|
-
return [
|
|
99
|
-
x * this.SCALE_X + this.TRANSLATE_X,
|
|
100
|
-
y * this.SCALE_Y + this.TRANSLATE_Y,
|
|
101
|
-
]
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* 将一个在canvas上的点,向x轴方向移动directionX距离,向y轴方向移动directionY距离。
|
|
106
|
-
* 因为canvas可能被缩小或者放大了,所以其在canvas层移动的距离需要计算上缩放的量。
|
|
107
|
-
* @param point 点
|
|
108
|
-
* @param directionX x轴距离
|
|
109
|
-
* @param directionY y轴距离
|
|
110
|
-
*/
|
|
111
|
-
moveCanvasPointByHtml(
|
|
112
|
-
point: PointTuple,
|
|
113
|
-
directionX: number,
|
|
114
|
-
directionY: number,
|
|
115
|
-
): PointTuple {
|
|
116
|
-
const [x, y] = point
|
|
117
|
-
return [x + directionX / this.SCALE_X, y + directionY / this.SCALE_Y]
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* 根据缩放情况,获取缩放后的delta距离
|
|
122
|
-
* @param deltaX x轴距离变化
|
|
123
|
-
* @param deltaY y轴距离变化
|
|
124
|
-
*/
|
|
125
|
-
fixDeltaXY(deltaX: number, deltaY: number): PointTuple {
|
|
126
|
-
return [deltaX / this.SCALE_X, deltaY / this.SCALE_Y]
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* 基于当前的缩放,获取画布渲染样式transform值
|
|
131
|
-
*/
|
|
132
|
-
getTransformStyle() {
|
|
133
|
-
const matrixString = [
|
|
134
|
-
this.SCALE_X,
|
|
135
|
-
this.SKEW_Y,
|
|
136
|
-
this.SKEW_X,
|
|
137
|
-
this.SCALE_Y,
|
|
138
|
-
this.TRANSLATE_X,
|
|
139
|
-
this.TRANSLATE_Y,
|
|
140
|
-
].join(',')
|
|
141
|
-
return {
|
|
142
|
-
transform: `matrix(${matrixString})`,
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* 放大缩小图形
|
|
148
|
-
* @param zoomSize 放大缩小的值,支持传入0-n之间的数字。小于1表示缩小,大于1表示放大。也支持传入true和false按照内置的刻度放大缩小
|
|
149
|
-
* @param point 缩放的原点
|
|
150
|
-
* @returns {string} -放大缩小的比例
|
|
151
|
-
*/
|
|
152
|
-
@action
|
|
153
|
-
zoom(zoomSize: ZoomParamType = false, point?: PointTuple): string {
|
|
154
|
-
let newScaleX = this.SCALE_X
|
|
155
|
-
let newScaleY = this.SCALE_Y
|
|
156
|
-
if (typeof zoomSize === 'number') {
|
|
157
|
-
newScaleX = zoomSize
|
|
158
|
-
newScaleY = zoomSize
|
|
159
|
-
} else {
|
|
160
|
-
if (zoomSize) {
|
|
161
|
-
newScaleX += this.ZOOM_SIZE
|
|
162
|
-
newScaleY += this.ZOOM_SIZE
|
|
163
|
-
} else {
|
|
164
|
-
newScaleX -= this.ZOOM_SIZE
|
|
165
|
-
newScaleY -= this.ZOOM_SIZE
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (newScaleX < this.MINI_SCALE_SIZE || newScaleX > this.MAX_SCALE_SIZE) {
|
|
170
|
-
return `${this.SCALE_X * 100}%`
|
|
171
|
-
}
|
|
172
|
-
if (point) {
|
|
173
|
-
this.TRANSLATE_X -= (newScaleX - this.SCALE_X) * point[0]
|
|
174
|
-
this.TRANSLATE_Y -= (newScaleY - this.SCALE_Y) * point[1]
|
|
175
|
-
}
|
|
176
|
-
this.SCALE_X = newScaleX
|
|
177
|
-
this.SCALE_Y = newScaleY
|
|
178
|
-
this.emitGraphTransform('zoom')
|
|
179
|
-
return `${this.SCALE_X * 100}%`
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
private emitGraphTransform(type: TransformType) {
|
|
183
|
-
this.eventCenter.emit(EventType.GRAPH_TRANSFORM, {
|
|
184
|
-
type,
|
|
185
|
-
transform: {
|
|
186
|
-
SCALE_X: this.SCALE_X,
|
|
187
|
-
SKEW_Y: this.SKEW_Y,
|
|
188
|
-
SKEW_X: this.SKEW_X,
|
|
189
|
-
SCALE_Y: this.SCALE_Y,
|
|
190
|
-
TRANSLATE_X: this.TRANSLATE_X,
|
|
191
|
-
TRANSLATE_Y: this.TRANSLATE_Y,
|
|
192
|
-
},
|
|
193
|
-
})
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
@action
|
|
197
|
-
resetZoom(): void {
|
|
198
|
-
this.SCALE_X = 1
|
|
199
|
-
this.SCALE_Y = 1
|
|
200
|
-
this.emitGraphTransform('resetZoom')
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
@action
|
|
204
|
-
translate(x: number, y: number) {
|
|
205
|
-
if (
|
|
206
|
-
this.TRANSLATE_X + x <= this.translateLimitMaxX &&
|
|
207
|
-
this.TRANSLATE_X + x >= this.translateLimitMinX
|
|
208
|
-
) {
|
|
209
|
-
this.TRANSLATE_X += x
|
|
210
|
-
}
|
|
211
|
-
if (
|
|
212
|
-
this.TRANSLATE_Y + y <= this.translateLimitMaxY &&
|
|
213
|
-
this.TRANSLATE_Y + y >= this.translateLimitMinY
|
|
214
|
-
) {
|
|
215
|
-
this.TRANSLATE_Y += y
|
|
216
|
-
}
|
|
217
|
-
this.emitGraphTransform('translate')
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* 将图形定位到画布中心
|
|
222
|
-
* @param targetX 图形当前x坐标
|
|
223
|
-
* @param targetY 图形当前y坐标
|
|
224
|
-
* @param width 画布宽
|
|
225
|
-
* @param height 画布高
|
|
226
|
-
*/
|
|
227
|
-
@action
|
|
228
|
-
focusOn(targetX: number, targetY: number, width: number, height: number) {
|
|
229
|
-
const [x, y] = this.CanvasPointToHtmlPoint([targetX, targetY])
|
|
230
|
-
const [deltaX, deltaY] = [width / 2 - x, height / 2 - y]
|
|
231
|
-
this.TRANSLATE_X += deltaX
|
|
232
|
-
this.TRANSLATE_Y += deltaY
|
|
233
|
-
this.emitGraphTransform('focusOn')
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* 更新画布可以移动范围
|
|
238
|
-
*/
|
|
239
|
-
updateTranslateLimits(
|
|
240
|
-
limit:
|
|
241
|
-
| boolean
|
|
242
|
-
| 'vertical'
|
|
243
|
-
| 'horizontal'
|
|
244
|
-
| [number, number, number, number],
|
|
245
|
-
) {
|
|
246
|
-
;[
|
|
247
|
-
this.translateLimitMinX,
|
|
248
|
-
this.translateLimitMinY,
|
|
249
|
-
this.translateLimitMaxX,
|
|
250
|
-
this.translateLimitMaxY,
|
|
251
|
-
] =
|
|
252
|
-
Array.isArray(limit) && limit.length === 4
|
|
253
|
-
? limit
|
|
254
|
-
: translateLimitsMap[limit.toString()]
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
export default TransformModel
|