@formily-design/shared 1.0.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.
Files changed (98) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +1 -0
  3. package/dist/designable.shared.umd.production.js +1 -0
  4. package/dist/designable.shared.umd.production.min.js +2051 -0
  5. package/esm/animation.d.ts +2 -0
  6. package/esm/animation.js +33 -0
  7. package/esm/array.d.ts +37 -0
  8. package/esm/array.js +111 -0
  9. package/esm/clone.d.ts +4 -0
  10. package/esm/clone.js +97 -0
  11. package/esm/compose.d.ts +1 -0
  12. package/esm/compose.js +7 -0
  13. package/esm/coordinate.d.ts +106 -0
  14. package/esm/coordinate.js +475 -0
  15. package/esm/element.d.ts +6 -0
  16. package/esm/element.js +137 -0
  17. package/esm/event.d.ts +96 -0
  18. package/esm/event.js +213 -0
  19. package/esm/globalThisPolyfill.d.ts +1 -0
  20. package/esm/globalThisPolyfill.js +22 -0
  21. package/esm/index.d.ts +17 -0
  22. package/esm/index.js +17 -0
  23. package/esm/instanceof.d.ts +1 -0
  24. package/esm/instanceof.js +11 -0
  25. package/esm/keycode.d.ts +147 -0
  26. package/esm/keycode.js +150 -0
  27. package/esm/lru.d.ts +73 -0
  28. package/esm/lru.js +293 -0
  29. package/esm/observer.d.ts +9 -0
  30. package/esm/observer.js +29 -0
  31. package/esm/request-idle.d.ts +10 -0
  32. package/esm/request-idle.js +8 -0
  33. package/esm/scroller.d.ts +10 -0
  34. package/esm/scroller.js +82 -0
  35. package/esm/subscribable.d.ts +14 -0
  36. package/esm/subscribable.js +48 -0
  37. package/esm/types.d.ts +13 -0
  38. package/esm/types.js +21 -0
  39. package/esm/uid.d.ts +1 -0
  40. package/esm/uid.js +9 -0
  41. package/lib/animation.d.ts +2 -0
  42. package/lib/animation.js +38 -0
  43. package/lib/array.d.ts +37 -0
  44. package/lib/array.js +125 -0
  45. package/lib/clone.d.ts +4 -0
  46. package/lib/clone.js +102 -0
  47. package/lib/compose.d.ts +1 -0
  48. package/lib/compose.js +11 -0
  49. package/lib/coordinate.d.ts +106 -0
  50. package/lib/coordinate.js +504 -0
  51. package/lib/element.d.ts +6 -0
  52. package/lib/element.js +145 -0
  53. package/lib/event.d.ts +96 -0
  54. package/lib/event.js +218 -0
  55. package/lib/globalThisPolyfill.d.ts +1 -0
  56. package/lib/globalThisPolyfill.js +25 -0
  57. package/lib/index.d.ts +17 -0
  58. package/lib/index.js +33 -0
  59. package/lib/instanceof.d.ts +1 -0
  60. package/lib/instanceof.js +15 -0
  61. package/lib/keycode.d.ts +147 -0
  62. package/lib/keycode.js +154 -0
  63. package/lib/lru.d.ts +73 -0
  64. package/lib/lru.js +297 -0
  65. package/lib/observer.d.ts +9 -0
  66. package/lib/observer.js +33 -0
  67. package/lib/request-idle.d.ts +10 -0
  68. package/lib/request-idle.js +13 -0
  69. package/lib/scroller.d.ts +10 -0
  70. package/lib/scroller.js +88 -0
  71. package/lib/subscribable.d.ts +14 -0
  72. package/lib/subscribable.js +52 -0
  73. package/lib/types.d.ts +13 -0
  74. package/lib/types.js +29 -0
  75. package/lib/uid.d.ts +1 -0
  76. package/lib/uid.js +12 -0
  77. package/package.json +32 -0
  78. package/rollup.config.js +3 -0
  79. package/src/animation.ts +38 -0
  80. package/src/array.ts +301 -0
  81. package/src/clone.ts +96 -0
  82. package/src/compose.ts +7 -0
  83. package/src/coordinate.ts +633 -0
  84. package/src/element.ts +144 -0
  85. package/src/event.ts +379 -0
  86. package/src/globalThisPolyfill.ts +19 -0
  87. package/src/index.ts +17 -0
  88. package/src/instanceof.ts +10 -0
  89. package/src/keycode.ts +150 -0
  90. package/src/lru.ts +322 -0
  91. package/src/observer.ts +38 -0
  92. package/src/request-idle.ts +22 -0
  93. package/src/scroller.ts +113 -0
  94. package/src/subscribable.ts +60 -0
  95. package/src/types.ts +27 -0
  96. package/src/uid.ts +10 -0
  97. package/tsconfig.build.json +10 -0
  98. package/tsconfig.json +5 -0
