@@ -19,15 +19,18 @@ export class SnaplineModel {
19
19
@observable isShowVertical : boolean
20
20
// 对齐线的中心位置,目前仅展示中心对齐的情况,后面可以考虑多种对齐策略
21
21
@observable position : Position
22
+ // 对齐线吸附触发距离阈值
23
+ epsilon : number ;
22
24
23
- constructor ( graphModel : GraphModel ) {
25
+ constructor ( graphModel : GraphModel , epsilon : number = 1 ) {
24
26
this . isShowHorizontal = false
25
27
this . isShowVertical = false
26
28
this . position = {
27
29
x : 0 ,
28
30
y : 0 ,
29
31
}
30
32
this . graphModel = graphModel
33
+ this . epsilon = epsilon
31
34
}
32
35
33
36
getStyle ( ) {
@@ -48,10 +51,10 @@ export class SnaplineModel {
48
51
const item = nodes [ i ]
49
52
// 排除当前节点
50
53
if ( item . id !== draggingNode . id ) {
51
- if ( x === item . x ) {
54
+ if ( equal ( x , item . x , this . epsilon ) ) {
52
55
isShowVertical = true
53
56
}
54
- if ( y === item . y ) {
57
+ if ( equal ( y , item . y , this . epsilon ) ) {
55
58
isShowHorizontal = true
56
59
}
57
60
// 如果水平垂直都显示,则停止循环。减少不必要的遍历
@@ -95,19 +98,20 @@ export class SnaplineModel {
95
98
// 排除当前节点
96
99
if ( item . id !== draggingNode . id ) {
97
100
const itemData = getNodeBBox ( item )
101
+
98
102
// 如果节点的最大最小Y轴坐标与节点的最大最小Y轴坐标相等,展示水平线
99
103
if (
100
- itemData . minY === draggingData ?. minY ||
101
- itemData . maxY === draggingData ?. minY
104
+ equal ( itemData . minY , draggingData ?. minY , this . epsilon ) ||
105
+ equal ( itemData . maxY , draggingData ?. minY , this . epsilon )
102
106
) {
103
107
// 找到则停止循环。减少不必要的遍历
104
108
isShowHorizontal = true
105
109
horizontalY = draggingData . minY
106
110
break
107
111
}
108
112
if (
109
- itemData . minY === draggingData ?. maxY ||
110
- itemData . maxY === draggingData ?. maxY
113
+ equal ( itemData . minY , draggingData ?. maxY , this . epsilon ) ||
114
+ equal ( itemData . maxY , draggingData ?. maxY , this . epsilon )
111
115
) {
112
116
isShowHorizontal = true
113
117
horizontalY = draggingData . maxY
@@ -145,29 +149,49 @@ export class SnaplineModel {
145
149
}
146
150
}
147
151
}
152
+
148
153
for ( let i = 0 ; i < nodes . length ; i ++ ) {
149
154
const item = nodes [ i ]
150
155
// 排除当前节点
151
156
if ( item . id !== draggingNode . id ) {
152
157
const itemData = getNodeBBox ( item )
153
- // 如果节点的最大最小X轴坐标与节点的最大最小X轴坐标相等,展示垂直线
154
- if (
155
- itemData . minX === draggingData ?. minX ||
156
- itemData . maxX === draggingData ?. minX
157
- ) {
158
- // 找到则停止循环。减少不必要的遍历
159
- isShowVertical = true
160
- verticalX = draggingData . minX
161
- break
162
- }
163
- if (
164
- itemData . minX === draggingData ?. maxX ||
165
- itemData . maxX === draggingData ?. maxX
166
- ) {
167
- isShowVertical = true
168
- verticalX = draggingData . maxX
169
- break
158
+ // 如果拖拽对象与另外的节点 x 方向靠近,将拖拽对象和鼠标的位置设置为 节点的 x 值(吸附效果)
159
+ const draggingBoundings = [ draggingData ?. minX , draggingData ?. maxX ]
160
+ const itemBoundings = [ itemData . minX , itemData . maxX ]
161
+
162
+ outerLoop: for ( let i = 0 ; i < 2 ; i ++ ) {
163
+ for ( let j = 0 ; j < 2 ; j ++ ) {
164
+ if ( equal ( draggingBoundings [ i ] , itemBoundings [ j ] , this . epsilon ) ) {
165
+ isShowVertical = true
166
+ verticalX = itemBoundings [ i ]
167
+
168
+ break outerLoop
169
+ }
170
+ }
170
171
}
172
+
173
+ // if (equal(itemData.minX, draggingData?.minX, this.epsilon)) {
174
+ // isShowVertical = true
175
+ // verticalX = draggingData.minX
176
+ // break;
177
+ // }
178
+ // if (
179
+ // equal(itemData.minX, draggingData?.minX, this.epsilon) ||
180
+ // equal(itemData.maxX, draggingData?.minX, this.epsilon)
181
+ // ) {
182
+ // // 找到则停止循环。减少不必要的遍历
183
+ // isShowVertical = true
184
+ // verticalX = draggingData.minX
185
+ // break
186
+ // }
187
+ // if (
188
+ // equal(itemData.minX, draggingData?.maxX, this.epsilon) ||
189
+ // equal(itemData.maxX, draggingData?.maxX, this.epsilon)
190
+ // ) {
191
+ // isShowVertical = true
192
+ // verticalX = draggingData.maxX
193
+ // break
194
+ // }
171
195
}
172
196
}
173
197
return {
@@ -235,4 +259,12 @@ export class SnaplineModel {
235
259
}
236
260
}
237
261
262
+ function equal ( num1 : number , num2 : number , epsilon : number ) {
263
+ if ( Math . abs ( num1 - num2 ) <= epsilon ) {
264
+ return true
265
+ } else {
266
+ return false
267
+ }
268
+ }
269
+
238
270
export default SnaplineModel
0 commit comments