@tableslayer/ui 0.1.3 → 0.1.4

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 (205) hide show
  1. package/package.json +2 -13
  2. package/src/lib/components/Avatar/Avatar.svelte +82 -0
  3. package/src/lib/components/Avatar/AvatarFileInput.svelte +85 -0
  4. package/src/lib/components/Avatar/AvatarPopover.svelte +34 -0
  5. package/src/lib/components/Avatar/index.ts +4 -0
  6. package/src/lib/components/Avatar/types.ts +24 -0
  7. package/src/lib/components/BrushSizeSlider/BrushSizeSlider.svelte +174 -0
  8. package/src/lib/components/BrushSizeSlider/index.ts +1 -0
  9. package/src/lib/components/Button/Button.svelte +182 -0
  10. package/src/lib/components/Button/ConfirmActionButton.svelte +98 -0
  11. package/src/lib/components/Button/IconButton.svelte +121 -0
  12. package/src/lib/components/Button/RadioButton.svelte +93 -0
  13. package/src/lib/components/Button/index.ts +5 -0
  14. package/src/lib/components/Button/types.ts +54 -0
  15. package/src/lib/components/CardFan/CardFan.svelte +165 -0
  16. package/src/lib/components/CardFan/index.ts +2 -0
  17. package/src/lib/components/CardFan/types.ts +6 -0
  18. package/src/lib/components/CodeBlock/Code.svelte +7 -0
  19. package/src/lib/components/CodeBlock/CodeBlock.svelte +102 -0
  20. package/src/lib/components/CodeBlock/index.ts +3 -0
  21. package/src/lib/components/CodeBlock/types.ts +10 -0
  22. package/src/lib/components/ColorMode/ColorMode.svelte +8 -0
  23. package/src/lib/components/ColorMode/index.ts +2 -0
  24. package/src/lib/components/ColorMode/types.ts +12 -0
  25. package/src/lib/components/ColorPicker/ColorPicker.svelte +838 -0
  26. package/src/lib/components/ColorPicker/ColorPickerSwatch.svelte +32 -0
  27. package/src/lib/components/ColorPicker/index.ts +3 -0
  28. package/src/lib/components/ColorPicker/types.ts +51 -0
  29. package/src/lib/components/ContextMenu/ContextMenu.svelte +86 -0
  30. package/src/lib/components/ContextMenu/index.ts +2 -0
  31. package/src/lib/components/ContextMenu/types.ts +15 -0
  32. package/src/lib/components/DrawingSliders/DrawingSliders.svelte +379 -0
  33. package/src/lib/components/DrawingSliders/index.ts +1 -0
  34. package/src/lib/components/Editor/Editor.svelte +825 -0
  35. package/src/lib/components/Editor/index.ts +1 -0
  36. package/src/lib/components/FogSliders/FogSliders.svelte +33 -0
  37. package/src/lib/components/FogSliders/index.ts +1 -0
  38. package/src/lib/components/Hr/Hr.svelte +15 -0
  39. package/src/lib/components/Hr/index.ts +1 -0
  40. package/src/lib/components/Icon/Icon.svelte +6 -0
  41. package/src/lib/components/Icon/index.ts +2 -0
  42. package/src/lib/components/Icon/types.ts +20 -0
  43. package/src/lib/components/Input/DualInputSlider.svelte +126 -0
  44. package/src/lib/components/Input/FileInput.svelte +176 -0
  45. package/src/lib/components/Input/FormControl.svelte +150 -0
  46. package/src/lib/components/Input/FormError.svelte +37 -0
  47. package/src/lib/components/Input/Input.svelte +56 -0
  48. package/src/lib/components/Input/InputCheckbox.svelte +99 -0
  49. package/src/lib/components/Input/InputSlider.svelte +86 -0
  50. package/src/lib/components/Input/Label.svelte +19 -0
  51. package/src/lib/components/Input/index.ts +9 -0
  52. package/src/lib/components/Input/types.ts +39 -0
  53. package/src/lib/components/Link/Link.svelte +41 -0
  54. package/src/lib/components/Link/LinkBox.svelte +20 -0
  55. package/src/lib/components/Link/LinkOverlay.svelte +23 -0
  56. package/src/lib/components/Link/index.ts +4 -0
  57. package/src/lib/components/Link/types.ts +17 -0
  58. package/src/lib/components/Loading/Loader.svelte +60 -0
  59. package/src/lib/components/Loading/Skeleton.svelte +9 -0
  60. package/src/lib/components/Loading/index.ts +2 -0
  61. package/src/lib/components/Logo/Logo.svelte +16 -0
  62. package/src/lib/components/Logo/index.ts +1 -0
  63. package/src/lib/components/MarkerTooltip/MarkerTooltip.svelte +435 -0
  64. package/src/lib/components/MarkerTooltip/index.ts +1 -0
  65. package/src/lib/components/Menu/SelectorMenu.svelte +280 -0
  66. package/src/lib/components/Menu/index.ts +2 -0
  67. package/src/lib/components/Menu/types.ts +17 -0
  68. package/src/lib/components/MyCounterButton.svelte +11 -0
  69. package/src/lib/components/Panel/index.ts +2 -0
  70. package/src/lib/components/Panel/panel.svelte +18 -0
  71. package/src/lib/components/Panel/types.ts +8 -0
  72. package/src/lib/components/PersistButton/PersistButton.svelte +100 -0
  73. package/src/lib/components/PersistButton/index.ts +1 -0
  74. package/src/lib/components/Popover/Popover.svelte +81 -0
  75. package/src/lib/components/Popover/index.ts +2 -0
  76. package/src/lib/components/Popover/types.ts +19 -0
  77. package/src/lib/components/PropsTable/PropsTable.svelte +107 -0
  78. package/src/lib/components/RadialMenu/EffectPreview.svelte +36 -0
  79. package/src/lib/components/RadialMenu/EffectPreviewScene.svelte +194 -0
  80. package/src/lib/components/RadialMenu/RadialMenu.svelte +503 -0
  81. package/src/lib/components/RadialMenu/RadialMenuItem.svelte +176 -0
  82. package/src/lib/components/RadialMenu/index.ts +2 -0
  83. package/src/lib/components/RadialMenu/types.ts +35 -0
  84. package/src/lib/components/Select/Select.svelte +342 -0
  85. package/src/lib/components/Select/index.ts +2 -0
  86. package/src/lib/components/Select/types.ts +22 -0
  87. package/src/lib/components/Spacer/Spacer.svelte +14 -0
  88. package/src/lib/components/Spacer/index.ts +2 -0
  89. package/src/lib/components/Spacer/types.ts +5 -0
  90. package/src/lib/components/Stage/components/AnnotationLayer/AnnotationLayer.svelte +445 -0
  91. package/src/lib/components/Stage/components/AnnotationLayer/AnnotationMaterial.svelte +167 -0
  92. package/src/lib/components/Stage/components/AnnotationLayer/types.ts +196 -0
  93. package/src/lib/components/Stage/components/CursorLayer/CursorLayer.svelte +148 -0
  94. package/src/lib/components/Stage/components/CursorLayer/cursor.svg +26 -0
  95. package/src/lib/components/Stage/components/CursorLayer/index.ts +2 -0
  96. package/src/lib/components/Stage/components/CursorLayer/types.ts +23 -0
  97. package/src/lib/components/Stage/components/DrawingLayer/DrawingMaterial.svelte +364 -0
  98. package/src/lib/components/Stage/components/DrawingLayer/types.ts +65 -0
  99. package/src/lib/components/Stage/components/EdgeOverlayLayer/EdgeOverlayLayer.svelte +72 -0
  100. package/src/lib/components/Stage/components/EdgeOverlayLayer/types.ts +34 -0
  101. package/src/lib/components/Stage/components/FogLayer/FogLayer.svelte +75 -0
  102. package/src/lib/components/Stage/components/FogLayer/types.ts +51 -0
  103. package/src/lib/components/Stage/components/FogOfWarLayer/FogOfWarLayer.svelte +249 -0
  104. package/src/lib/components/Stage/components/FogOfWarLayer/FogOfWarMaterial.svelte +200 -0
  105. package/src/lib/components/Stage/components/FogOfWarLayer/types.ts +116 -0
  106. package/src/lib/components/Stage/components/GridLayer/GridLayer.svelte +20 -0
  107. package/src/lib/components/Stage/components/GridLayer/GridMaterial.svelte +69 -0
  108. package/src/lib/components/Stage/components/GridLayer/types.ts +79 -0
  109. package/src/lib/components/Stage/components/LayerInput/LayerInput.svelte +300 -0
  110. package/src/lib/components/Stage/components/MapLayer/MapLayer.svelte +196 -0
  111. package/src/lib/components/Stage/components/MapLayer/dataSources/GifDataSource.ts +265 -0
  112. package/src/lib/components/Stage/components/MapLayer/dataSources/IMapDataSource.ts +55 -0
  113. package/src/lib/components/Stage/components/MapLayer/dataSources/ImageDataSource.ts +87 -0
  114. package/src/lib/components/Stage/components/MapLayer/dataSources/VideoDataSource.ts +150 -0
  115. package/src/lib/components/Stage/components/MapLayer/dataSources/dataSourceFactory.ts +48 -0
  116. package/src/lib/components/Stage/components/MapLayer/dataSources/index.ts +16 -0
  117. package/src/lib/components/Stage/components/MapLayer/types.ts +58 -0
  118. package/src/lib/components/Stage/components/MarkerLayer/MarkerLayer.svelte +398 -0
  119. package/src/lib/components/Stage/components/MarkerLayer/MarkerToken.svelte +262 -0
  120. package/src/lib/components/Stage/components/MarkerLayer/types.ts +126 -0
  121. package/src/lib/components/Stage/components/MeasurementLayer/MeasurementLayer.svelte +364 -0
  122. package/src/lib/components/Stage/components/MeasurementLayer/MeasurementManager.svelte +473 -0
  123. package/src/lib/components/Stage/components/MeasurementLayer/measurements/BaseMeasurement.ts +427 -0
  124. package/src/lib/components/Stage/components/MeasurementLayer/measurements/BeamMeasurement.ts +105 -0
  125. package/src/lib/components/Stage/components/MeasurementLayer/measurements/CircleMeasurement.ts +98 -0
  126. package/src/lib/components/Stage/components/MeasurementLayer/measurements/ConeMeasurement.ts +163 -0
  127. package/src/lib/components/Stage/components/MeasurementLayer/measurements/LineMeasurement.ts +102 -0
  128. package/src/lib/components/Stage/components/MeasurementLayer/measurements/RectangleMeasurement.ts +120 -0
  129. package/src/lib/components/Stage/components/MeasurementLayer/measurements/index.ts +7 -0
  130. package/src/lib/components/Stage/components/MeasurementLayer/types.ts +94 -0
  131. package/src/lib/components/Stage/components/MeasurementLayer/utils/canvasDrawing.ts +357 -0
  132. package/src/lib/components/Stage/components/MeasurementLayer/utils/distanceCalculations.ts +170 -0
  133. package/src/lib/components/Stage/components/ParticleSystem/ParticleSystem.svelte +220 -0
  134. package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/ash.png +0 -0
  135. package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/leaves.png +0 -0
  136. package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/rain.png +0 -0
  137. package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/snow.png +0 -0
  138. package/src/lib/components/Stage/components/ParticleSystem/rng.js +20 -0
  139. package/src/lib/components/Stage/components/ParticleSystem/types.ts +95 -0
  140. package/src/lib/components/Stage/components/PerformanceDebugger/PerformanceDebugger.svelte +144 -0
  141. package/src/lib/components/Stage/components/PerformanceDebugger/index.ts +1 -0
  142. package/src/lib/components/Stage/components/PerformanceOverlay/PerformanceOverlay.svelte +208 -0
  143. package/src/lib/components/Stage/components/PerformanceOverlay/index.ts +1 -0
  144. package/src/lib/components/Stage/components/PointerInputManager/PointerInputManager.svelte +201 -0
  145. package/src/lib/components/Stage/components/Scene/Scene.svelte +651 -0
  146. package/src/lib/components/Stage/components/Scene/luts.ts +24 -0
  147. package/src/lib/components/Stage/components/Scene/types.ts +225 -0
  148. package/src/lib/components/Stage/components/Stage/Stage.svelte +332 -0
  149. package/src/lib/components/Stage/components/Stage/types.ts +136 -0
  150. package/src/lib/components/Stage/components/WeatherLayer/WeatherLayer.svelte +135 -0
  151. package/src/lib/components/Stage/components/WeatherLayer/presets/AshPreset.ts +71 -0
  152. package/src/lib/components/Stage/components/WeatherLayer/presets/LeavesPreset.ts +70 -0
  153. package/src/lib/components/Stage/components/WeatherLayer/presets/RainPreset.ts +68 -0
  154. package/src/lib/components/Stage/components/WeatherLayer/presets/SnowPreset.ts +70 -0
  155. package/src/lib/components/Stage/components/WeatherLayer/presets/index.ts +6 -0
  156. package/src/lib/components/Stage/components/WeatherLayer/types.ts +35 -0
  157. package/src/lib/components/Stage/helpers/clippingPlaneStore.svelte.ts +28 -0
  158. package/src/lib/components/Stage/helpers/debugState.svelte.ts +18 -0
  159. package/src/lib/components/Stage/helpers/grid.ts +548 -0
  160. package/src/lib/components/Stage/helpers/lazyBrush.ts +171 -0
  161. package/src/lib/components/Stage/helpers/performanceMetrics.svelte.ts +220 -0
  162. package/src/lib/components/Stage/helpers/utils.ts +21 -0
  163. package/src/lib/components/Stage/index.ts +49 -0
  164. package/src/lib/components/Stage/shaders/AnnotationEffects.frag +1070 -0
  165. package/src/lib/components/Stage/shaders/Annotations.frag +29 -0
  166. package/src/lib/components/Stage/shaders/Drawing.frag +83 -0
  167. package/src/lib/components/Stage/shaders/Drawing.vert +5 -0
  168. package/src/lib/components/Stage/shaders/Fog.frag +147 -0
  169. package/src/lib/components/Stage/shaders/FractalNoise.frag +96 -0
  170. package/src/lib/components/Stage/shaders/GridShader.frag +174 -0
  171. package/src/lib/components/Stage/shaders/Overlay.frag +23 -0
  172. package/src/lib/components/Stage/shaders/Overlay.vert +0 -0
  173. package/src/lib/components/Stage/shaders/Particles.frag +27 -0
  174. package/src/lib/components/Stage/shaders/Particles.vert +51 -0
  175. package/src/lib/components/Stage/shaders/ToolOutline.frag +59 -0
  176. package/src/lib/components/Stage/shaders/default.vert +8 -0
  177. package/src/lib/components/Stage/types.ts +4 -0
  178. package/src/lib/components/Table/Table.svelte +16 -0
  179. package/src/lib/components/Table/Td.svelte +17 -0
  180. package/src/lib/components/Table/Th.svelte +18 -0
  181. package/src/lib/components/Table/index.ts +4 -0
  182. package/src/lib/components/Table/types.ts +14 -0
  183. package/src/lib/components/Text/Text.svelte +23 -0
  184. package/src/lib/components/Text/index.ts +2 -0
  185. package/src/lib/components/Text/types.ts +12 -0
  186. package/src/lib/components/Title/Title.svelte +54 -0
  187. package/src/lib/components/Title/index.ts +2 -0
  188. package/src/lib/components/Title/types.ts +9 -0
  189. package/src/lib/components/Toast/Toast.svelte +155 -0
  190. package/src/lib/components/Toast/index.ts +5 -0
  191. package/src/lib/components/Toast/toastCookie.ts +24 -0
  192. package/src/lib/components/Toast/types.ts +6 -0
  193. package/src/lib/components/ToolTip/ToolTip.svelte +70 -0
  194. package/src/lib/components/ToolTip/index.ts +2 -0
  195. package/src/lib/components/ToolTip/types.ts +14 -0
  196. package/src/lib/components/index.ts +32 -0
  197. package/src/lib/components/types.ts +0 -0
  198. package/src/lib/index.ts +2 -0
  199. package/src/lib/styles/globals.css +108 -0
  200. package/src/lib/styles/normalize.css +9 -0
  201. package/src/lib/styles/reset.css +133 -0
  202. package/src/lib/styles/utilities.css +179 -0
  203. package/src/lib/styles/vars.css +1103 -0
  204. package/src/lib/types/awareness.ts +17 -0
  205. package/src/lib/utils/rle.ts +217 -0
