@pooder/kit 3.0.1 → 3.2.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.
package/src/geometry.ts CHANGED
@@ -1,12 +1,99 @@
1
1
  import paper from "paper";
2
2
 
3
+ export type PositionAnchor =
4
+ | "top-left"
5
+ | "top-center"
6
+ | "top-right"
7
+ | "center-left"
8
+ | "center"
9
+ | "center-right"
10
+ | "bottom-left"
11
+ | "bottom-center"
12
+ | "bottom-right";
13
+
3
14
  export interface HoleData {
4
- x: number;
5
- y: number;
15
+ x?: number;
16
+ y?: number;
17
+ anchor?: PositionAnchor;
18
+ offsetX?: number;
19
+ offsetY?: number;
6
20
  innerRadius: number;
7
21
  outerRadius: number;
8
22
  }
9
23
 
24
+ export function resolveHolePosition(
25
+ hole: HoleData,
26
+ geometry: { x: number; y: number; width: number; height: number },
27
+ canvasSize: { width: number; height: number },
28
+ ): { x: number; y: number } {
29
+ if (hole.anchor) {
30
+ const { x, y, width, height } = geometry;
31
+ let bx = x; // center x
32
+ let by = y; // center y
33
+
34
+ // Calculate anchor base position based on shape bounds
35
+ // Note: geometry.x/y is the CENTER of the shape
36
+ const left = x - width / 2;
37
+ const right = x + width / 2;
38
+ const top = y - height / 2;
39
+ const bottom = y + height / 2;
40
+
41
+ switch (hole.anchor) {
42
+ case "top-left":
43
+ bx = left;
44
+ by = top;
45
+ break;
46
+ case "top-center":
47
+ bx = x;
48
+ by = top;
49
+ break;
50
+ case "top-right":
51
+ bx = right;
52
+ by = top;
53
+ break;
54
+ case "center-left":
55
+ bx = left;
56
+ by = y;
57
+ break;
58
+ case "center":
59
+ bx = x;
60
+ by = y;
61
+ break;
62
+ case "center-right":
63
+ bx = right;
64
+ by = y;
65
+ break;
66
+ case "bottom-left":
67
+ bx = left;
68
+ by = bottom;
69
+ break;
70
+ case "bottom-center":
71
+ bx = x;
72
+ by = bottom;
73
+ break;
74
+ case "bottom-right":
75
+ bx = right;
76
+ by = bottom;
77
+ break;
78
+ }
79
+
80
+ return {
81
+ x: bx + (hole.offsetX || 0),
82
+ y: by + (hole.offsetY || 0),
83
+ };
84
+ } else if (hole.x !== undefined && hole.y !== undefined) {
85
+ // Legacy / Direct coordinates (Normalized relative to Dieline Geometry)
86
+ // Formula: absolute = normalized * width + (center - width/2)
87
+ // This handles padding correctly.
88
+ const { x, width, y, height } = geometry;
89
+ return {
90
+ x: hole.x * width + (x - width / 2) + (hole.offsetX || 0),
91
+ y: hole.y * height + (y - height / 2) + (hole.offsetY || 0),
92
+ };
93
+ }
94
+ return { x: 0, y: 0 };
95
+ }
96
+
10
97
  export interface GeometryOptions {
11
98
  shape: "rect" | "circle" | "ellipse" | "custom";
12
99
  width: number;
@@ -270,7 +357,10 @@ function getDielineShape(options: GeometryOptions): paper.PathItem {
270
357
  cutsPath.remove();
271
358
  mainShape = temp;
272
359
  } catch (e) {
273
- console.error("Geometry: Failed to subtract cutsPath from mainShape", e);
360
+ console.error(
361
+ "Geometry: Failed to subtract cutsPath from mainShape",
362
+ e,
363
+ );
274
364
  }
275
365
  }
276
366
  }
@@ -453,6 +543,8 @@ export function getNearestPointOnDieline(
453
543
  }
454
544
 
455
545
  export function getPathBounds(pathData: string): {
546
+ x: number;
547
+ y: number;
456
548
  width: number;
457
549
  height: number;
458
550
  } {
@@ -460,5 +552,10 @@ export function getPathBounds(pathData: string): {
460
552
  path.pathData = pathData;
461
553
  const bounds = path.bounds;
462
554
  path.remove();
463
- return { width: bounds.width, height: bounds.height };
555
+ return {
556
+ x: bounds.x,
557
+ y: bounds.y,
558
+ width: bounds.width,
559
+ height: bounds.height,
560
+ };
464
561
  }