@cornerstonejs/tools 1.21.1 → 1.21.2

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 (35) hide show
  1. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDown.js +1 -1
  2. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDown.js.map +1 -1
  3. package/dist/cjs/tools/MagnifyTool.js +2 -2
  4. package/dist/cjs/tools/MagnifyTool.js.map +1 -1
  5. package/dist/cjs/tools/annotation/CobbAngleTool.d.ts +31 -5
  6. package/dist/cjs/tools/annotation/CobbAngleTool.js +266 -70
  7. package/dist/cjs/tools/annotation/CobbAngleTool.js.map +1 -1
  8. package/dist/cjs/tools/base/AnnotationTool.d.ts +1 -1
  9. package/dist/cjs/tools/base/AnnotationTool.js.map +1 -1
  10. package/dist/cjs/types/ToolSpecificAnnotationTypes.d.ts +44 -0
  11. package/dist/cjs/utilities/math/angle/angleBetweenLines.d.ts +3 -1
  12. package/dist/cjs/utilities/math/angle/angleBetweenLines.js +18 -1
  13. package/dist/cjs/utilities/math/angle/angleBetweenLines.js.map +1 -1
  14. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDown.js +1 -1
  15. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDown.js.map +1 -1
  16. package/dist/esm/tools/MagnifyTool.js +2 -2
  17. package/dist/esm/tools/MagnifyTool.js.map +1 -1
  18. package/dist/esm/tools/annotation/CobbAngleTool.d.ts +31 -5
  19. package/dist/esm/tools/annotation/CobbAngleTool.js +273 -71
  20. package/dist/esm/tools/annotation/CobbAngleTool.js.map +1 -1
  21. package/dist/esm/tools/base/AnnotationTool.d.ts +1 -1
  22. package/dist/esm/tools/base/AnnotationTool.js.map +1 -1
  23. package/dist/esm/types/ToolSpecificAnnotationTypes.d.ts +44 -0
  24. package/dist/esm/utilities/math/angle/angleBetweenLines.d.ts +3 -1
  25. package/dist/esm/utilities/math/angle/angleBetweenLines.js +19 -2
  26. package/dist/esm/utilities/math/angle/angleBetweenLines.js.map +1 -1
  27. package/dist/umd/index.js +1 -1
  28. package/dist/umd/index.js.map +1 -1
  29. package/package.json +3 -3
  30. package/src/eventDispatchers/mouseEventHandlers/mouseDown.ts +1 -1
  31. package/src/tools/MagnifyTool.ts +2 -2
  32. package/src/tools/annotation/CobbAngleTool.ts +418 -98
  33. package/src/tools/base/AnnotationTool.ts +2 -1
  34. package/src/types/ToolSpecificAnnotationTypes.ts +46 -0
  35. package/src/utilities/math/angle/angleBetweenLines.ts +39 -9
@@ -23,6 +23,7 @@ import {
23
23
  drawHandles as drawHandlesSvg,
24
24
  drawLine as drawLineSvg,
25
25
  drawLinkedTextBox as drawLinkedTextBoxSvg,
26
+ drawTextBox as drawTextBoxSvg,
26
27
  } from '../../drawingSvg';
27
28
  import { state } from '../../store';
28
29
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
@@ -47,7 +48,7 @@ import {
47
48
  InteractionTypes,
48
49
  SVGDrawingHelper,
49
50
  } from '../../types';
50
- import { AngleAnnotation } from '../../types/ToolSpecificAnnotationTypes';
51
+ import { CobbAngleAnnotation } from '../../types/ToolSpecificAnnotationTypes';
51
52
  import { StyleSpecifier } from '../../types/AnnotationStyle';
52
53
 
