midgard-hex-grid 0.0.0-stage → 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 (75) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +207 -2
  3. package/dist/c-r-fill-around.d.ts +19 -0
  4. package/dist/c-r-fill-around.d.ts.map +1 -0
  5. package/dist/c-r-fill-around.js +28 -0
  6. package/dist/c-r-fill-around.js.map +1 -0
  7. package/dist/c-r-skeleton.d.ts +18 -0
  8. package/dist/c-r-skeleton.d.ts.map +1 -0
  9. package/dist/c-r-skeleton.js +32 -0
  10. package/dist/c-r-skeleton.js.map +1 -0
  11. package/dist/c-r-validation.d.ts +16 -0
  12. package/dist/c-r-validation.d.ts.map +1 -0
  13. package/dist/c-r-validation.js +30 -0
  14. package/dist/c-r-validation.js.map +1 -0
  15. package/dist/coordinate-layer.d.ts +52 -0
  16. package/dist/coordinate-layer.d.ts.map +1 -0
  17. package/dist/coordinate-layer.js +67 -0
  18. package/dist/coordinate-layer.js.map +1 -0
  19. package/dist/coordinate-positioner.d.ts +49 -0
  20. package/dist/coordinate-positioner.d.ts.map +1 -0
  21. package/dist/coordinate-positioner.js +69 -0
  22. package/dist/coordinate-positioner.js.map +1 -0
  23. package/dist/coordinate-range-fill.d.ts +54 -0
  24. package/dist/coordinate-range-fill.d.ts.map +1 -0
  25. package/dist/coordinate-range-fill.js +81 -0
  26. package/dist/coordinate-range-fill.js.map +1 -0
  27. package/dist/coordinate-range.d.ts +69 -0
  28. package/dist/coordinate-range.d.ts.map +1 -0
  29. package/dist/coordinate-range.js +63 -0
  30. package/dist/coordinate-range.js.map +1 -0
  31. package/dist/coordinate.d.ts +30 -0
  32. package/dist/coordinate.d.ts.map +1 -0
  33. package/dist/coordinate.js +40 -0
  34. package/dist/coordinate.js.map +1 -0
  35. package/dist/g-bounds.d.ts +25 -0
  36. package/dist/g-bounds.d.ts.map +1 -0
  37. package/dist/g-bounds.js +51 -0
  38. package/dist/g-bounds.js.map +1 -0
  39. package/dist/g-x-dominated.d.ts +19 -0
  40. package/dist/g-x-dominated.d.ts.map +1 -0
  41. package/dist/g-x-dominated.js +54 -0
  42. package/dist/g-x-dominated.js.map +1 -0
  43. package/dist/g-y-dominated.d.ts +19 -0
  44. package/dist/g-y-dominated.d.ts.map +1 -0
  45. package/dist/g-y-dominated.js +54 -0
  46. package/dist/g-y-dominated.js.map +1 -0
  47. package/dist/geometry.d.ts +73 -0
  48. package/dist/geometry.d.ts.map +1 -0
  49. package/dist/geometry.js +79 -0
  50. package/dist/geometry.js.map +1 -0
  51. package/dist/h-g-bounds.d.ts +26 -0
  52. package/dist/h-g-bounds.d.ts.map +1 -0
  53. package/dist/h-g-bounds.js +37 -0
  54. package/dist/h-g-bounds.js.map +1 -0
  55. package/dist/h-g-hexagon.d.ts +36 -0
  56. package/dist/h-g-hexagon.d.ts.map +1 -0
  57. package/dist/h-g-hexagon.js +38 -0
  58. package/dist/h-g-hexagon.js.map +1 -0
  59. package/dist/hex-grid.d.ts +149 -0
  60. package/dist/hex-grid.d.ts.map +1 -0
  61. package/dist/hex-grid.js +169 -0
  62. package/dist/hex-grid.js.map +1 -0
  63. package/dist/index.d.ts +16 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +10 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/neighbours.d.ts +48 -0
  68. package/dist/neighbours.d.ts.map +1 -0
  69. package/dist/neighbours.js +119 -0
  70. package/dist/neighbours.js.map +1 -0
  71. package/dist/orientation.d.ts +8 -0
  72. package/dist/orientation.d.ts.map +1 -0
  73. package/dist/orientation.js +2 -0
  74. package/dist/orientation.js.map +1 -0
  75. package/package.json +21 -4
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 Niklas Herrloff
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,208 @@
1
- # Temporary Holding Version
1
+ # Midgard Hex Grid
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Midgard Hex Grid is a small reusable TypeScript library for creating and working with hexagonal grids.
4
+
5
+ The library supports both x-dominated and y-dominated hex grids and handles the coordinate system, neighbour calculations, positioning and hexagon geometry. Its purpose is to let another programmer work with hexagonal grids without having to implement these calculations themselves.
6
+
7
+ ## Features
8
+
9
+ - Create x-dominated and y-dominated hex grids
10
+ - Create a single hexagon
11
+ - Generate complete grids from a rectangular skeleton
12
+ - Calculate the six neighbours of a coordinate
13
+ - Validate Midgard coordinates
14
+ - Calculate center positions
15
+ - Calculate the six corner points of a hexagon
16
+ - Calculate the outer bounds of a grid
17
+ - Generate coordinate ranges
18
+ - Generate layered coordinates with z-index values for rendering
19
+
20
+ ## Requirements
21
+
22
+ - TypeScript
23
+ - JavaScript environment with ES modules
24
+
25
+ The library has no runtime dependencies.
26
+
27
+ Development uses:
28
+
29
+ - TypeScript 7
30
+ - Vitest 5
31
+
32
+ ## Installation
33
+
34
+ Clone the repository and install the development dependencies:
35
+
36
+ ```bash
37
+ npm install
38
+ ```
39
+
40
+ Build the library:
41
+
42
+ ```bash
43
+ npm run build
44
+ ```
45
+
46
+ The compiled JavaScript and TypeScript declarations are generated in the `dist` directory.
47
+
48
+ ## Basic usage
49
+
50
+ The main class is `HexGrid`.
51
+
52
+ Create a grid by first choosing its orientation:
53
+
54
+ ```ts
55
+ import { HexGrid } from './dist/index.js'
56
+
57
+ const grid = new HexGrid('x-dominated')
58
+ ```
59
+
60
+ The orientation can be:
61
+
62
+ ```ts
63
+ 'x-dominated'
64
+ ```
65
+
66
+ or:
67
+
68
+ ```ts
69
+ 'y-dominated'
70
+ ```
71
+
72
+ ### Create a single hexagon
73
+
74
+ ```ts
75
+ const grid = new HexGrid('x-dominated')
76
+
77
+ const hexagon = grid.createSingleHexagon({
78
+ hexDiameter: 100
79
+ })
80
+ ```
81
+
82
+ The returned hexagon contains:
83
+
84
+ - its Midgard coordinate
85
+ - its center position
86
+ - its six corner points
87
+
88
+ These values can, for example, be used by an application to render the hexagon as SVG.
89
+
90
+ ### Create a complete grid
91
+
92
+ ```ts
93
+ const grid = new HexGrid('x-dominated')
94
+
95
+ const hexagons = grid.createGrid({
96
+ hexDiameter: 100,
97
+ skeletonWidth: 3,
98
+ skeletonHeight: 2
99
+ })
100
+ ```
101
+
102
+ `skeletonWidth` and `skeletonHeight` describe the rectangular skeleton around which the complete grid is generated.
103
+
104
+ The library automatically fills the surrounding coordinates and returns the hexagons in rendering order with calculated z-index values.
105
+
106
+ ### Y-dominated grid
107
+
108
+ The same API can be used for the other orientation:
109
+
110
+ ```ts
111
+ const grid = new HexGrid('y-dominated')
112
+
113
+ const hexagons = grid.createGrid({
114
+ hexDiameter: 100,
115
+ skeletonWidth: 3,
116
+ skeletonHeight: 2
117
+ })
118
+ ```
119
+
120
+ The grid orientation controls the coordinate relationships, positioning and geometry internally.
121
+
122
+ ## Neighbours
123
+
124
+ The six neighbouring coordinates can be calculated through the grid:
125
+
126
+ ```ts
127
+ const neighbours = grid.getNeighbours({
128
+ x: 2,
129
+ y: 2
130
+ })
131
+ ```
132
+
133
+ The result depends on whether the `HexGrid` is x-dominated or y-dominated.
134
+
135
+ ## Coordinate validation
136
+
137
+ A coordinate can be checked before it is used:
138
+
139
+ ```ts
140
+ const valid = grid.isValidCoordinate({
141
+ x: 2,
142
+ y: 2
143
+ })
144
+ ```
145
+
146
+ ## Lower-level API
147
+
148
+ `HexGrid` provides the simplest interface for most uses.
149
+
150
+ The library also exports lower-level classes for programmers who want to work directly with individual parts of the grid system, including:
151
+
152
+ - `CoordinateValidator`
153
+ - `NeighbourCalculator`
154
+ - `HexagonGeometry`
155
+ - `CoordinatePositioner`
156
+ - `CoordinateRange`
157
+ - `CoordinateRangeFiller`
158
+ - `CoordinateLayer`
159
+
160
+ The public TypeScript types are exported from `src/index.ts`.
161
+
162
+ ## Testing
163
+
164
+ The mathematical and coordinate logic is tested with automated unit tests using Vitest.
165
+
166
+ Run all automated tests with:
167
+
168
+ ```bash
169
+ npx vitest run
170
+ ```
171
+
172
+ The library is also tested visually with a separate graphical Test-App. This makes it possible to verify that the calculated coordinates and geometry produce the expected SVG hexagons and grid layouts.
173
+
174
+ See [`TEST_REPORT.md`](./TEST_REPORT.md) for the test documentation and results.
175
+
176
+ ## Development commands
177
+
178
+ Check the TypeScript code without producing build files:
179
+
180
+ ```bash
181
+ npm run check
182
+ ```
183
+
184
+ Build the library:
185
+
186
+ ```bash
187
+ npm run build
188
+ ```
189
+
190
+ Run the automated tests:
191
+
192
+ ```bash
193
+ npx vitest run
194
+ ```
195
+
196
+ ## Version
197
+
198
+ Current version: `1.0.0`
199
+
200
+ The version is also available from the library:
201
+
202
+ ```ts
203
+ import { MIDGARD_HEX_GRID_VERSION } from './dist/index.js'
204
+ ```
205
+
206
+ ## License
207
+
208
+ ISC
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Determines whether a Midgard coordinate range
3
+ * should be filled around its skeleton.
4
+ */
5
+ export declare class CoordinateRangeFillAround {
6
+ /**
7
+ * Determines whether surrounding coordinates should be added.
8
+ *
9
+ * A 1 by 1 skeleton can choose whether to use fillAround.
10
+ * Any larger skeleton is always filled around automatically.
11
+ *
12
+ * @param width - The width of the coordinate range.
13
+ * @param height - The height of the coordinate range.
14
+ * @param fillAround - Whether a 1 by 1 range should be filled around.
15
+ * @returns True if the range should be filled around.
16
+ */
17
+ shouldFillAround(width: number, height: number, fillAround?: boolean): boolean;
18
+ }
19
+ //# sourceMappingURL=c-r-fill-around.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"c-r-fill-around.d.ts","sourceRoot":"","sources":["../src/c-r-fill-around.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,yBAAyB;IAClC;;;;;;;;;;OAUG;IACH,gBAAgB,CACd,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,OAAe,GAC1B,OAAO,CAaT;CACF"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Determines whether a Midgard coordinate range
3
+ * should be filled around its skeleton.
4
+ */
5
+ export class CoordinateRangeFillAround {
6
+ /**
7
+ * Determines whether surrounding coordinates should be added.
8
+ *
9
+ * A 1 by 1 skeleton can choose whether to use fillAround.
10
+ * Any larger skeleton is always filled around automatically.
11
+ *
12
+ * @param width - The width of the coordinate range.
13
+ * @param height - The height of the coordinate range.
14
+ * @param fillAround - Whether a 1 by 1 range should be filled around.
15
+ * @returns True if the range should be filled around.
16
+ */
17
+ shouldFillAround(width, height, fillAround = false) {
18
+ const isSingleCoordinate = width === 1 && height === 1;
19
+ if (!isSingleCoordinate) {
20
+ return true;
21
+ }
22
+ if (fillAround) {
23
+ return true;
24
+ }
25
+ return false;
26
+ }
27
+ }
28
+ //# sourceMappingURL=c-r-fill-around.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"c-r-fill-around.js","sourceRoot":"","sources":["../src/c-r-fill-around.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,yBAAyB;IAClC;;;;;;;;;;OAUG;IACH,gBAAgB,CACd,KAAa,EACb,MAAc,EACd,UAAU,GAAY,KAAK;QAE3B,MAAM,kBAAkB,GACtB,KAAK,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,CAAA;QAE7B,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,OAAO,IAAI,CAAA;QACb,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,IAAI,CAAA;QACb,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ import type { Coordinate } from './coordinate.js';
2
+ /**
3
+ * Creates the skeleton coordinates for a Midgard coordinate range.
4
+ *
5
+ * The upper-left skeleton coordinate is always (2, 2).
6
+ * Skeleton coordinates use steps of two in both directions.
7
+ */
8
+ export declare class CoordinateRangeSkeleton {
9
+ /**
10
+ * Creates a rectangular skeleton of coordinates.
11
+ *
12
+ * @param width - The number of skeleton coordinates horizontally.
13
+ * @param height - The number of skeleton coordinates vertically.
14
+ * @returns The coordinates that form the skeleton.
15
+ */
16
+ create(width: number, height: number): Coordinate[];
17
+ }
18
+ //# sourceMappingURL=c-r-skeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"c-r-skeleton.d.ts","sourceRoot":"","sources":["../src/c-r-skeleton.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;;;;GAKG;AACH,qBAAa,uBAAuB;IAClC;;;;;;OAMG;IACH,MAAM,CACJ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,UAAU,EAAE,CAoBd;CACF"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Creates the skeleton coordinates for a Midgard coordinate range.
3
+ *
4
+ * The upper-left skeleton coordinate is always (2, 2).
5
+ * Skeleton coordinates use steps of two in both directions.
6
+ */
7
+ export class CoordinateRangeSkeleton {
8
+ /**
9
+ * Creates a rectangular skeleton of coordinates.
10
+ *
11
+ * @param width - The number of skeleton coordinates horizontally.
12
+ * @param height - The number of skeleton coordinates vertically.
13
+ * @returns The coordinates that form the skeleton.
14
+ */
15
+ create(width, height) {
16
+ const coordinates = [];
17
+ const startX = 2;
18
+ const startY = 2;
19
+ for (let yIndex = 0; yIndex < height; yIndex++) {
20
+ const y = startY + yIndex * 2;
21
+ for (let xIndex = 0; xIndex < width; xIndex++) {
22
+ const x = startX + xIndex * 2;
23
+ coordinates.push({
24
+ x,
25
+ y
26
+ });
27
+ }
28
+ }
29
+ return coordinates;
30
+ }
31
+ }
32
+ //# sourceMappingURL=c-r-skeleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"c-r-skeleton.js","sourceRoot":"","sources":["../src/c-r-skeleton.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,OAAO,uBAAuB;IAClC;;;;;;OAMG;IACH,MAAM,CACJ,KAAa,EACb,MAAc;QAEd,MAAM,WAAW,GAAiB,EAAE,CAAA;QAEpC,MAAM,MAAM,GAAG,CAAC,CAAA;QAChB,MAAM,MAAM,GAAG,CAAC,CAAA;QAEhB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;YAC/C,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAA;YAE7B,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;gBAC9C,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAA;gBAE7B,WAAW,CAAC,IAAI,CAAC;oBACf,CAAC;oBACD,CAAC;iBACF,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAA;IACpB,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Validates the dimensions of a Midgard coordinate range.
3
+ */
4
+ export declare class CoordinateRangeValidator {
5
+ /**
6
+ * Checks whether width and height are valid range dimensions.
7
+ *
8
+ * Both dimensions must be positive integers.
9
+ *
10
+ * @param width - The width of the coordinate range.
11
+ * @param height - The height of the coordinate range.
12
+ * @returns True if both dimensions are valid.
13
+ */
14
+ isValid(width: number, height: number): boolean;
15
+ }
16
+ //# sourceMappingURL=c-r-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"c-r-validation.d.ts","sourceRoot":"","sources":["../src/c-r-validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,wBAAwB;IACjC;;;;;;;;OAQG;IACH,OAAO,CACL,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAkBT;CACF"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Validates the dimensions of a Midgard coordinate range.
3
+ */
4
+ export class CoordinateRangeValidator {
5
+ /**
6
+ * Checks whether width and height are valid range dimensions.
7
+ *
8
+ * Both dimensions must be positive integers.
9
+ *
10
+ * @param width - The width of the coordinate range.
11
+ * @param height - The height of the coordinate range.
12
+ * @returns True if both dimensions are valid.
13
+ */
14
+ isValid(width, height) {
15
+ if (!Number.isInteger(width)) {
16
+ return false;
17
+ }
18
+ if (!Number.isInteger(height)) {
19
+ return false;
20
+ }
21
+ if (width < 1) {
22
+ return false;
23
+ }
24
+ if (height < 1) {
25
+ return false;
26
+ }
27
+ return true;
28
+ }
29
+ }
30
+ //# sourceMappingURL=c-r-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"c-r-validation.js","sourceRoot":"","sources":["../src/c-r-validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,wBAAwB;IACjC;;;;;;;;OAQG;IACH,OAAO,CACL,KAAa,EACb,MAAc;QAEd,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAA;QACd,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAA;QACd,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,OAAO,KAAK,CAAA;QACd,CAAC;QAED,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACf,OAAO,KAAK,CAAA;QACd,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
@@ -0,0 +1,52 @@
1
+ import type { Coordinate } from './coordinate.js';
2
+ /**
3
+ * Represents a Midgard coordinate with a z-index for rendering.
4
+ *
5
+ * The z-index is based on the coordinate's y row.
6
+ * The row with the lowest y value starts at 100,
7
+ * and each following row increases by 100.
8
+ */
9
+ export type LayeredCoordinate = {
10
+ x: number;
11
+ y: number;
12
+ zIndex: number;
13
+ };
14
+ /**
15
+ * Handles sorting and layering of Midgard coordinates
16
+ * for rendering.
17
+ */
18
+ export declare class CoordinateLayer {
19
+ private readonly coordinates;
20
+ /**
21
+ * Creates a new coordinate layer.
22
+ *
23
+ * A copy of the coordinates is stored so that the original
24
+ * array is not changed.
25
+ *
26
+ * @param coordinates - The coordinates to sort and layer.
27
+ */
28
+ constructor(coordinates: Coordinate[]);
29
+ /**
30
+ * Sorts the coordinates by y first and x second.
31
+ *
32
+ * Coordinates with the lowest y value come first.
33
+ * Coordinates on the same y row are ordered from
34
+ * the lowest x value to the highest x value.
35
+ *
36
+ * @returns A new array containing the sorted coordinates.
37
+ */
38
+ sortCoordinates(): Coordinate[];
39
+ /**
40
+ * Creates layered coordinates for rendering a Midgard hex grid.
41
+ *
42
+ * Coordinates are ordered by y first and x second.
43
+ * The first y row receives z-index 100.
44
+ * Each following y row increases the z-index by 100.
45
+ *
46
+ * All coordinates on the same y row receive the same z-index.
47
+ *
48
+ * @returns Sorted coordinates with their calculated z-index.
49
+ */
50
+ getLayeredCoordinates(): LayeredCoordinate[];
51
+ }
52
+ //# sourceMappingURL=coordinate-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinate-layer.d.ts","sourceRoot":"","sources":["../src/coordinate-layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAE1C;;;;;;;OAOG;IACH,YAAY,WAAW,EAAE,UAAU,EAAE,EAEpC;IAED;;;;;;;;OAQG;IACH,eAAe,IAAI,UAAU,EAAE,CAY9B;IAED;;;;;;;;;;OAUG;IACH,qBAAqB,IAAI,iBAAiB,EAAE,CAqB3C;CACF"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Handles sorting and layering of Midgard coordinates
3
+ * for rendering.
4
+ */
5
+ export class CoordinateLayer {
6
+ coordinates;
7
+ /**
8
+ * Creates a new coordinate layer.
9
+ *
10
+ * A copy of the coordinates is stored so that the original
11
+ * array is not changed.
12
+ *
13
+ * @param coordinates - The coordinates to sort and layer.
14
+ */
15
+ constructor(coordinates) {
16
+ this.coordinates = [...coordinates];
17
+ }
18
+ /**
19
+ * Sorts the coordinates by y first and x second.
20
+ *
21
+ * Coordinates with the lowest y value come first.
22
+ * Coordinates on the same y row are ordered from
23
+ * the lowest x value to the highest x value.
24
+ *
25
+ * @returns A new array containing the sorted coordinates.
26
+ */
27
+ sortCoordinates() {
28
+ const sortedCoordinates = [...this.coordinates];
29
+ sortedCoordinates.sort((firstCoordinate, secondCoordinate) => {
30
+ if (firstCoordinate.y !== secondCoordinate.y) {
31
+ return firstCoordinate.y - secondCoordinate.y;
32
+ }
33
+ return firstCoordinate.x - secondCoordinate.x;
34
+ });
35
+ return sortedCoordinates;
36
+ }
37
+ /**
38
+ * Creates layered coordinates for rendering a Midgard hex grid.
39
+ *
40
+ * Coordinates are ordered by y first and x second.
41
+ * The first y row receives z-index 100.
42
+ * Each following y row increases the z-index by 100.
43
+ *
44
+ * All coordinates on the same y row receive the same z-index.
45
+ *
46
+ * @returns Sorted coordinates with their calculated z-index.
47
+ */
48
+ getLayeredCoordinates() {
49
+ const sortedCoordinates = this.sortCoordinates();
50
+ const layeredCoordinates = [];
51
+ let previousY;
52
+ let zIndex = 0;
53
+ for (const coordinate of sortedCoordinates) {
54
+ if (coordinate.y !== previousY) {
55
+ zIndex += 100;
56
+ previousY = coordinate.y;
57
+ }
58
+ layeredCoordinates.push({
59
+ x: coordinate.x,
60
+ y: coordinate.y,
61
+ zIndex
62
+ });
63
+ }
64
+ return layeredCoordinates;
65
+ }
66
+ }
67
+ //# sourceMappingURL=coordinate-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinate-layer.js","sourceRoot":"","sources":["../src/coordinate-layer.ts"],"names":[],"mappings":"AAeA;;;GAGG;AACH,MAAM,OAAO,eAAe;IACT,WAAW,CAAc;IAE1C;;;;;;;OAOG;IACH,YAAY,WAAyB;QACnC,IAAI,CAAC,WAAW,GAAG,CAAC,GAAG,WAAW,CAAC,CAAA;IACrC,CAAC;IAED;;;;;;;;OAQG;IACH,eAAe;QACb,MAAM,iBAAiB,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAA;QAE/C,iBAAiB,CAAC,IAAI,CAAC,CAAC,eAAe,EAAE,gBAAgB,EAAE,EAAE;YAC3D,IAAI,eAAe,CAAC,CAAC,KAAK,gBAAgB,CAAC,CAAC,EAAE,CAAC;gBAC7C,OAAO,eAAe,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAA;YAC/C,CAAC;YAED,OAAO,eAAe,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAA;QAC/C,CAAC,CAAC,CAAA;QAEF,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IAED;;;;;;;;;;OAUG;IACH,qBAAqB;QACnB,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,EAAE,CAAA;QAChD,MAAM,kBAAkB,GAAwB,EAAE,CAAA;QAElD,IAAI,SAA6B,CAAA;QACjC,IAAI,MAAM,GAAG,CAAC,CAAA;QAEd,KAAK,MAAM,UAAU,IAAI,iBAAiB,EAAE,CAAC;YAC3C,IAAI,UAAU,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC/B,MAAM,IAAI,GAAG,CAAA;gBACb,SAAS,GAAG,UAAU,CAAC,CAAC,CAAA;YAC1B,CAAC;YAED,kBAAkB,CAAC,IAAI,CAAC;gBACtB,CAAC,EAAE,UAAU,CAAC,CAAC;gBACf,CAAC,EAAE,UAAU,CAAC,CAAC;gBACf,MAAM;aACP,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,kBAAkB,CAAA;IAC3B,CAAC;CACF"}
@@ -0,0 +1,49 @@
1
+ import type { Coordinate } from './coordinate.js';
2
+ import type { Point } from './geometry.js';
3
+ import type { GridOrientation } from './orientation.js';
4
+ /**
5
+ * Converts Midgard grid coordinates into geometric center positions.
6
+ *
7
+ * The calculated point represents the center of a hexagon
8
+ * in a two-dimensional coordinate system such as SVG.
9
+ */
10
+ export declare class CoordinatePositioner {
11
+ private readonly orientation;
12
+ /**
13
+ * Creates a new coordinate positioner.
14
+ *
15
+ * @param orientation - The orientation of the hex grid.
16
+ */
17
+ constructor(orientation: GridOrientation);
18
+ /**
19
+ * Calculates the center position of a Midgard coordinate.
20
+ *
21
+ * For an x-dominated grid, dimension represents the
22
+ * complete width of one hexagon.
23
+ *
24
+ * For a y-dominated grid, dimension represents the
25
+ * complete height of one hexagon.
26
+ *
27
+ * @param coordinate - The Midgard coordinate to position.
28
+ * @param dimension - The width or height of one hexagon.
29
+ * @returns The calculated center point.
30
+ */
31
+ getCenterPosition(coordinate: Coordinate, dimension: number): Point;
32
+ /**
33
+ * Calculates the center position in an x-dominated grid.
34
+ *
35
+ * @param coordinate - The Midgard coordinate to position.
36
+ * @param width - The complete width of one hexagon.
37
+ * @returns The calculated center point.
38
+ */
39
+ getXDominatedCenterPosition(coordinate: Coordinate, width: number): Point;
40
+ /**
41
+ * Calculates the center position in a y-dominated grid.
42
+ *
43
+ * @param coordinate - The Midgard coordinate to position.
44
+ * @param height - The complete height of one hexagon.
45
+ * @returns The calculated center point.
46
+ */
47
+ getYDominatedCenterPosition(coordinate: Coordinate, height: number): Point;
48
+ }
49
+ //# sourceMappingURL=coordinate-positioner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinate-positioner.d.ts","sourceRoot":"","sources":["../src/coordinate-positioner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAE1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAEvD;;;;;GAKG;AACH,qBAAa,oBAAoB;IAE/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiB;IAE7C;;;;OAIG;IACH,YAAY,WAAW,EAAE,eAAe,EAIvC;IAED;;;;;;;;;;;;OAYG;IACI,iBAAiB,CACtB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,GAChB,KAAK,CAgBP;IAED;;;;;;OAMG;IACI,2BAA2B,CAChC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,GACZ,KAAK,CAeP;IAED;;;;;;OAMG;IACI,2BAA2B,CAChC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,GACb,KAAK,CAeP;CAEF"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Converts Midgard grid coordinates into geometric center positions.
3
+ *
4
+ * The calculated point represents the center of a hexagon
5
+ * in a two-dimensional coordinate system such as SVG.
6
+ */
7
+ export class CoordinatePositioner {
8
+ orientation;
9
+ /**
10
+ * Creates a new coordinate positioner.
11
+ *
12
+ * @param orientation - The orientation of the hex grid.
13
+ */
14
+ constructor(orientation) {
15
+ this.orientation = orientation;
16
+ }
17
+ /**
18
+ * Calculates the center position of a Midgard coordinate.
19
+ *
20
+ * For an x-dominated grid, dimension represents the
21
+ * complete width of one hexagon.
22
+ *
23
+ * For a y-dominated grid, dimension represents the
24
+ * complete height of one hexagon.
25
+ *
26
+ * @param coordinate - The Midgard coordinate to position.
27
+ * @param dimension - The width or height of one hexagon.
28
+ * @returns The calculated center point.
29
+ */
30
+ getCenterPosition(coordinate, dimension) {
31
+ if (this.orientation === 'x-dominated') {
32
+ return this.getXDominatedCenterPosition(coordinate, dimension);
33
+ }
34
+ return this.getYDominatedCenterPosition(coordinate, dimension);
35
+ }
36
+ /**
37
+ * Calculates the center position in an x-dominated grid.
38
+ *
39
+ * @param coordinate - The Midgard coordinate to position.
40
+ * @param width - The complete width of one hexagon.
41
+ * @returns The calculated center point.
42
+ */
43
+ getXDominatedCenterPosition(coordinate, width) {
44
+ const hexagonHeight = (width * 2) / Math.sqrt(3);
45
+ const xStep = width / 2;
46
+ const yStep = (hexagonHeight * 3) / 4;
47
+ return {
48
+ x: coordinate.x * xStep,
49
+ y: coordinate.y * yStep
50
+ };
51
+ }
52
+ /**
53
+ * Calculates the center position in a y-dominated grid.
54
+ *
55
+ * @param coordinate - The Midgard coordinate to position.
56
+ * @param height - The complete height of one hexagon.
57
+ * @returns The calculated center point.
58
+ */
59
+ getYDominatedCenterPosition(coordinate, height) {
60
+ const hexagonWidth = (height * 2) / Math.sqrt(3);
61
+ const xStep = (hexagonWidth * 3) / 4;
62
+ const yStep = height / 2;
63
+ return {
64
+ x: coordinate.x * xStep,
65
+ y: coordinate.y * yStep
66
+ };
67
+ }
68
+ }
69
+ //# sourceMappingURL=coordinate-positioner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinate-positioner.js","sourceRoot":"","sources":["../src/coordinate-positioner.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,MAAM,OAAO,oBAAoB;IAEd,WAAW,CAAiB;IAE7C;;;;OAIG;IACH,YAAY,WAA4B;QAEtC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;IAEhC,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,iBAAiB,CACtB,UAAsB,EACtB,SAAiB;QAGjB,IAAI,IAAI,CAAC,WAAW,KAAK,aAAa,EAAE,CAAC;YAEvC,OAAO,IAAI,CAAC,2BAA2B,CACrC,UAAU,EACV,SAAS,CACV,CAAA;QAEH,CAAC;QAED,OAAO,IAAI,CAAC,2BAA2B,CACrC,UAAU,EACV,SAAS,CACV,CAAA;IAEH,CAAC;IAED;;;;;;OAMG;IACI,2BAA2B,CAChC,UAAsB,EACtB,KAAa;QAGb,MAAM,aAAa,GACjB,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAE5B,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,CAAA;QAEvB,MAAM,KAAK,GACT,CAAC,aAAa,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QAEzB,OAAO;YACL,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,KAAK;YACvB,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,KAAK;SACxB,CAAA;IAEH,CAAC;IAED;;;;;;OAMG;IACI,2BAA2B,CAChC,UAAsB,EACtB,MAAc;QAGd,MAAM,YAAY,GAChB,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAE7B,MAAM,KAAK,GACT,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QAExB,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,CAAA;QAExB,OAAO;YACL,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,KAAK;YACvB,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,KAAK;SACxB,CAAA;IAEH,CAAC;CAEF"}