@@ -0,0 +1,357 @@
1
+ /**
2
+ * Utility functions for drawing shapes on canvas
3
+ */
4
+
5
+ /**
6
+ * Draws a line, optionally with an outline
7
+ * @param context Canvas 2D context
8
+ * @param startX Start X coordinate
9
+ * @param startY Start Y coordinate
10
+ * @param endX End X coordinate
11
+ * @param endY End Y coordinate
12
+ * @param color Line color
13
+ * @param thickness Line thickness
14
+ * @param outlineColor Optional outline color
15
+ * @param outlineThickness Optional outline thickness
16
+ */
17
+ export function drawLine(
18
+ context: CanvasRenderingContext2D,
19
+ startX: number,
20
+ startY: number,
21
+ endX: number,
22
+ endY: number,
23
+ color: string,
24
+ thickness: number,
25
+ outlineColor?: string,
26
+ outlineThickness?: number
27
+ ): void {
28
+ // Draw outline if specified
29
+ if (outlineColor && outlineThickness) {
30
+ context.strokeStyle = outlineColor;
31
+ context.lineWidth = thickness + outlineThickness * 2;
32
+ context.lineCap = 'round';
33
+ context.lineJoin = 'round';
34
+ context.beginPath();
35
+ context.moveTo(startX, startY);
36
+ context.lineTo(endX, endY);
37
+ context.stroke();
38
+ }
39
+
40
+ // Draw the line
41
+ context.strokeStyle = color;
42
+ context.lineWidth = thickness;
43
+ context.lineCap = 'round';
44
+ context.lineJoin = 'round';
45
+ context.beginPath();
46
+ context.moveTo(startX, startY);
47
+ context.lineTo(endX, endY);
48
+ context.stroke();
49
+ }
50
+
51
+ /**
52
+ * Draws a circle, optionally with an outline
53
+ * @param context Canvas 2D context
54
+ * @param x Center X coordinate
55
+ * @param y Center Y coordinate
56
+ * @param radius Circle radius
57
+ * @param color Circle color
58
+ * @param outlineColor Optional outline color
59
+ * @param outlineThickness Optional outline thickness
60
+ */
61
+ export function drawCircle(
62
+ context: CanvasRenderingContext2D,
63
+ x: number,
64
+ y: number,
65
+ radius: number,
66
+ color: string,
67
+ outlineColor?: string,
68
+ outlineThickness?: number
69
+ ): void {
70
+ // Draw outline if specified
71
+ if (outlineColor && outlineThickness) {
72
+ context.beginPath();
73
+ context.arc(x, y, radius + outlineThickness, 0, Math.PI * 2);
74
+ context.fillStyle = outlineColor;
75
+ context.fill();
76
+ }
77
+
78
+ // Draw the circle
79
+ context.beginPath();
80
+ context.arc(x, y, radius, 0, Math.PI * 2);
81
+ context.fillStyle = color;
82
+ context.fill();
83
+ }
84
+
85
+ /**
86
+ * Draws a large circle with stroke and optional fill
87
+ * @param context Canvas 2D context
88
+ * @param x Center X coordinate
89
+ * @param y Center Y coordinate
90
+ * @param radius Circle radius
91
+ * @param strokeColor Stroke color
92
+ * @param strokeThickness Stroke thickness
93
+ * @param fillColor Optional fill color
94
+ * @param fillOpacity Optional fill opacity (0-1)
95
+ * @param outlineColor Optional outline color
96
+ * @param outlineThickness Optional outline thickness
97
+ */
98
+ export function drawLargeCircle(
99
+ context: CanvasRenderingContext2D,
100
+ x: number,
101
+ y: number,
102
+ radius: number,
103
+ strokeColor: string,
104
+ strokeThickness: number,
105
+ fillColor?: string,
106
+ fillOpacity?: number,
107
+ outlineColor?: string,
108
+ outlineThickness?: number
109
+ ): void {
110
+ // Draw fill if specified
111
+ if (fillColor && fillOpacity !== undefined) {
112
+ const originalAlpha = context.globalAlpha;
113
+ context.globalAlpha = fillOpacity;
114
+ context.fillStyle = fillColor;
115
+ context.beginPath();
116
+ context.arc(x, y, radius, 0, 2 * Math.PI);
117
+ context.fill();
118
+ context.globalAlpha = originalAlpha;
119
+ }
120
+
121
+ // Draw outline if specified
122
+ if (outlineColor && outlineThickness) {
123
+ context.strokeStyle = outlineColor;
124
+ context.lineWidth = strokeThickness + outlineThickness * 2;
125
+ context.beginPath();
126
+ context.arc(x, y, radius, 0, 2 * Math.PI);
127
+ context.stroke();
128
+ }
129
+
130
+ // Draw the main stroke
131
+ context.strokeStyle = strokeColor;
132
+ context.lineWidth = strokeThickness;
133
+ context.beginPath();
134
+ context.arc(x, y, radius, 0, 2 * Math.PI);
135
+ context.stroke();
136
+ }
137
+
138
+ /**
139
+ * Draws a rectangle with stroke and optional fill
140
+ * @param context Canvas 2D context
141
+ * @param x Top-left X coordinate
142
+ * @param y Top-left Y coordinate
143
+ * @param width Rectangle width
144
+ * @param height Rectangle height
145
+ * @param strokeColor Stroke color
146
+ * @param strokeThickness Stroke thickness
147
+ * @param fillColor Optional fill color
148
+ * @param fillOpacity Optional fill opacity (0-1)
149
+ * @param outlineColor Optional outline color
150
+ * @param outlineThickness Optional outline thickness
151
+ */
152
+ export function drawRectangle(
153
+ context: CanvasRenderingContext2D,
154
+ x: number,
155
+ y: number,
156
+ width: number,
157
+ height: number,
158
+ strokeColor: string,
159
+ strokeThickness: number,
160
+ fillColor?: string,
161
+ fillOpacity?: number,
162
+ outlineColor?: string,
163
+ outlineThickness?: number
164
+ ): void {
165
+ // Draw fill if specified
166
+ if (fillColor && fillOpacity !== undefined) {
167
+ const originalAlpha = context.globalAlpha;
168
+ context.globalAlpha = fillOpacity;
169
+ context.fillStyle = fillColor;
170
+ context.fillRect(x, y, width, height);
171
+ context.globalAlpha = originalAlpha;
172
+ }
173
+
174
+ // Draw outline if specified
175
+ if (outlineColor && outlineThickness) {
176
+ context.strokeStyle = outlineColor;
177
+ context.lineWidth = strokeThickness + outlineThickness * 2;
178
+ context.strokeRect(x, y, width, height);
179
+ }
180
+
181
+ // Draw the main stroke
182
+ context.strokeStyle = strokeColor;
183
+ context.lineWidth = strokeThickness;
184
+ context.strokeRect(x, y, width, height);
185
+ }
186
+
187
+ /**
188
+ * Draws a cone/sector with stroke and optional fill
189
+ * @param context Canvas 2D context
190
+ * @param x Center X coordinate
191
+ * @param y Center Y coordinate
192
+ * @param radius Cone radius
193
+ * @param startAngle Start angle in radians
194
+ * @param endAngle End angle in radians
195
+ * @param strokeColor Stroke color
196
+ * @param strokeThickness Stroke thickness
197
+ * @param fillColor Optional fill color
198
+ * @param fillOpacity Optional fill opacity (0-1)
199
+ * @param outlineColor Optional outline color
200
+ * @param outlineThickness Optional outline thickness
201
+ */
202
+ export function drawCone(
203
+ context: CanvasRenderingContext2D,
204
+ x: number,
205
+ y: number,
206
+ radius: number,
207
+ startAngle: number,
208
+ endAngle: number,
209
+ strokeColor: string,
210
+ strokeThickness: number,
211
+ fillColor?: string,
212
+ fillOpacity?: number,
213
+ outlineColor?: string,
214
+ outlineThickness?: number
215
+ ): void {
216
+ // Invert angles for canvas coordinate system (Y increases downward)
217
+ const invertedStartAngle = -endAngle;
218
+ const invertedEndAngle = -startAngle;
219
+
220
+ // Draw fill if specified
221
+ if (fillColor && fillOpacity !== undefined) {
222
+ const originalAlpha = context.globalAlpha;
223
+ context.globalAlpha = fillOpacity;
224
+ context.fillStyle = fillColor;
225
+ context.beginPath();
226
+ context.moveTo(x, y);
227
+ context.arc(x, y, radius, invertedStartAngle, invertedEndAngle);
228
+ context.closePath();
229
+ context.fill();
230
+ context.globalAlpha = originalAlpha;
231
+ }
232
+
233
+ // Draw outline if specified
234
+ if (outlineColor && outlineThickness) {
235
+ context.strokeStyle = outlineColor;
236
+ context.lineWidth = strokeThickness + outlineThickness * 2;
237
+ context.beginPath();
238
+ context.moveTo(x, y);
239
+ context.arc(x, y, radius, invertedStartAngle, invertedEndAngle);
240
+ context.closePath();
241
+ context.stroke();
242
+ }
243
+
244
+ // Draw the main stroke
245
+ context.strokeStyle = strokeColor;
246
+ context.lineWidth = strokeThickness;
247
+ context.beginPath();
248
+ context.moveTo(x, y);
249
+ context.arc(x, y, radius, invertedStartAngle, invertedEndAngle);
250
+ context.closePath();
251
+ context.stroke();
252
+ }
253
+
254
+ /**
255
+ * Creates a text canvas with consistent styling
256
+ * @param text The text to display
257
+ * @param fontSize Font size in pixels
258
+ * @param color Text color
259
+ * @param outlineColor Outline color
260
+ * @param outlineThickness Outline thickness
261
+ * @param units Optional units text to display in smaller font
262
+ * @returns Canvas element with rendered text
263
+ */
264
+ export function createTextCanvas(
265
+ text: string,
266
+ fontSize: number,
267
+ color: string,
268
+ outlineColor: string = '#000000',
269
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
270
+ _outlineThickness: number = 16,
271
+ units?: string
272
+ ): HTMLCanvasElement {
273
+ const canvas = document.createElement('canvas');
274
+ const context = canvas.getContext('2d', { colorSpace: 'srgb' })!;
275
+
276
+ // Set canvas size
277
+ canvas.width = 256;
278
+ canvas.height = 256;
279
+
280
+ // Set composite operation to ensure proper alpha blending
281
+ context.globalCompositeOperation = 'source-over';
282
+
283
+ // Clear canvas to fully transparent (alpha = 0)
284
+ context.clearRect(0, 0, canvas.width, canvas.height);
285
+
286
+ // Set text properties with semi-bold font
287
+ context.font = `600 ${fontSize}px Inter`;
288
+ context.textAlign = 'center';
289
+ context.textBaseline = 'alphabetic';
290
+
291
+ if (units) {
292
+ // Split rendering for number and units
293
+ const unitsFontSize = fontSize * 0.5; // 50% of the main font size
294
+
295
+ // Measure both parts with the same font we'll use for drawing
296
+ context.font = `600 ${fontSize}px Inter`;
297
+ const numberWidth = context.measureText(text).width;
298
+ context.font = `600 ${unitsFontSize}px Inter`;
299
+ const unitsWidth = context.measureText(' ' + units).width;
300
+ const totalWidth = numberWidth + unitsWidth;
301
+
302
+ // Calculate padding for the background box
303
+ const padding = fontSize * 0.3;
304
+ const boxWidth = totalWidth + padding * 2;
305
+ const boxHeight = fontSize + padding;
306
+ const boxX = (canvas.width - boxWidth) / 2;
307
+ const boxY = (canvas.height - boxHeight) / 2;
308
+
309
+ // Draw background box
310
+ context.fillStyle = color;
311
+ context.fillRect(boxX, boxY, boxWidth, boxHeight);
312
+
313
+ // Calculate starting position to center the combined text
314
+ const startX = (canvas.width - totalWidth) / 2;
315
+ // Center the text vertically - the baseline should be at the vertical center plus some offset
316
+ const baselineY = canvas.height / 2 + fontSize * 0.35;
317
+
318
+ // Draw number text
319
+ context.font = `600 ${fontSize}px Inter`;
320
+ context.textAlign = 'left';
321
+ context.textBaseline = 'alphabetic';
322
+ context.fillStyle = outlineColor;
323
+ context.fillText(text, startX, baselineY);
324
+
325
+ // Re-measure the actual rendered width to ensure proper spacing
326
+ const actualNumberWidth = context.measureText(text).width;
327
+
328
+ // Draw units text in smaller font, aligned to same baseline
329
+ context.font = `600 ${unitsFontSize}px Inter`;
330
+ context.textBaseline = 'alphabetic';
331
+ context.fillText(' ' + units, startX + actualNumberWidth, baselineY);
332
+ } else {
333
+ // Original behavior for text without units
334
+ // Measure text for box dimensions
335
+ context.font = `600 ${fontSize}px Inter`;
336
+ const textMetrics = context.measureText(text);
337
+ const padding = fontSize * 0.3;
338
+ const boxWidth = textMetrics.width + padding * 2;
339
+ const boxHeight = fontSize + padding;
340
+ const boxX = (canvas.width - boxWidth) / 2;
341
+ const boxY = (canvas.height - boxHeight) / 2;
342
+
343
+ // Draw background box
344
+ context.fillStyle = color;
345
+ context.fillRect(boxX, boxY, boxWidth, boxHeight);
346
+
347
+ // Center the text vertically - the baseline should be at the vertical center plus some offset
348
+ const baselineY = canvas.height / 2 + fontSize * 0.35;
349
+
350
+ // Draw text on top
351
+ context.textBaseline = 'alphabetic';
352
+ context.fillStyle = outlineColor;
353
+ context.fillText(text, canvas.width / 2, baselineY);
354
+ }
355
+
356
+ return canvas;
357
+ }
@@ -0,0 +1,170 @@
1
+ import * as THREE from 'three';
2
+ import { hexDistance, pixelToHex, type HexCoordinate } from '../../../helpers/grid';
3
+ import { GridType } from '../../GridLayer/types';
4
+
5
+ /**
6
+ * Calculate hex grid distance between two points
7
+ * @param startPoint Start point in pixel coordinates
8
+ * @param endPoint End point in pixel coordinates
9
+ * @param gridSpacing Grid spacing in inches
10
+ * @param displaySize Display size in inches
11
+ * @param displayResolution Display resolution in pixels
12
+ * @param worldGridSize The real-world size of one hex
13
+ * @param returnHexCount If true, returns hex count instead of world units
14
+ * @returns Distance in world grid units or hex count
15
+ */
16
+ export function calculateHexGridDistance(
17
+ startPoint: THREE.Vector2,
18
+ endPoint: THREE.Vector2,
19
+ gridSpacing: number,
20
+ displaySize: { x: number; y: number },
21
+ displayResolution: { x: number; y: number },
22
+ worldGridSize: number = 5,
23
+ returnHexCount: boolean = false
24
+ ): number {
25
+ // Convert pixel coordinates to world coordinates (inches)
26
+ const pixelsPerInchX = displayResolution.x / displaySize.x;
27
+
28
+ // Calculate hex size in pixels
29
+ // The grid spacing represents the distance between hex centers
30
+ // For pointy-top hexagons, this is the width of the hex
31
+ const hexSizePixels = gridSpacing * pixelsPerInchX;
32
+
33
+ // Convert points to hex coordinates
34
+ const startHex = pixelToHex(startPoint, hexSizePixels) as HexCoordinate & { isGrid2?: boolean };
35
+ const endHex = pixelToHex(endPoint, hexSizePixels) as HexCoordinate & { isGrid2?: boolean };
36
+
37
+ // Calculate distance in hex units
38
+ const hexes = hexDistance(startHex, endHex);
39
+
40
+ // Return either hex count or world units
41
+ return returnHexCount ? hexes : hexes * worldGridSize;
42
+ }
43
+
44
+ /**
45
+ * Calculate grid-based distance between two points
46
+ * @param startPoint Start point in pixel coordinates
47
+ * @param endPoint End point in pixel coordinates
48
+ * @param gridSpacing Grid spacing in inches
49
+ * @param displaySize Display size in inches
50
+ * @param displayResolution Display resolution in pixels
51
+ * @param gridType Type of grid (square or hex)
52
+ * @param snapToGrid Whether snapping is enabled
53
+ * @param enableDMG252 Whether to use DMG 252 diagonal rules
54
+ * @param worldGridSize The real-world size of one grid square
55
+ * @param worldGridUnits The units for the world grid size
56
+ * @returns Distance in world grid units
57
+ */
58
+ export function calculateLineDistance(
59
+ startPoint: THREE.Vector2,
60
+ endPoint: THREE.Vector2,
61
+ gridSpacing: number,
62
+ displaySize: { x: number; y: number },
63
+ displayResolution: { x: number; y: number },
64
+ gridType: GridType = GridType.Square,
65
+ snapToGrid: boolean = false,
66
+ enableDMG252: boolean = false,
67
+ worldGridSize: number = 5,
68
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
69
+ _worldGridUnits: string = 'FT'
70
+ ): number {
71
+ // For hex grids with snapping enabled, use hex pathfinding
72
+ if (gridType === GridType.Hex && snapToGrid) {
73
+ return calculateHexGridDistance(startPoint, endPoint, gridSpacing, displaySize, displayResolution, worldGridSize);
74
+ }
75
+
76
+ // Convert pixel coordinates to world coordinates (inches)
77
+ const pixelsPerInchX = displayResolution.x / displaySize.x;
78
+ const pixelsPerInchY = displayResolution.y / displaySize.y;
79
+
80
+ // Convert to inches
81
+ const startInches = new THREE.Vector2(startPoint.x / pixelsPerInchX, startPoint.y / pixelsPerInchY);
82
+ const endInches = new THREE.Vector2(endPoint.x / pixelsPerInchX, endPoint.y / pixelsPerInchY);
83
+
84
+ // If DMG 252 rules are enabled and we're snapping to a square grid
85
+ if (enableDMG252 && snapToGrid && gridType === GridType.Square) {
86
+ // Convert to grid coordinates (number of grid squares)
87
+ const startGrid = new THREE.Vector2(startInches.x / gridSpacing, startInches.y / gridSpacing);
88
+ const endGrid = new THREE.Vector2(endInches.x / gridSpacing, endInches.y / gridSpacing);
89
+
90
+ // Calculate grid distance using DMG 252 rules, then convert to world units
91
+ const gridDistance = calculateDMG252Distance(startGrid, endGrid);
92
+ return gridDistance * worldGridSize;
93
+ }
94
+
95
+ // Standard distance calculation - convert to world grid units
96
+ const distanceInches = startInches.distanceTo(endInches);
97
+ const gridDistance = distanceInches / gridSpacing;
98
+ return gridDistance * worldGridSize;
99
+ }
100
+
101
+ /**
102
+ * Calculate D&D diagonal movement distance
103
+ * In D&D, diagonal movement costs 1.5 times normal movement
104
+ * This is implemented as: max(dx, dy) + min(dx, dy) * 0.5
105
+ */
106
+ export function calculateDnDDiagonalDistance(startPoint: THREE.Vector2, endPoint: THREE.Vector2): number {
107
+ const dx = Math.abs(endPoint.x - startPoint.x);
108
+ const dy = Math.abs(endPoint.y - startPoint.y);
109
+ return Math.max(dx, dy) + Math.min(dx, dy) * 0.5;
110
+ }
111
+
112
+ /**
113
+ * Calculate distance using DMG 252 diagonal movement rules
114
+ * First diagonal = 1 grid unit, second = 2 grid units, alternating
115
+ * Only applies when snapping to square grid
116
+ */
117
+ export function calculateDMG252Distance(startPoint: THREE.Vector2, endPoint: THREE.Vector2): number {
118
+ const dx = Math.abs(endPoint.x - startPoint.x);
119
+ const dy = Math.abs(endPoint.y - startPoint.y);
120
+
121
+ // Get the number of diagonal and straight moves
122
+ const diagonalMoves = Math.min(dx, dy);
123
+ const straightMoves = Math.max(dx, dy) - diagonalMoves;
124
+
125
+ // Calculate diagonal cost using DMG 252 rules
126
+ // Every other diagonal costs 2 units instead of 1
127
+ const fullDiagonalPairs = Math.floor(diagonalMoves / 2);
128
+ const remainingDiagonals = diagonalMoves % 2;
129
+
130
+ const diagonalCost = fullDiagonalPairs * 3 + remainingDiagonals * 1; // 3 = 1 + 2 for each pair
131
+ const straightCost = straightMoves;
132
+
133
+ return diagonalCost + straightCost;
134
+ }
135
+
136
+ /**
137
+ * Calculate radius from center point to edge point
138
+ */
139
+ export function calculateRadius(centerPoint: THREE.Vector2, edgePoint: THREE.Vector2): number {
140
+ return centerPoint.distanceTo(edgePoint);
141
+ }
142
+
143
+ /**
144
+ * Calculate area of a circle
145
+ */
146
+ export function calculateCircleArea(radius: number): number {
147
+ return Math.PI * radius * radius;
148
+ }
149
+
150
+ /**
151
+ * Calculate area of a square
152
+ */
153
+ export function calculateSquareArea(sideLength: number): number {
154
+ return sideLength * sideLength;
155
+ }
156
+
157
+ /**
158
+ * Convert pixels to game units (assuming 1 inch = 1 unit)
159
+ * This is a placeholder - actual conversion depends on grid scale
160
+ */
161
+ export function pixelsToUnits(pixels: number, pixelsPerUnit: number = 1): number {
162
+ return pixels / pixelsPerUnit;
163
+ }
164
+
165
+ /**
166
+ * Convert game units to pixels
167
+ */
168
+ export function unitsToPixels(units: number, pixelsPerUnit: number = 1): number {
169
+ return units * pixelsPerUnit;
170
+ }