@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.
- package/package.json +2 -13
- package/src/lib/components/Avatar/Avatar.svelte +82 -0
- package/src/lib/components/Avatar/AvatarFileInput.svelte +85 -0
- package/src/lib/components/Avatar/AvatarPopover.svelte +34 -0
- package/src/lib/components/Avatar/index.ts +4 -0
- package/src/lib/components/Avatar/types.ts +24 -0
- package/src/lib/components/BrushSizeSlider/BrushSizeSlider.svelte +174 -0
- package/src/lib/components/BrushSizeSlider/index.ts +1 -0
- package/src/lib/components/Button/Button.svelte +182 -0
- package/src/lib/components/Button/ConfirmActionButton.svelte +98 -0
- package/src/lib/components/Button/IconButton.svelte +121 -0
- package/src/lib/components/Button/RadioButton.svelte +93 -0
- package/src/lib/components/Button/index.ts +5 -0
- package/src/lib/components/Button/types.ts +54 -0
- package/src/lib/components/CardFan/CardFan.svelte +165 -0
- package/src/lib/components/CardFan/index.ts +2 -0
- package/src/lib/components/CardFan/types.ts +6 -0
- package/src/lib/components/CodeBlock/Code.svelte +7 -0
- package/src/lib/components/CodeBlock/CodeBlock.svelte +102 -0
- package/src/lib/components/CodeBlock/index.ts +3 -0
- package/src/lib/components/CodeBlock/types.ts +10 -0
- package/src/lib/components/ColorMode/ColorMode.svelte +8 -0
- package/src/lib/components/ColorMode/index.ts +2 -0
- package/src/lib/components/ColorMode/types.ts +12 -0
- package/src/lib/components/ColorPicker/ColorPicker.svelte +838 -0
- package/src/lib/components/ColorPicker/ColorPickerSwatch.svelte +32 -0
- package/src/lib/components/ColorPicker/index.ts +3 -0
- package/src/lib/components/ColorPicker/types.ts +51 -0
- package/src/lib/components/ContextMenu/ContextMenu.svelte +86 -0
- package/src/lib/components/ContextMenu/index.ts +2 -0
- package/src/lib/components/ContextMenu/types.ts +15 -0
- package/src/lib/components/DrawingSliders/DrawingSliders.svelte +379 -0
- package/src/lib/components/DrawingSliders/index.ts +1 -0
- package/src/lib/components/Editor/Editor.svelte +825 -0
- package/src/lib/components/Editor/index.ts +1 -0
- package/src/lib/components/FogSliders/FogSliders.svelte +33 -0
- package/src/lib/components/FogSliders/index.ts +1 -0
- package/src/lib/components/Hr/Hr.svelte +15 -0
- package/src/lib/components/Hr/index.ts +1 -0
- package/src/lib/components/Icon/Icon.svelte +6 -0
- package/src/lib/components/Icon/index.ts +2 -0
- package/src/lib/components/Icon/types.ts +20 -0
- package/src/lib/components/Input/DualInputSlider.svelte +126 -0
- package/src/lib/components/Input/FileInput.svelte +176 -0
- package/src/lib/components/Input/FormControl.svelte +150 -0
- package/src/lib/components/Input/FormError.svelte +37 -0
- package/src/lib/components/Input/Input.svelte +56 -0
- package/src/lib/components/Input/InputCheckbox.svelte +99 -0
- package/src/lib/components/Input/InputSlider.svelte +86 -0
- package/src/lib/components/Input/Label.svelte +19 -0
- package/src/lib/components/Input/index.ts +9 -0
- package/src/lib/components/Input/types.ts +39 -0
- package/src/lib/components/Link/Link.svelte +41 -0
- package/src/lib/components/Link/LinkBox.svelte +20 -0
- package/src/lib/components/Link/LinkOverlay.svelte +23 -0
- package/src/lib/components/Link/index.ts +4 -0
- package/src/lib/components/Link/types.ts +17 -0
- package/src/lib/components/Loading/Loader.svelte +60 -0
- package/src/lib/components/Loading/Skeleton.svelte +9 -0
- package/src/lib/components/Loading/index.ts +2 -0
- package/src/lib/components/Logo/Logo.svelte +16 -0
- package/src/lib/components/Logo/index.ts +1 -0
- package/src/lib/components/MarkerTooltip/MarkerTooltip.svelte +435 -0
- package/src/lib/components/MarkerTooltip/index.ts +1 -0
- package/src/lib/components/Menu/SelectorMenu.svelte +280 -0
- package/src/lib/components/Menu/index.ts +2 -0
- package/src/lib/components/Menu/types.ts +17 -0
- package/src/lib/components/MyCounterButton.svelte +11 -0
- package/src/lib/components/Panel/index.ts +2 -0
- package/src/lib/components/Panel/panel.svelte +18 -0
- package/src/lib/components/Panel/types.ts +8 -0
- package/src/lib/components/PersistButton/PersistButton.svelte +100 -0
- package/src/lib/components/PersistButton/index.ts +1 -0
- package/src/lib/components/Popover/Popover.svelte +81 -0
- package/src/lib/components/Popover/index.ts +2 -0
- package/src/lib/components/Popover/types.ts +19 -0
- package/src/lib/components/PropsTable/PropsTable.svelte +107 -0
- package/src/lib/components/RadialMenu/EffectPreview.svelte +36 -0
- package/src/lib/components/RadialMenu/EffectPreviewScene.svelte +194 -0
- package/src/lib/components/RadialMenu/RadialMenu.svelte +503 -0
- package/src/lib/components/RadialMenu/RadialMenuItem.svelte +176 -0
- package/src/lib/components/RadialMenu/index.ts +2 -0
- package/src/lib/components/RadialMenu/types.ts +35 -0
- package/src/lib/components/Select/Select.svelte +342 -0
- package/src/lib/components/Select/index.ts +2 -0
- package/src/lib/components/Select/types.ts +22 -0
- package/src/lib/components/Spacer/Spacer.svelte +14 -0
- package/src/lib/components/Spacer/index.ts +2 -0
- package/src/lib/components/Spacer/types.ts +5 -0
- package/src/lib/components/Stage/components/AnnotationLayer/AnnotationLayer.svelte +445 -0
- package/src/lib/components/Stage/components/AnnotationLayer/AnnotationMaterial.svelte +167 -0
- package/src/lib/components/Stage/components/AnnotationLayer/types.ts +196 -0
- package/src/lib/components/Stage/components/CursorLayer/CursorLayer.svelte +148 -0
- package/src/lib/components/Stage/components/CursorLayer/cursor.svg +26 -0
- package/src/lib/components/Stage/components/CursorLayer/index.ts +2 -0
- package/src/lib/components/Stage/components/CursorLayer/types.ts +23 -0
- package/src/lib/components/Stage/components/DrawingLayer/DrawingMaterial.svelte +364 -0
- package/src/lib/components/Stage/components/DrawingLayer/types.ts +65 -0
- package/src/lib/components/Stage/components/EdgeOverlayLayer/EdgeOverlayLayer.svelte +72 -0
- package/src/lib/components/Stage/components/EdgeOverlayLayer/types.ts +34 -0
- package/src/lib/components/Stage/components/FogLayer/FogLayer.svelte +75 -0
- package/src/lib/components/Stage/components/FogLayer/types.ts +51 -0
- package/src/lib/components/Stage/components/FogOfWarLayer/FogOfWarLayer.svelte +249 -0
- package/src/lib/components/Stage/components/FogOfWarLayer/FogOfWarMaterial.svelte +200 -0
- package/src/lib/components/Stage/components/FogOfWarLayer/types.ts +116 -0
- package/src/lib/components/Stage/components/GridLayer/GridLayer.svelte +20 -0
- package/src/lib/components/Stage/components/GridLayer/GridMaterial.svelte +69 -0
- package/src/lib/components/Stage/components/GridLayer/types.ts +79 -0
- package/src/lib/components/Stage/components/LayerInput/LayerInput.svelte +300 -0
- package/src/lib/components/Stage/components/MapLayer/MapLayer.svelte +196 -0
- package/src/lib/components/Stage/components/MapLayer/dataSources/GifDataSource.ts +265 -0
- package/src/lib/components/Stage/components/MapLayer/dataSources/IMapDataSource.ts +55 -0
- package/src/lib/components/Stage/components/MapLayer/dataSources/ImageDataSource.ts +87 -0
- package/src/lib/components/Stage/components/MapLayer/dataSources/VideoDataSource.ts +150 -0
- package/src/lib/components/Stage/components/MapLayer/dataSources/dataSourceFactory.ts +48 -0
- package/src/lib/components/Stage/components/MapLayer/dataSources/index.ts +16 -0
- package/src/lib/components/Stage/components/MapLayer/types.ts +58 -0
- package/src/lib/components/Stage/components/MarkerLayer/MarkerLayer.svelte +398 -0
- package/src/lib/components/Stage/components/MarkerLayer/MarkerToken.svelte +262 -0
- package/src/lib/components/Stage/components/MarkerLayer/types.ts +126 -0
- package/src/lib/components/Stage/components/MeasurementLayer/MeasurementLayer.svelte +364 -0
- package/src/lib/components/Stage/components/MeasurementLayer/MeasurementManager.svelte +473 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/BaseMeasurement.ts +427 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/BeamMeasurement.ts +105 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/CircleMeasurement.ts +98 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/ConeMeasurement.ts +163 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/LineMeasurement.ts +102 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/RectangleMeasurement.ts +120 -0
- package/src/lib/components/Stage/components/MeasurementLayer/measurements/index.ts +7 -0
- package/src/lib/components/Stage/components/MeasurementLayer/types.ts +94 -0
- package/src/lib/components/Stage/components/MeasurementLayer/utils/canvasDrawing.ts +357 -0
- package/src/lib/components/Stage/components/MeasurementLayer/utils/distanceCalculations.ts +170 -0
- package/src/lib/components/Stage/components/ParticleSystem/ParticleSystem.svelte +220 -0
- package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/ash.png +0 -0
- package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/leaves.png +0 -0
- package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/rain.png +0 -0
- package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/snow.png +0 -0
- package/src/lib/components/Stage/components/ParticleSystem/rng.js +20 -0
- package/src/lib/components/Stage/components/ParticleSystem/types.ts +95 -0
- package/src/lib/components/Stage/components/PerformanceDebugger/PerformanceDebugger.svelte +144 -0
- package/src/lib/components/Stage/components/PerformanceDebugger/index.ts +1 -0
- package/src/lib/components/Stage/components/PerformanceOverlay/PerformanceOverlay.svelte +208 -0
- package/src/lib/components/Stage/components/PerformanceOverlay/index.ts +1 -0
- package/src/lib/components/Stage/components/PointerInputManager/PointerInputManager.svelte +201 -0
- package/src/lib/components/Stage/components/Scene/Scene.svelte +651 -0
- package/src/lib/components/Stage/components/Scene/luts.ts +24 -0
- package/src/lib/components/Stage/components/Scene/types.ts +225 -0
- package/src/lib/components/Stage/components/Stage/Stage.svelte +332 -0
- package/src/lib/components/Stage/components/Stage/types.ts +136 -0
- package/src/lib/components/Stage/components/WeatherLayer/WeatherLayer.svelte +135 -0
- package/src/lib/components/Stage/components/WeatherLayer/presets/AshPreset.ts +71 -0
- package/src/lib/components/Stage/components/WeatherLayer/presets/LeavesPreset.ts +70 -0
- package/src/lib/components/Stage/components/WeatherLayer/presets/RainPreset.ts +68 -0
- package/src/lib/components/Stage/components/WeatherLayer/presets/SnowPreset.ts +70 -0
- package/src/lib/components/Stage/components/WeatherLayer/presets/index.ts +6 -0
- package/src/lib/components/Stage/components/WeatherLayer/types.ts +35 -0
- package/src/lib/components/Stage/helpers/clippingPlaneStore.svelte.ts +28 -0
- package/src/lib/components/Stage/helpers/debugState.svelte.ts +18 -0
- package/src/lib/components/Stage/helpers/grid.ts +548 -0
- package/src/lib/components/Stage/helpers/lazyBrush.ts +171 -0
- package/src/lib/components/Stage/helpers/performanceMetrics.svelte.ts +220 -0
- package/src/lib/components/Stage/helpers/utils.ts +21 -0
- package/src/lib/components/Stage/index.ts +49 -0
- package/src/lib/components/Stage/shaders/AnnotationEffects.frag +1070 -0
- package/src/lib/components/Stage/shaders/Annotations.frag +29 -0
- package/src/lib/components/Stage/shaders/Drawing.frag +83 -0
- package/src/lib/components/Stage/shaders/Drawing.vert +5 -0
- package/src/lib/components/Stage/shaders/Fog.frag +147 -0
- package/src/lib/components/Stage/shaders/FractalNoise.frag +96 -0
- package/src/lib/components/Stage/shaders/GridShader.frag +174 -0
- package/src/lib/components/Stage/shaders/Overlay.frag +23 -0
- package/src/lib/components/Stage/shaders/Overlay.vert +0 -0
- package/src/lib/components/Stage/shaders/Particles.frag +27 -0
- package/src/lib/components/Stage/shaders/Particles.vert +51 -0
- package/src/lib/components/Stage/shaders/ToolOutline.frag +59 -0
- package/src/lib/components/Stage/shaders/default.vert +8 -0
- package/src/lib/components/Stage/types.ts +4 -0
- package/src/lib/components/Table/Table.svelte +16 -0
- package/src/lib/components/Table/Td.svelte +17 -0
- package/src/lib/components/Table/Th.svelte +18 -0
- package/src/lib/components/Table/index.ts +4 -0
- package/src/lib/components/Table/types.ts +14 -0
- package/src/lib/components/Text/Text.svelte +23 -0
- package/src/lib/components/Text/index.ts +2 -0
- package/src/lib/components/Text/types.ts +12 -0
- package/src/lib/components/Title/Title.svelte +54 -0
- package/src/lib/components/Title/index.ts +2 -0
- package/src/lib/components/Title/types.ts +9 -0
- package/src/lib/components/Toast/Toast.svelte +155 -0
- package/src/lib/components/Toast/index.ts +5 -0
- package/src/lib/components/Toast/toastCookie.ts +24 -0
- package/src/lib/components/Toast/types.ts +6 -0
- package/src/lib/components/ToolTip/ToolTip.svelte +70 -0
- package/src/lib/components/ToolTip/index.ts +2 -0
- package/src/lib/components/ToolTip/types.ts +14 -0
- package/src/lib/components/index.ts +32 -0
- package/src/lib/components/types.ts +0 -0
- package/src/lib/index.ts +2 -0
- package/src/lib/styles/globals.css +108 -0
- package/src/lib/styles/normalize.css +9 -0
- package/src/lib/styles/reset.css +133 -0
- package/src/lib/styles/utilities.css +179 -0
- package/src/lib/styles/vars.css +1103 -0
- package/src/lib/types/awareness.ts +17 -0
- 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
|
+
}
|