53
54
  class CobbAngleTool extends AnnotationTool {
@@ -64,6 +65,8 @@ class CobbAngleTool extends AnnotationTool {
64
65
  movingTextBox?: boolean;
65
66
  newAnnotation?: boolean;
66
67
  hasMoved?: boolean;
68
+ isNearFirstLine?: boolean;
69
+ isNearSecondLine?: boolean;
67
70
  } | null;
68
71
  isDrawing: boolean;
69
72
  isHandleOutsideImage: boolean;
@@ -83,7 +86,7 @@ class CobbAngleTool extends AnnotationTool {
83
86
 
84
87
  this._throttledCalculateCachedStats = throttle(
85
88
  this._calculateCachedStats,
86
- 100,
89
+ 25,
87
90
  { trailing: true }
88
91
  );
89
92
  }
@@ -98,7 +101,7 @@ class CobbAngleTool extends AnnotationTool {
98
101
  */
99
102
  addNewAnnotation = (
100
103
  evt: EventTypes.MouseDownActivateEventType
101
- ): AngleAnnotation => {
104
+ ): CobbAngleAnnotation => {
102
105
  if (this.angleStartedNotYetCompleted) {
103
106
  return;
104
107
  }
@@ -192,52 +195,20 @@ class CobbAngleTool extends AnnotationTool {
192
195
  */
193
196
  isPointNearTool = (
194
197
  element: HTMLDivElement,
195
- annotation: AngleAnnotation,
198
+ annotation: CobbAngleAnnotation,
196
199
  canvasCoords: Types.Point2,
197
200
  proximity: number
198
201
  ): boolean => {
199
202
  const enabledElement = getEnabledElement(element);
200
203
  const { viewport } = enabledElement;
201
204
  const { data } = annotation;
202
- const [point1, point2, point3, point4] = data.handles.points;
203
- const canvasPoint1 = viewport.worldToCanvas(point1);
204
- const canvasPoint2 = viewport.worldToCanvas(point2);
205
- const canvasPoint3 = viewport.worldToCanvas(point3);
206
- const canvasPoint4 = viewport.worldToCanvas(point4);
207
-
208
- const line1 = {
209
- start: {
210
- x: canvasPoint1[0],
211
- y: canvasPoint1[1],
212
- },
213
- end: {
214
- x: canvasPoint2[0],
215
- y: canvasPoint2[1],
216
- },
217
- };
218
-
219
- const line2 = {
220
- start: {
221
- x: canvasPoint3[0],
222
- y: canvasPoint3[1],
223
- },
224
- end: {
225
- x: canvasPoint4[0],
226
- y: canvasPoint4[1],
227
- },
228
- };
229
-
230
- const distanceToPoint = lineSegment.distanceToPoint(
231
- [line1.start.x, line1.start.y],
232
- [line1.end.x, line1.end.y],
233
- [canvasCoords[0], canvasCoords[1]]
234
- );
235
205
 
236
- const distanceToPoint2 = lineSegment.distanceToPoint(
237
- [line2.start.x, line2.start.y],
238
- [line2.end.x, line2.end.y],
239
- [canvasCoords[0], canvasCoords[1]]
240
- );
206
+ const { distanceToPoint, distanceToPoint2 } = this.distanceToLines({
207
+ viewport,
208
+ points: data.handles.points,
209
+ canvasCoords,
210
+ proximity,
211
+ });
241
212
 
242
213
  if (distanceToPoint <= proximity || distanceToPoint2 <= proximity) {
243
214
  return true;
@@ -248,8 +219,10 @@ class CobbAngleTool extends AnnotationTool {
248
219
 
249
220
  toolSelectedCallback = (
250
221
  evt: EventTypes.MouseDownEventType,
251
- annotation: AngleAnnotation,
252
- interactionType: InteractionTypes
222
+ annotation: CobbAngleAnnotation,
223
+ interactionType: InteractionTypes,
224
+ canvasCoords: Types.Point2,
225
+ proximity = 6
253
226
  ): void => {
254
227
  const eventDetail = evt.detail;
255
228
  const { element } = eventDetail;
@@ -261,19 +234,28 @@ class CobbAngleTool extends AnnotationTool {
261
234
  this.getToolName()
262
235
  );
263
236
 
237
+ const enabledElement = getEnabledElement(element);
238
+ const { renderingEngine, viewport } = enabledElement;
239
+
240
+ const { isNearFirstLine, isNearSecondLine } = this.distanceToLines({
241
+ viewport,
242
+ points: annotation.data.handles.points,
243
+ canvasCoords,
244
+ proximity,
245
+ });
246
+
264
247
  this.editData = {
265
248
  annotation,
266
249
  viewportIdsToRender,
267
250
  movingTextBox: false,
251
+ isNearFirstLine,
252
+ isNearSecondLine,
268
253
  };
269
254
 
270
255
  this._activateModify(element);
271
256
 
272
257
  hideElementCursor(element);
273
258
 
274
- const enabledElement = getEnabledElement(element);
275
- const { renderingEngine } = enabledElement;
276
-
277
259
  triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
278
260
 
279
261
  evt.preventDefault();
@@ -281,7 +263,7 @@ class CobbAngleTool extends AnnotationTool {
281
263
 
282
264
  handleSelectedCallback(
283
265
  evt: EventTypes.MouseDownEventType,
284
- annotation: AngleAnnotation,
266
+ annotation: CobbAngleAnnotation,
285
267
  handle: ToolHandle,
286
268
  interactionType = 'mouse'
287
269
  ): void {
@@ -436,8 +418,14 @@ class CobbAngleTool extends AnnotationTool {
436
418
  const eventDetail = evt.detail;
437
419
  const { element } = eventDetail;
438
420
 
439
- const { annotation, viewportIdsToRender, handleIndex, movingTextBox } =
440
- this.editData;
421
+ const {
422
+ annotation,
423
+ viewportIdsToRender,
424
+ handleIndex,
425
+ movingTextBox,
426
+ isNearFirstLine,
427
+ isNearSecondLine,
428
+ } = this.editData;
441
429
  const { data } = annotation;
442
430
 
443
431
  if (movingTextBox) {
@@ -453,21 +441,35 @@ class CobbAngleTool extends AnnotationTool {
453
441
  worldPosition[2] += worldPosDelta[2];
454
442
 
455
443
  textBox.hasMoved = true;
456
- } else if (handleIndex === undefined) {
457
- // Drag mode - moving handle
444
+ } else if (
445
+ handleIndex === undefined &&
446
+ (isNearFirstLine || isNearSecondLine)
447
+ ) {
448
+ // select tool mode - moving annotation
458
449
  const { deltaPoints } = eventDetail as EventTypes.MouseDragEventDetail;
459
450
  const worldPosDelta = deltaPoints.world;
460
-
461
451
  const points = data.handles.points;
462
452
 
463
- points.forEach((point) => {
464
- point[0] += worldPosDelta[0];
465
- point[1] += worldPosDelta[1];
466
- point[2] += worldPosDelta[2];
467
- });
453
+ // separate the logic for moving handles to move them separately
454
+ if (isNearFirstLine) {
455
+ const firstLinePoints = [points[0], points[1]];
456
+ firstLinePoints.forEach((point) => {
457
+ point[0] += worldPosDelta[0];
458
+ point[1] += worldPosDelta[1];
459
+ point[2] += worldPosDelta[2];
460
+ });
461
+ } else if (isNearSecondLine) {
462
+ const secondLinePoints = [points[2], points[3]];
463
+ secondLinePoints.forEach((point) => {
464
+ point[0] += worldPosDelta[0];
465
+ point[1] += worldPosDelta[1];
466
+ point[2] += worldPosDelta[2];
467
+ });
468
+ }
469
+
468
470
  annotation.invalidated = true;
469
471
  } else {
470
- // Move mode - after double click, and mouse move to draw
472
+ // Drag handle mode - after double click, and mouse move to draw
471
473
  const { currentPoints } = eventDetail;
472
474
  const worldPos = currentPoints.world;
473
475
 
@@ -485,40 +487,44 @@ class CobbAngleTool extends AnnotationTool {
485
487
 
486
488
  cancel = (element: HTMLDivElement) => {
487
489
  // If it is mid-draw or mid-modify
488
- if (this.isDrawing) {
489
- this.isDrawing = false;
490
- this._deactivateDraw(element);
491
- this._deactivateModify(element);
492
- resetElementCursor(element);
490
+ if (!this.isDrawing) {
491
+ return;
492
+ }
493
493
 
494
- const { annotation, viewportIdsToRender, newAnnotation } = this.editData;
495
- const { data } = annotation;
494
+ this.isDrawing = false;
495
+ this._deactivateDraw(element);
496
+ this._deactivateModify(element);
497
+ resetElementCursor(element);
496
498
 
497
- annotation.highlighted = false;
498
- data.handles.activeHandleIndex = null;
499
+ const { annotation, viewportIdsToRender, newAnnotation } = this.editData;
500
+ const { data } = annotation;
499
501
 
500
- const enabledElement = getEnabledElement(element);
501
- const { renderingEngine } = enabledElement;
502
+ if (data.handles.points.length < 4) {
503
+ // If it is mid-draw
504
+ removeAnnotation(annotation.annotationUID);
505
+ }
502
506
 
503
- triggerAnnotationRenderForViewportIds(
504
- renderingEngine,
505
- viewportIdsToRender
506
- );
507
+ annotation.highlighted = false;
508
+ data.handles.activeHandleIndex = null;
507
509
 
508
- if (newAnnotation) {
509
- const eventType = Events.ANNOTATION_COMPLETED;
510
+ const enabledElement = getEnabledElement(element);
511
+ const { renderingEngine } = enabledElement;
510
512
 
511
- const eventDetail: AnnotationCompletedEventDetail = {
512
- annotation,
513
- };
513
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
514
514
 
515
- triggerEvent(eventTarget, eventType, eventDetail);
516
- }
515
+ if (newAnnotation) {
516
+ const eventType = Events.ANNOTATION_COMPLETED;
517
517
 
518
- this.editData = null;
519
- this.angleStartedNotYetCompleted = false;
520
- return annotation.annotationUID;
518
+ const eventDetail: AnnotationCompletedEventDetail = {
519
+ annotation,
520
+ };
521
+
522
+ triggerEvent(eventTarget, eventType, eventDetail);
521
523
  }
524
+
525
+ this.editData = null;
526
+ this.angleStartedNotYetCompleted = false;
527
+ return annotation.annotationUID;
522
528
  };
523
529
 
524
530
  _activateModify = (element: HTMLDivElement) => {
@@ -661,7 +667,7 @@ class CobbAngleTool extends AnnotationTool {
661
667
 
662
668
  // Draw SVG
663
669
  for (let i = 0; i < annotations.length; i++) {
664
- const annotation = annotations[i] as AngleAnnotation;
670
+ const annotation = annotations[i] as CobbAngleAnnotation;
665
671
  const { annotationUID, data } = annotation;
666
672
  const { points, activeHandleIndex } = data.handles;
667
673
 
@@ -680,6 +686,26 @@ class CobbAngleTool extends AnnotationTool {
680
686
  ) {
681
687
  data.cachedStats[targetId] = {
682
688
  angle: null,
689
+ arc1Angle: null,
690
+ arc2Angle: null,
691
+ points: {
692
+ world: {
693
+ arc1Start: null,
694
+ arc1End: null,
695
+ arc2Start: null,
696
+ arc2End: null,
697
+ arc1Angle: null,
698
+ arc2Angle: null,
699
+ },
700
+ canvas: {
701
+ arc1Start: null,
702
+ arc1End: null,
703
+ arc2Start: null,
704
+ arc2End: null,
705
+ arc1Angle: null,
706
+ arc2Angle: null,
707
+ },
708
+ },
683
709
  };
684
710
 
685
711
  this._calculateCachedStats(annotation, renderingEngine, enabledElement);
@@ -724,13 +750,22 @@ class CobbAngleTool extends AnnotationTool {
724
750
  );
725
751
  }
726
752
 
727
- let lineUID = '1';
753
+ const firstLine = [canvasCoordinates[0], canvasCoordinates[1]] as [
754
+ Types.Point2,
755
+ Types.Point2
756
+ ];
757
+ const secondLine = [canvasCoordinates[2], canvasCoordinates[3]] as [
758
+ Types.Point2,
759
+ Types.Point2
760
+ ];
761
+
762
+ let lineUID = 'line1';
728
763
  drawLineSvg(
729
764
  svgDrawingHelper,
730
765
  annotationUID,
731
766
  lineUID,
732
- canvasCoordinates[0],
733
- canvasCoordinates[1],
767
+ firstLine[0],
768
+ firstLine[1],
734
769
  {
735
770
  color,
736
771
  width: lineWidth,
@@ -740,19 +775,19 @@ class CobbAngleTool extends AnnotationTool {
740
775
 
741
776
  renderStatus = true;
742
777
 
743
- // Don't add textBox until annotation has 4 anchor points
778
+ // Don't add the stats until annotation has 4 anchor points
744
779
  if (canvasCoordinates.length < 4) {
745
780
  return renderStatus;
746
781
  }
747
782
 
748
- lineUID = '2';
783
+ lineUID = 'line2';
749
784
 
750
785
  drawLineSvg(
751
786
  svgDrawingHelper,
752
787
  annotationUID,
753
788
  lineUID,
754
- canvasCoordinates[2],
755
- canvasCoordinates[3],
789
+ secondLine[0],
790
+ secondLine[1],
756
791
  {
757
792
  color,
758
793
  width: lineWidth,
@@ -760,15 +795,49 @@ class CobbAngleTool extends AnnotationTool {
760
795
  }
761
796
  );
762
797
 
763
- lineUID = '3';
764
- const mid1 = midPoint2(canvasCoordinates[0], canvasCoordinates[1]);
765
- const mid2 = midPoint2(canvasCoordinates[2], canvasCoordinates[3]);
798
+ lineUID = 'linkLine';
799
+ const mid1 = midPoint2(firstLine[0], firstLine[1]);
800
+ const mid2 = midPoint2(secondLine[0], secondLine[1]);
766
801
  drawLineSvg(svgDrawingHelper, annotationUID, lineUID, mid1, mid2, {
767
802
  color,
768
803
  lineWidth: '1',
769
804
  lineDash: '1,4',
770
805
  });
771
806
 
807
+ // Calculating the arcs
808
+
809
+ const { arc1Start, arc1End, arc2End, arc2Start } =
810
+ data.cachedStats[targetId].points.canvas;
811
+ const { arc1Angle, arc2Angle } = data.cachedStats[targetId];
812
+
813
+ lineUID = 'arc1';
814
+
815
+ drawLineSvg(
816
+ svgDrawingHelper,
817
+ annotationUID,
818
+ lineUID,
819
+ arc1Start as Types.Point2,
820
+ arc1End as Types.Point2,
821
+ {
822
+ color,
823
+ lineWidth: '1',
824
+ }
825
+ );
826
+
827
+ lineUID = 'arc2';
828
+
829
+ drawLineSvg(
830
+ svgDrawingHelper,
831
+ annotationUID,
832
+ lineUID,
833
+ arc2Start as Types.Point2,
834
+ arc2End as Types.Point2,
835
+ {
836
+ color,
837
+ lineWidth: '1',
838
+ }
839
+ );
840
+
772
841
  if (!data.cachedStats[targetId]?.angle) {
773
842
  continue;
774
843
  }
@@ -801,7 +870,7 @@ class CobbAngleTool extends AnnotationTool {
801
870
  data.handles.textBox.worldPosition
802
871
  );
803
872
 
804
- const textBoxUID = '1';
873
+ const textBoxUID = 'cobbAngleText';
805
874
  const boundingBox = drawLinkedTextBoxSvg(
806
875
  svgDrawingHelper,
807
876
  annotationUID,
@@ -821,6 +890,46 @@ class CobbAngleTool extends AnnotationTool {
821
890
  bottomLeft: viewport.canvasToWorld([left, top + height]),
822
891
  bottomRight: viewport.canvasToWorld([left + width, top + height]),
823
892
  };
893
+
894
+ const arc1TextBoxUID = 'arcAngle1';
895
+
896
+ const arc1TextLine = [
897
+ `${arc1Angle.toFixed(2)} ${String.fromCharCode(176)}`,
898
+ ];
899
+
900
+ const arch1TextPosCanvas = midPoint2(arc1Start, arc1End);
901
+
902
+ drawTextBoxSvg(
903
+ svgDrawingHelper,
904
+ annotationUID,
905
+ arc1TextBoxUID,
906
+ arc1TextLine,
907
+ arch1TextPosCanvas,
908
+ {
909
+ ...options,
910
+ padding: 3,
911
+ }
912
+ );
913
+
914
+ const arc2TextBoxUID = 'arcAngle2';
915
+
916
+ const arc2TextLine = [
917
+ `${arc2Angle.toFixed(2)} ${String.fromCharCode(176)}`,
918
+ ];
919
+
920
+ const arch2TextPosCanvas = midPoint2(arc2Start, arc2End);
921
+
922
+ drawTextBoxSvg(
923
+ svgDrawingHelper,
924
+ annotationUID,
925
+ arc2TextBoxUID,
926
+ arc2TextLine,
927
+ arch2TextPosCanvas,
928
+ {
929
+ ...options,
930
+ padding: 3,
931
+ }
932
+ );
824
933
  }
825
934
 
826
935
  return renderStatus;
@@ -862,16 +971,56 @@ class CobbAngleTool extends AnnotationTool {
862
971
  }
863
972
  }
864
973
  }
974
+ const { viewport } = enabledElement;
975
+
976
+ const canvasPoints = data.handles.points.map((p) =>
977
+ viewport.worldToCanvas(p)
978
+ );
979
+
980
+ const firstLine = [canvasPoints[0], canvasPoints[1]] as [
981
+ Types.Point2,
982
+ Types.Point2
983
+ ];
984
+ const secondLine = [canvasPoints[2], canvasPoints[3]] as [
985
+ Types.Point2,
986
+ Types.Point2
987
+ ];
988
+
989
+ const mid1 = midPoint2(firstLine[0], firstLine[1]);
990
+ const mid2 = midPoint2(secondLine[0], secondLine[1]);
991
+
992
+ const { arc1Start, arc1End, arc2End, arc2Start, arc1Angle, arc2Angle } =
993
+ this.getArcsStartEndPoints({
994
+ firstLine,
995
+ secondLine,
996
+ mid1,
997
+ mid2,
998
+ });
865
999
 
866
1000
  const { cachedStats } = data;
867
1001
  const targetIds = Object.keys(cachedStats);
868
1002
 
869
1003
  for (let i = 0; i < targetIds.length; i++) {
870
1004
  const targetId = targetIds[i];
871
- const angle = angleBetweenLines(seg1, seg2);
872
1005
 
873
1006
  cachedStats[targetId] = {
874
- angle,
1007
+ angle: angleBetweenLines(seg1, seg2),
1008
+ arc1Angle,
1009
+ arc2Angle,
1010
+ points: {
1011
+ canvas: {
1012
+ arc1Start,
1013
+ arc1End,
1014
+ arc2End,
1015
+ arc2Start,
1016
+ },
1017
+ world: {
1018
+ arc1Start: viewport.canvasToWorld(arc1Start),
1019
+ arc1End: viewport.canvasToWorld(arc1End),
1020
+ arc2End: viewport.canvasToWorld(arc2End),
1021
+ arc2Start: viewport.canvasToWorld(arc2Start),
1022
+ },
1023
+ },
875
1024
  };
876
1025
  }
877
1026
 
@@ -889,6 +1038,177 @@ class CobbAngleTool extends AnnotationTool {
889
1038
 
890
1039
  return cachedStats;
891
1040
  }
1041
+
1042
+ distanceToLines = ({ viewport, points, canvasCoords, proximity }) => {
1043
+ const [point1, point2, point3, point4] = points;
1044
+ const canvasPoint1 = viewport.worldToCanvas(point1);
1045
+ const canvasPoint2 = viewport.worldToCanvas(point2);
1046
+ const canvasPoint3 = viewport.worldToCanvas(point3);
1047
+ const canvasPoint4 = viewport.worldToCanvas(point4);
1048
+
1049
+ const line1 = {
1050
+ start: {
1051
+ x: canvasPoint1[0],
1052
+ y: canvasPoint1[1],
1053
+ },
1054
+ end: {
1055
+ x: canvasPoint2[0],
1056
+ y: canvasPoint2[1],
1057
+ },
1058
+ };
1059
+
1060
+ const line2 = {
1061
+ start: {
1062
+ x: canvasPoint3[0],
1063
+ y: canvasPoint3[1],
1064
+ },
1065
+ end: {
1066
+ x: canvasPoint4[0],
1067
+ y: canvasPoint4[1],
1068
+ },
1069
+ };
1070
+
1071
+ const distanceToPoint = lineSegment.distanceToPoint(
1072
+ [line1.start.x, line1.start.y],
1073
+ [line1.end.x, line1.end.y],
1074
+ [canvasCoords[0], canvasCoords[1]]
1075
+ );
1076
+
1077
+ const distanceToPoint2 = lineSegment.distanceToPoint(
1078
+ [line2.start.x, line2.start.y],
1079
+ [line2.end.x, line2.end.y],
1080
+ [canvasCoords[0], canvasCoords[1]]
1081
+ );
1082
+
1083
+ let isNearFirstLine = false;
1084
+ let isNearSecondLine = false;
1085
+
1086
+ if (distanceToPoint <= proximity) {
1087
+ isNearFirstLine = true;
1088
+ } else if (distanceToPoint2 <= proximity) {
1089
+ isNearSecondLine = true;
1090
+ }
1091
+ return {
1092
+ distanceToPoint,
1093
+ distanceToPoint2,
1094
+ isNearFirstLine,
1095
+ isNearSecondLine,
1096
+ };
1097
+ };
1098
+
1099
+ getArcsStartEndPoints = ({
1100
+ firstLine,
1101
+ secondLine,
1102
+ mid1,
1103
+ mid2,
1104
+ }): {
1105
+ arc1Start: Types.Point2;
1106
+ arc1End: Types.Point2;
1107
+ arc2Start: Types.Point2;
1108
+ arc2End: Types.Point2;
1109
+ arc1Angle: number;
1110
+ arc2Angle: number;
1111
+ } => {
1112
+ const linkLine = [mid1, mid2] as [Types.Point2, Types.Point2];
1113
+
1114
+ const arc1Angle = angleBetweenLines(firstLine, linkLine);
1115
+ const arc2Angle = angleBetweenLines(secondLine, linkLine);
1116
+
1117
+ const arc1Side = arc1Angle > 90 ? 1 : 0;
1118
+ const arc2Side = arc2Angle > 90 ? 0 : 1;
1119
+
1120
+ const midLinkLine = midPoint2(linkLine[0], linkLine[1]);
1121
+
1122
+ const linkLineLength = Math.sqrt(
1123
+ (linkLine[1][0] - linkLine[0][0]) ** 2 +
1124
+ (linkLine[1][1] - linkLine[0][1]) ** 2
1125
+ );
1126
+ const ratio = 0.1; // 10% of the line length
1127
+
1128
+ const midFirstLine = midPoint2(firstLine[0], firstLine[1]);
1129
+ const midSecondLine = midPoint2(secondLine[0], secondLine[1]);
1130
+
1131
+ // For arc1Start
1132
+ const directionVectorStartArc1 = [
1133
+ firstLine[arc1Side][0] - midFirstLine[0],
1134
+ firstLine[arc1Side][1] - midFirstLine[1],
1135
+ ];
1136
+ const magnitudeStartArc1 = Math.sqrt(
1137
+ directionVectorStartArc1[0] ** 2 + directionVectorStartArc1[1] ** 2
1138
+ );
1139
+ const normalizedDirectionStartArc1 = [
1140
+ directionVectorStartArc1[0] / magnitudeStartArc1,
1141
+ directionVectorStartArc1[1] / magnitudeStartArc1,
1142
+ ];
1143
+ const arc1Start = [
1144
+ midFirstLine[0] +
1145
+ normalizedDirectionStartArc1[0] * linkLineLength * ratio,
1146
+ midFirstLine[1] +
1147
+ normalizedDirectionStartArc1[1] * linkLineLength * ratio,
1148
+ ] as Types.Point2;
1149
+
1150
+ // Existing logic for arc1End
1151
+ const directionVectorEndArc1 = [
1152
+ midLinkLine[0] - mid1[0],
1153
+ midLinkLine[1] - mid1[1],
1154
+ ];
1155
+ const magnitudeEndArc1 = Math.sqrt(
1156
+ directionVectorEndArc1[0] ** 2 + directionVectorEndArc1[1] ** 2
1157
+ );
1158
+ const normalizedDirectionEndArc1 = [
1159
+ directionVectorEndArc1[0] / magnitudeEndArc1,
1160
+ directionVectorEndArc1[1] / magnitudeEndArc1,
1161
+ ];
1162
+ const arc1End = [
1163
+ mid1[0] + normalizedDirectionEndArc1[0] * linkLineLength * ratio,
1164
+ mid1[1] + normalizedDirectionEndArc1[1] * linkLineLength * ratio,
1165
+ ] as Types.Point2;
1166
+
1167
+ // Similar logic for arc2Start
1168
+ const directionVectorStartArc2 = [
1169
+ secondLine[arc2Side][0] - midSecondLine[0],
1170
+ secondLine[arc2Side][1] - midSecondLine[1],
1171
+ ];
1172
+ const magnitudeStartArc2 = Math.sqrt(
1173
+ directionVectorStartArc2[0] ** 2 + directionVectorStartArc2[1] ** 2
1174
+ );
1175
+ const normalizedDirectionStartArc2 = [
1176
+ directionVectorStartArc2[0] / magnitudeStartArc2,
1177
+ directionVectorStartArc2[1] / magnitudeStartArc2,
1178
+ ];
1179
+ const arc2Start = [
1180
+ midSecondLine[0] +
1181
+ normalizedDirectionStartArc2[0] * linkLineLength * ratio,
1182
+ midSecondLine[1] +
1183
+ normalizedDirectionStartArc2[1] * linkLineLength * ratio,
1184
+ ] as Types.Point2;
1185
+
1186
+ // Similar logic for arc2End
1187
+ const directionVectorEndArc2 = [
1188
+ midLinkLine[0] - mid2[0],
1189
+ midLinkLine[1] - mid2[1],
1190
+ ];
1191
+ const magnitudeEndArc2 = Math.sqrt(
1192
+ directionVectorEndArc2[0] ** 2 + directionVectorEndArc2[1] ** 2
1193
+ );
1194
+ const normalizedDirectionEndArc2 = [
1195
+ directionVectorEndArc2[0] / magnitudeEndArc2,
1196
+ directionVectorEndArc2[1] / magnitudeEndArc2,
1197
+ ];
1198
+ const arc2End = [
1199
+ mid2[0] + normalizedDirectionEndArc2[0] * linkLineLength * ratio,
1200
+ mid2[1] + normalizedDirectionEndArc2[1] * linkLineLength * ratio,
1201
+ ] as Types.Point2;
1202
+
1203
+ return {
1204
+ arc1Start,
1205
+ arc1End,
1206
+ arc2Start,
1207
+ arc2End,
1208
+ arc1Angle: arc1Angle > 90 ? 180 - arc1Angle : arc1Angle,
1209
+ arc2Angle: arc2Angle > 90 ? 180 - arc2Angle : arc2Angle,
1210
+ };
1211
+ };
892
1212
  }
893
1213
 
894
1214
  function defaultGetTextLines(data, targetId): string[] {