@@ -0,0 +1,633 @@
1
+ import { isValidNumber } from './types'
2
+ export interface IPoint {
3
+ x: number
4
+ y: number
5
+ }
6
+
7
+ export interface ISize {
8
+ width: number
9
+ height: number
10
+ }
11
+
12
+ export interface ILineSegment {
13
+ start: IPoint
14
+ end: IPoint
15
+ }
16
+
17
+ export interface IRectEdgeLines {
18
+ v: ILineSegment[]
19
+ h: ILineSegment[]
20
+ }
21
+
22
+ export function isRect(rect: any): rect is IRect {
23
+ return rect?.x && rect?.y && rect?.width && rect?.height
24
+ }
25
+
26
+ export function isPoint(val: any): val is IPoint {
27
+ return isValidNumber(val?.x) && isValidNumber(val?.y)
28
+ }
29
+
30
+ export function isLineSegment(val: any): val is ILineSegment {
31
+ return isPoint(val?.start) && isPoint(val?.end)
32
+ }
33
+
34
+ export class Point implements IPoint {
35
+ x: number
36
+ y: number
37
+ constructor(x: number, y: number) {
38
+ this.x = x
39
+ this.y = y
40
+ }
41
+ }
42
+
43
+ export class Rect implements IRect {
44
+ x = 0
45
+ y = 0
46
+ width = 0
47
+ height = 0
48
+ constructor(x: number, y: number, width: number, height: number) {
49
+ this.x = x
50
+ this.y = y
51
+ this.width = width
52
+ this.height = height
53
+ }
54
+
55
+ get left() {
56
+ return this.x
57
+ }
58
+
59
+ get right() {
60
+ return this.x + this.width
61
+ }
62
+
63
+ get top() {
64
+ return this.y
65
+ }
66
+
67
+ get bottom() {
68
+ return this.y + this.height
69
+ }
70
+ }
71
+
72
+ export class LineSegment {
73
+ start: IPoint
74
+ end: IPoint
75
+ constructor(start: IPoint, end: IPoint) {
76
+ this.start = { ...start }
77
+ this.end = { ...end }
78
+ }
79
+ }
80
+
81
+ export interface IRect {
82
+ x: number
83
+ y: number
84
+ width: number
85
+ height: number
86
+ }
87
+
88
+ export enum RectQuadrant {
89
+ Inner1 = 'I1', //内部第一象限
90
+ Inner2 = 'I2', //内部第二象限
91
+ Inner3 = 'I3', //内部第三象限
92
+ Inner4 = 'I4', //内部第四象限
93
+ Outer1 = 'O1', //内部第五象限
94
+ Outer2 = 'O2', //内部第六象限
95
+ Outer3 = 'O3', //内部第七象限
96
+ Outer4 = 'O4', //内部第八象限
97
+ }
98
+
99
+ export interface IPointToRectRelative {
100
+ quadrant: RectQuadrant
101
+ distance: number
102
+ }
103
+
104
+ export function isPointInRect(point: IPoint, rect: IRect, sensitive = true) {
105
+ const boundSensor = (value: number) => {
106
+ if (!sensitive) return 0
107
+ const sensor = value * 0.1
108
+ if (sensor > 20) return 20
109
+ if (sensor < 10) return 10
110
+ return sensor
111
+ }
112
+
113
+ return (
114
+ point.x >= rect.x + boundSensor(rect.width) &&
115
+ point.x <= rect.x + rect.width - boundSensor(rect.width) &&
116
+ point.y >= rect.y + boundSensor(rect.height) &&
117
+ point.y <= rect.y + rect.height - boundSensor(rect.height)
118
+ )
119
+ }
120
+
121
+ export function isEqualRect(target: IRect, source: IRect) {
122
+ return (
123
+ target?.x === source?.x &&
124
+ target.y === source.y &&
125
+ target.width === source.width &&
126
+ target.height === source.height
127
+ )
128
+ }
129
+
130
+ export function getRectPoints(source: IRect) {
131
+ const p1 = new Point(source.x, source.y)
132
+ const p2 = new Point(source.x + source.width, source.y)
133
+ const p3 = new Point(source.x + source.width, source.y + source.height)
134
+ const p4 = new Point(source.x, source.y + source.height)
135
+ return [p1, p2, p3, p4]
136
+ }
137
+
138
+ export function isRectInRect(target: IRect, source: IRect) {
139
+ const [p1, p2, p3, p4] = getRectPoints(target)
140
+ return (
141
+ isPointInRect(p1, source, false) &&
142
+ isPointInRect(p2, source, false) &&
143
+ isPointInRect(p3, source, false) &&
144
+ isPointInRect(p4, source, false)
145
+ )
146
+ }
147
+
148
+ export function isCrossRectInRect(target: IRect, source: IRect) {
149
+ const targetCenterPoint = new Point(
150
+ target.x + target.width / 2,
151
+ target.y + target.height / 2
152
+ )
153
+ const sourceCenterPoint = new Point(
154
+ source.x + source.width / 2,
155
+ source.y + source.height / 2
156
+ )
157
+ return (
158
+ Math.abs(targetCenterPoint.x - sourceCenterPoint.x) <=
159
+ target.width / 2 + source.width / 2 &&
160
+ Math.abs(targetCenterPoint.y - sourceCenterPoint.y) <=
161
+ target.height / 2 + source.height / 2
162
+ )
163
+ }
164
+
165
+ /**
166
+ * 计算点在矩形的哪个象限
167
+ * @param point
168
+ * @param rect
169
+ */
170
+ export function calcQuadrantOfPointToRect(point: IPoint, rect: IRect) {
171
+ const isInner = isPointInRect(point, rect)
172
+ if (point.x <= rect.x + rect.width / 2) {
173
+ if (point.y <= rect.y + rect.height / 2) {
174
+ if (isInner) {
175
+ return RectQuadrant.Inner1
176
+ } else {
177
+ return RectQuadrant.Outer1
178
+ }
179
+ } else {
180
+ if (isInner) {
181
+ return RectQuadrant.Inner4
182
+ } else {
183
+ return RectQuadrant.Outer4
184
+ }
185
+ }
186
+ } else {
187
+ if (point.y <= rect.y + rect.height / 2) {
188
+ if (isInner) {
189
+ return RectQuadrant.Inner2
190
+ } else {
191
+ return RectQuadrant.Outer2
192
+ }
193
+ } else {
194
+ if (isInner) {
195
+ return RectQuadrant.Inner3
196
+ } else {
197
+ return RectQuadrant.Outer3
198
+ }
199
+ }
200
+ }
201
+ }
202
+
203
+ export function calcDistanceOfPointToRect(point: IPoint, rect: IRect) {
204
+ let minX = Math.min(
205
+ Math.abs(point.x - rect.x),
206
+ Math.abs(point.x - (rect.x + rect.width))
207
+ )
208
+ let minY = Math.min(
209
+ Math.abs(point.y - rect.y),
210
+ Math.abs(point.y - (rect.y + rect.height))
211
+ )
212
+ if (point.x >= rect.x && point.x <= rect.x + rect.width) {
213
+ minX = 0
214
+ }
215
+ if (point.y >= rect.y && point.y <= rect.y + rect.height) {
216
+ minY = 0
217
+ }
218
+
219
+ return Math.sqrt(minX ** 2 + minY ** 2)
220
+ }
221
+
222
+ export function calcDistancePointToEdge(point: IPoint, rect: IRect) {
223
+ const distanceTop = Math.abs(point.y - rect.y)
224
+ const distanceBottom = Math.abs(point.y - (rect.y + rect.height))
225
+ const distanceLeft = Math.abs(point.x - rect.x)
226
+ const distanceRight = Math.abs(point.x - (rect.x + rect.width))
227
+ return Math.min(distanceTop, distanceBottom, distanceLeft, distanceRight)
228
+ }
229
+
230
+ export function isNearAfter(point: IPoint, rect: IRect, inline = false) {
231
+ if (inline) {
232
+ return (
233
+ Math.abs(point.x - rect.x) + Math.abs(point.y - rect.y) >
234
+ Math.abs(point.x - (rect.x + rect.width)) +
235
+ Math.abs(point.y - (rect.y + rect.height))
236
+ )
237
+ }
238
+ return Math.abs(point.y - rect.y) > Math.abs(point.y - (rect.y + rect.height))
239
+ }
240
+
241
+ /**
242
+ * 计算点鱼矩形的相对位置信息
243
+ * @param point
244
+ * @param rect
245
+ */
246
+ export function calcRelativeOfPointToRect(
247
+ point: IPoint,
248
+ rect: IRect
249
+ ): IPointToRectRelative {
250
+ const distance = calcDistanceOfPointToRect(point, rect)
251
+ const quadrant = calcQuadrantOfPointToRect(point, rect)
252
+ return {
253
+ quadrant,
254
+ distance,
255
+ }
256
+ }
257
+
258
+ export function calcBoundingRect(rects: IRect[]) {
259
+ if (!rects?.length) return
260
+ if (rects?.length === 1 && !rects[0]) return
261
+ let minTop = Infinity
262
+ let maxBottom = -Infinity
263
+ let minLeft = Infinity
264
+ let maxRight = -Infinity
265
+ rects.forEach((item) => {
266
+ const rect = new Rect(item.x, item.y, item.width, item.height)
267
+ if (rect.top <= minTop) {
268
+ minTop = rect.top
269
+ }
270
+ if (rect.bottom >= maxBottom) {
271
+ maxBottom = rect.bottom
272
+ }
273
+ if (rect.left <= minLeft) {
274
+ minLeft = rect.left
275
+ }
276
+ if (rect.right >= maxRight) {
277
+ maxRight = rect.right
278
+ }
279
+ })
280
+ return new Rect(minLeft, minTop, maxRight - minLeft, maxBottom - minTop)
281
+ }
282
+
283
+ export function calcRectByStartEndPoint(
284
+ startPoint: IPoint,
285
+ endPoint: IPoint,
286
+ scrollX = 0,
287
+ scrollY = 0
288
+ ) {
289
+ let drawStartX = 0,
290
+ drawStartY = 0
291
+ if (
292
+ endPoint.x + scrollX >= startPoint.x &&
293
+ endPoint.y + scrollY >= startPoint.y
294
+ ) {
295
+ //4象限
296
+ drawStartX = startPoint.x
297
+ drawStartY = startPoint.y
298
+ return new Rect(
299
+ drawStartX - scrollX,
300
+ drawStartY - scrollY,
301
+ Math.abs(endPoint.x - startPoint.x + scrollX),
302
+ Math.abs(endPoint.y - startPoint.y + scrollY)
303
+ )
304
+ } else if (
305
+ endPoint.x + scrollX < startPoint.x &&
306
+ endPoint.y + scrollY < startPoint.y
307
+ ) {
308
+ //1象限
309
+ drawStartX = endPoint.x
310
+ drawStartY = endPoint.y
311
+ return new Rect(
312
+ drawStartX,
313
+ drawStartY,
314
+ Math.abs(endPoint.x - startPoint.x + scrollX),
315
+ Math.abs(endPoint.y - startPoint.y + scrollY)
316
+ )
317
+ } else if (
318
+ endPoint.x + scrollX < startPoint.x &&
319
+ endPoint.y + scrollY >= startPoint.y
320
+ ) {
321
+ //3象限
322
+ drawStartX = endPoint.x
323
+ drawStartY = startPoint.y
324
+ return new Rect(
325
+ drawStartX - scrollX,
326
+ drawStartY - scrollY,
327
+ Math.abs(endPoint.x - startPoint.x + scrollX),
328
+ Math.abs(endPoint.y - startPoint.y + scrollY)
329
+ )
330
+ } else {
331
+ //2象限
332
+ drawStartX = startPoint.x
333
+ drawStartY = endPoint.y
334
+ return new Rect(
335
+ drawStartX,
336
+ drawStartY,
337
+ Math.abs(endPoint.x - startPoint.x + scrollX),
338
+ Math.abs(endPoint.y - startPoint.y + scrollY)
339
+ )
340
+ }
341
+ }
342
+
343
+ export function calcEdgeLinesOfRect(rect: IRect): IRectEdgeLines {
344
+ return {
345
+ v: [
346
+ new LineSegment(
347
+ new Point(rect.x, rect.y),
348
+ new Point(rect.x, rect.y + rect.height)
349
+ ),
350
+ new LineSegment(
351
+ new Point(rect.x + rect.width / 2, rect.y),
352
+ new Point(rect.x + rect.width / 2, rect.y + rect.height)
353
+ ),
354
+ new LineSegment(
355
+ new Point(rect.x + rect.width, rect.y),
356
+ new Point(rect.x + rect.width, rect.y + rect.height)
357
+ ),
358
+ ],
359
+ h: [
360
+ new LineSegment(
361
+ new Point(rect.x, rect.y),
362
+ new Point(rect.x + rect.width, rect.y)
363
+ ),
364
+ new LineSegment(
365
+ new Point(rect.x, rect.y + rect.height / 2),
366
+ new Point(rect.x + rect.width, rect.y + rect.height / 2)
367
+ ),
368
+ new LineSegment(
369
+ new Point(rect.x, rect.y + rect.height),
370
+ new Point(rect.x + rect.width, rect.y + rect.height)
371
+ ),
372
+ ],
373
+ }
374
+ }
375
+
376
+ export function calcRectOfAxisLineSegment(line: ILineSegment) {
377
+ if (!isLineSegment(line)) return
378
+ const isXAxis = line.start.x === line.end.x
379
+ return new Rect(
380
+ line.start.x,
381
+ line.start.y,
382
+ isXAxis ? 0 : line.end.x - line.start.x,
383
+ isXAxis ? line.end.y - line.start.y : 0
384
+ )
385
+ }
386
+
387
+ export function calcSpaceBlockOfRect(
388
+ target: IRect,
389
+ source: IRect,
390
+ type?: string
391
+ ) {
392
+ const targetRect = new Rect(target.x, target.y, target.width, target.height)
393
+ const sourceRect = new Rect(source.x, source.y, source.width, source.height)
394
+ if (sourceRect.bottom < targetRect.top && sourceRect.left > targetRect.right)
395
+ return
396
+ if (sourceRect.top > targetRect.bottom && sourceRect.left > targetRect.right)
397
+ return
398
+ if (sourceRect.bottom < targetRect.top && sourceRect.right < targetRect.left)
399
+ return
400
+ if (sourceRect.top > targetRect.bottom && sourceRect.right < targetRect.left)
401
+ return
402
+ if (sourceRect.bottom < targetRect.top) {
403
+ const distance = targetRect.top - sourceRect.bottom
404
+ const left = Math.min(sourceRect.left, targetRect.left)
405
+ const right = Math.max(sourceRect.right, targetRect.right)
406
+ if (type && type !== 'top') return
407
+ return {
408
+ type: 'top',
409
+ distance,
410
+ rect: new Rect(left, sourceRect.bottom, right - left, distance),
411
+ }
412
+ } else if (sourceRect.top > targetRect.bottom) {
413
+ const distance = sourceRect.top - targetRect.bottom
414
+ const left = Math.min(sourceRect.left, targetRect.left)
415
+ const right = Math.max(sourceRect.right, targetRect.right)
416
+ if (type && type !== 'bottom') return
417
+ return {
418
+ type: 'bottom',
419
+ distance,
420
+ rect: new Rect(left, targetRect.bottom, right - left, distance),
421
+ }
422
+ } else if (sourceRect.right < targetRect.left) {
423
+ const distance = targetRect.left - sourceRect.right
424
+ const top = Math.min(sourceRect.top, targetRect.top)
425
+ const bottom = Math.max(sourceRect.bottom, targetRect.bottom)
426
+ if (type && type !== 'left') return
427
+ return {
428
+ type: 'left',
429
+ distance,
430
+ rect: new Rect(sourceRect.right, top, distance, bottom - top),
431
+ }
432
+ } else if (sourceRect.left > targetRect.right) {
433
+ const distance = sourceRect.left - targetRect.right
434
+ const top = Math.min(sourceRect.top, targetRect.top)
435
+ const bottom = Math.max(sourceRect.bottom, targetRect.bottom)
436
+ if (type && type !== 'right') return
437
+ return {
438
+ type: 'right',
439
+ distance,
440
+ rect: new Rect(targetRect.right, top, distance, bottom - top),
441
+ }
442
+ }
443
+ }
444
+
445
+ export function calcExtendsLineSegmentOfRect(
446
+ targetRect: Rect,
447
+ referRect: Rect
448
+ ) {
449
+ if (
450
+ referRect.right < targetRect.right &&
451
+ targetRect.left <= referRect.right
452
+ ) {
453
+ //右侧
454
+ if (referRect.bottom < targetRect.top) {
455
+ //上方
456
+ return {
457
+ start: { x: referRect.right, y: referRect.bottom },
458
+ end: { x: targetRect.right, y: referRect.bottom },
459
+ }
460
+ } else if (referRect.top > targetRect.bottom) {
461
+ //下方
462
+ return {
463
+ start: { x: referRect.right, y: referRect.top },
464
+ end: { x: targetRect.right, y: referRect.top },
465
+ }
466
+ }
467
+ } else if (
468
+ referRect.left > targetRect.left &&
469
+ targetRect.right >= referRect.left
470
+ ) {
471
+ //左侧
472
+ if (referRect.bottom < targetRect.top) {
473
+ //上方
474
+ return {
475
+ start: { x: targetRect.left, y: referRect.bottom },
476
+ end: { x: referRect.left, y: referRect.bottom },
477
+ }
478
+ } else if (referRect.top > targetRect.bottom) {
479
+ //下方
480
+ return {
481
+ start: { x: targetRect.left, y: referRect.top },
482
+ end: { x: referRect.left, y: referRect.top },
483
+ }
484
+ }
485
+ }
486
+ if (referRect.top < targetRect.top && targetRect.bottom >= referRect.top) {
487
+ //refer在上方
488
+ if (referRect.right < targetRect.left) {
489
+ //右侧
490
+ return {
491
+ start: { x: referRect.right, y: referRect.bottom },
492
+ end: { x: referRect.right, y: targetRect.bottom },
493
+ }
494
+ } else if (referRect.left > targetRect.right) {
495
+ //左侧
496
+ return {
497
+ start: { x: referRect.left, y: referRect.bottom },
498
+ end: { x: referRect.left, y: targetRect.bottom },
499
+ }
500
+ }
501
+ } else if (
502
+ referRect.bottom > targetRect.bottom &&
503
+ referRect.top <= targetRect.bottom
504
+ ) {
505
+ //refer下方
506
+ if (referRect.right < targetRect.left) {
507
+ //右侧
508
+ return {
509
+ start: { x: referRect.right, y: targetRect.top },
510
+ end: { x: referRect.right, y: referRect.top },
511
+ }
512
+ } else if (referRect.left > targetRect.right) {
513
+ //左侧
514
+ return {
515
+ start: { x: referRect.left, y: targetRect.top },
516
+ end: { x: referRect.left, y: referRect.top },
517
+ }
518
+ }
519
+ }
520
+ }
521
+
522
+ export function calcOffsetOfSnapLineSegmentToEdge(
523
+ line: ILineSegment,
524
+ current: IRect
525
+ ) {
526
+ const edges = calcEdgeLinesOfRect(current)
527
+ const isVerticalLine = line.start.x === line.end.x
528
+ if (isVerticalLine) {
529
+ return { x: calcMinDistanceValue(edges.x, line.start.x) - current.x, y: 0 }
530
+ }
531
+ function calcEdgeLinesOfRect(rect: IRect) {
532
+ return {
533
+ x: [rect.x, rect.x + rect.width / 2, rect.x + rect.width],
534
+ y: [rect.y, rect.y + rect.height / 2, rect.y + rect.height],
535
+ }
536
+ }
537
+ function calcMinDistanceValue(edges: number[], targetValue: number) {
538
+ let minDistance = Infinity,
539
+ minDistanceIndex = -1
540
+ for (let i = 0; i < edges.length; i++) {
541
+ const distance = Math.abs(edges[i] - targetValue)
542
+ if (minDistance > distance) {
543
+ minDistance = distance
544
+ minDistanceIndex = i
545
+ }
546
+ }
547
+ return edges[minDistanceIndex]
548
+ }
549
+
550
+ return { x: 0, y: calcMinDistanceValue(edges.y, line.start.y) - current.y }
551
+ }
552
+
553
+ export function calcDistanceOfSnapLineToEdges(
554
+ line: ILineSegment,
555
+ edges: IRectEdgeLines
556
+ ) {
557
+ let distance = Infinity
558
+ if (line?.start?.y === line?.end?.y) {
559
+ edges.h.forEach((target) => {
560
+ const _distance = Math.abs(target.start.y - line.start.y)
561
+ if (_distance < distance) {
562
+ distance = _distance
563
+ }
564
+ })
565
+ } else if (line?.start?.x === line?.end?.x) {
566
+ edges.v.forEach((target) => {
567
+ const _distance = Math.abs(target.start.x - line.start.x)
568
+ if (_distance < distance) {
569
+ distance = _distance
570
+ }
571
+ })
572
+ } else {
573
+ throw new Error('can not calculate slash distance')
574
+ }
575
+ return distance
576
+ }
577
+
578
+ export function calcCombineSnapLineSegment(
579
+ target: ILineSegment,
580
+ source: ILineSegment
581
+ ): ILineSegment {
582
+ if (target.start.x === target.end.x) {
583
+ return new LineSegment(
584
+ new Point(
585
+ target.start.x,
586
+ target.start.y > source.start.y ? source.start.y : target.start.y
587
+ ),
588
+ new Point(
589
+ target.start.x,
590
+ target.end.y > source.end.y ? target.end.y : source.end.y
591
+ )
592
+ )
593
+ }
594
+
595
+ return new LineSegment(
596
+ new Point(
597
+ target.start.x > source.start.x ? source.start.x : target.start.x,
598
+ target.start.y
599
+ ),
600
+ new Point(
601
+ target.end.x > source.end.x ? target.end.x : source.end.x,
602
+ target.end.y
603
+ )
604
+ )
605
+ }
606
+
607
+ export function calcClosestEdges(
608
+ line: ILineSegment,
609
+ edges: IRectEdgeLines
610
+ ): [number, ILineSegment] {
611
+ let result: ILineSegment
612
+ let distance = Infinity
613
+ if (line?.start?.y === line?.end?.y) {
614
+ edges.h.forEach((target) => {
615
+ const _distance = Math.abs(target.start.y - line.start.y)
616
+ if (_distance < distance) {
617
+ distance = _distance
618
+ result = target
619
+ }
620
+ })
621
+ } else if (line?.start?.x === line?.end?.x) {
622
+ edges.v.forEach((target) => {
623
+ const _distance = Math.abs(target.start.x - line.start.x)
624
+ if (_distance < distance) {
625
+ distance = _distance
626
+ result = target
627
+ }
628
+ })
629
+ } else {
630
+ throw new Error('can not calculate slash distance')
631
+ }
632
+ return [distance, result]
633
+ }