@adecore/drawing 0.49.5 → 0.49.7

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/dist/geometry.js CHANGED
@@ -40,7 +40,7 @@ export function unionOf(rects) {
40
40
  return { x: left, y: top, w: right - left, h: bottom - top };
41
41
  }
42
42
  export function boundsOfElements(elements) {
43
- return unionOf(elements.map(boundsOf));
43
+ return unionOf(elements);
44
44
  }
45
45
  function cornersOf(rect) {
46
46
  return [
@@ -6,6 +6,13 @@ const LABEL_REACH = 48;
6
6
  function labelOf(element) {
7
7
  return element.kind === 'text' || element.kind === 'note' ? element.text.trim() || null : null;
8
8
  }
9
+ function hitsLabel(element, point, tolerance) {
10
+ // Filled, unrotated rectangles, texts and notes use the same inclusive box test.
11
+ if ((element.angle ?? 0) === 0 && (element.kind === 'rect' || element.kind === 'text' || element.kind === 'note')) {
12
+ return point.x >= element.x && point.x <= element.x + element.w && point.y >= element.y && point.y <= element.y + element.h;
13
+ }
14
+ return hitsElement({ ...element, fill: 'solid' }, point, tolerance);
15
+ }
9
16
  /* A shape says what it is by the text inside it, which is how a box on a diagram is named. */
10
17
  function labelInside(element, elements) {
11
18
  for (const candidate of elements) {
@@ -13,7 +20,7 @@ function labelInside(element, elements) {
13
20
  continue;
14
21
  }
15
22
  const center = centerOf(boundsOf(candidate));
16
- if (hitsElement({ ...element, fill: 'solid' }, center, 0)) {
23
+ if (hitsLabel(element, center, 0)) {
17
24
  return labelOf(candidate);
18
25
  }
19
26
  }
@@ -27,8 +34,14 @@ function labelAt(point, elements, arrowId) {
27
34
  continue;
28
35
  }
29
36
  const center = centerOf(boundsOf(element));
30
- const distance = Math.hypot(center.x - point.x, center.y - point.y);
31
- if (distance > LABEL_REACH && !hitsElement({ ...element, fill: 'solid' }, point, LABEL_REACH)) {
37
+ const dx = center.x - point.x;
38
+ const dy = center.y - point.y;
39
+ const beyondReach = Math.abs(dx) > LABEL_REACH || Math.abs(dy) > LABEL_REACH;
40
+ if (beyondReach && !hitsLabel(element, point, LABEL_REACH)) {
41
+ continue;
42
+ }
43
+ const distance = Math.hypot(dx, dy);
44
+ if (!beyondReach && distance > LABEL_REACH && !hitsLabel(element, point, LABEL_REACH)) {
32
45
  continue;
33
46
  }
34
47
  const label = labelOf(element) ?? labelInside(element, elements);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adecore/drawing",
3
- "version": "0.49.5",
3
+ "version": "0.49.7",
4
4
  "description": "Drawing schemas, geometry, deterministic paths, SVG export and reading order.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "author": "Bas Milius",
package/src/geometry.ts CHANGED
@@ -67,7 +67,7 @@ export function unionOf(rects: readonly Rect[]): Rect | null {
67
67
  }
68
68
 
69
69
  export function boundsOfElements(elements: readonly DrawingElement[]): Rect | null {
70
- return unionOf(elements.map(boundsOf));
70
+ return unionOf(elements);
71
71
  }
72
72
 
73
73
  function cornersOf(rect: Rect): Point[] {
@@ -11,6 +11,15 @@ function labelOf(element: DrawingElement): string | null {
11
11
  return element.kind === 'text' || element.kind === 'note' ? element.text.trim() || null : null;
12
12
  }
13
13
 
14
+ function hitsLabel(element: DrawingElement, point: Point, tolerance: number): boolean {
15
+ // Filled, unrotated rectangles, texts and notes use the same inclusive box test.
16
+ if ((element.angle ?? 0) === 0 && (element.kind === 'rect' || element.kind === 'text' || element.kind === 'note')) {
17
+ return point.x >= element.x && point.x <= element.x + element.w && point.y >= element.y && point.y <= element.y + element.h;
18
+ }
19
+
20
+ return hitsElement({ ...element, fill: 'solid' }, point, tolerance);
21
+ }
22
+
14
23
  /* A shape says what it is by the text inside it, which is how a box on a diagram is named. */
15
24
  function labelInside(element: DrawingElement, elements: readonly DrawingElement[]): string | null {
16
25
  for (const candidate of elements) {
@@ -20,7 +29,7 @@ function labelInside(element: DrawingElement, elements: readonly DrawingElement[
20
29
 
21
30
  const center = centerOf(boundsOf(candidate));
22
31
 
23
- if (hitsElement({ ...element, fill: 'solid' }, center, 0)) {
32
+ if (hitsLabel(element, center, 0)) {
24
33
  return labelOf(candidate);
25
34
  }
26
35
  }
@@ -38,9 +47,17 @@ function labelAt(point: Point, elements: readonly DrawingElement[], arrowId: str
38
47
  }
39
48
 
40
49
  const center = centerOf(boundsOf(element));
41
- const distance = Math.hypot(center.x - point.x, center.y - point.y);
50
+ const dx = center.x - point.x;
51
+ const dy = center.y - point.y;
52
+ const beyondReach = Math.abs(dx) > LABEL_REACH || Math.abs(dy) > LABEL_REACH;
53
+
54
+ if (beyondReach && !hitsLabel(element, point, LABEL_REACH)) {
55
+ continue;
56
+ }
57
+
58
+ const distance = Math.hypot(dx, dy);
42
59
 
43
- if (distance > LABEL_REACH && !hitsElement({ ...element, fill: 'solid' }, point, LABEL_REACH)) {
60
+ if (!beyondReach && distance > LABEL_REACH && !hitsLabel(element, point, LABEL_REACH)) {
44
61
  continue;
45
62
  }
46
63