@tableslayer/ui 0.1.4 → 0.1.5

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 (206) hide show
  1. package/dist/components/PropsTable/PropsTable.svelte +1 -1
  2. package/package.json +9 -9
  3. package/src/lib/components/Avatar/Avatar.svelte +0 -82
  4. package/src/lib/components/Avatar/AvatarFileInput.svelte +0 -85
  5. package/src/lib/components/Avatar/AvatarPopover.svelte +0 -34
  6. package/src/lib/components/Avatar/index.ts +0 -4
  7. package/src/lib/components/Avatar/types.ts +0 -24
  8. package/src/lib/components/BrushSizeSlider/BrushSizeSlider.svelte +0 -174
  9. package/src/lib/components/BrushSizeSlider/index.ts +0 -1
  10. package/src/lib/components/Button/Button.svelte +0 -182
  11. package/src/lib/components/Button/ConfirmActionButton.svelte +0 -98
  12. package/src/lib/components/Button/IconButton.svelte +0 -121
  13. package/src/lib/components/Button/RadioButton.svelte +0 -93
  14. package/src/lib/components/Button/index.ts +0 -5
  15. package/src/lib/components/Button/types.ts +0 -54
  16. package/src/lib/components/CardFan/CardFan.svelte +0 -165
  17. package/src/lib/components/CardFan/index.ts +0 -2
  18. package/src/lib/components/CardFan/types.ts +0 -6
  19. package/src/lib/components/CodeBlock/Code.svelte +0 -7
  20. package/src/lib/components/CodeBlock/CodeBlock.svelte +0 -102
  21. package/src/lib/components/CodeBlock/index.ts +0 -3
  22. package/src/lib/components/CodeBlock/types.ts +0 -10
  23. package/src/lib/components/ColorMode/ColorMode.svelte +0 -8
  24. package/src/lib/components/ColorMode/index.ts +0 -2
  25. package/src/lib/components/ColorMode/types.ts +0 -12
  26. package/src/lib/components/ColorPicker/ColorPicker.svelte +0 -838
  27. package/src/lib/components/ColorPicker/ColorPickerSwatch.svelte +0 -32
  28. package/src/lib/components/ColorPicker/index.ts +0 -3
  29. package/src/lib/components/ColorPicker/types.ts +0 -51
  30. package/src/lib/components/ContextMenu/ContextMenu.svelte +0 -86
  31. package/src/lib/components/ContextMenu/index.ts +0 -2
  32. package/src/lib/components/ContextMenu/types.ts +0 -15
  33. package/src/lib/components/DrawingSliders/DrawingSliders.svelte +0 -379
  34. package/src/lib/components/DrawingSliders/index.ts +0 -1
  35. package/src/lib/components/Editor/Editor.svelte +0 -825
  36. package/src/lib/components/Editor/index.ts +0 -1
  37. package/src/lib/components/FogSliders/FogSliders.svelte +0 -33
  38. package/src/lib/components/FogSliders/index.ts +0 -1
  39. package/src/lib/components/Hr/Hr.svelte +0 -15
  40. package/src/lib/components/Hr/index.ts +0 -1
  41. package/src/lib/components/Icon/Icon.svelte +0 -6
  42. package/src/lib/components/Icon/index.ts +0 -2
  43. package/src/lib/components/Icon/types.ts +0 -20
  44. package/src/lib/components/Input/DualInputSlider.svelte +0 -126
  45. package/src/lib/components/Input/FileInput.svelte +0 -176
  46. package/src/lib/components/Input/FormControl.svelte +0 -150
  47. package/src/lib/components/Input/FormError.svelte +0 -37
  48. package/src/lib/components/Input/Input.svelte +0 -56
  49. package/src/lib/components/Input/InputCheckbox.svelte +0 -99
  50. package/src/lib/components/Input/InputSlider.svelte +0 -86
  51. package/src/lib/components/Input/Label.svelte +0 -19
  52. package/src/lib/components/Input/index.ts +0 -9
  53. package/src/lib/components/Input/types.ts +0 -39
  54. package/src/lib/components/Link/Link.svelte +0 -41
  55. package/src/lib/components/Link/LinkBox.svelte +0 -20
  56. package/src/lib/components/Link/LinkOverlay.svelte +0 -23
  57. package/src/lib/components/Link/index.ts +0 -4
  58. package/src/lib/components/Link/types.ts +0 -17
  59. package/src/lib/components/Loading/Loader.svelte +0 -60
  60. package/src/lib/components/Loading/Skeleton.svelte +0 -9
  61. package/src/lib/components/Loading/index.ts +0 -2
  62. package/src/lib/components/Logo/Logo.svelte +0 -16
  63. package/src/lib/components/Logo/index.ts +0 -1
  64. package/src/lib/components/MarkerTooltip/MarkerTooltip.svelte +0 -435
  65. package/src/lib/components/MarkerTooltip/index.ts +0 -1
  66. package/src/lib/components/Menu/SelectorMenu.svelte +0 -280
  67. package/src/lib/components/Menu/index.ts +0 -2
  68. package/src/lib/components/Menu/types.ts +0 -17
  69. package/src/lib/components/MyCounterButton.svelte +0 -11
  70. package/src/lib/components/Panel/index.ts +0 -2
  71. package/src/lib/components/Panel/panel.svelte +0 -18
  72. package/src/lib/components/Panel/types.ts +0 -8
  73. package/src/lib/components/PersistButton/PersistButton.svelte +0 -100
  74. package/src/lib/components/PersistButton/index.ts +0 -1
  75. package/src/lib/components/Popover/Popover.svelte +0 -81
  76. package/src/lib/components/Popover/index.ts +0 -2
  77. package/src/lib/components/Popover/types.ts +0 -19
  78. package/src/lib/components/PropsTable/PropsTable.svelte +0 -107
  79. package/src/lib/components/RadialMenu/EffectPreview.svelte +0 -36
  80. package/src/lib/components/RadialMenu/EffectPreviewScene.svelte +0 -194
  81. package/src/lib/components/RadialMenu/RadialMenu.svelte +0 -503
  82. package/src/lib/components/RadialMenu/RadialMenuItem.svelte +0 -176
  83. package/src/lib/components/RadialMenu/index.ts +0 -2
  84. package/src/lib/components/RadialMenu/types.ts +0 -35
  85. package/src/lib/components/Select/Select.svelte +0 -342
  86. package/src/lib/components/Select/index.ts +0 -2
  87. package/src/lib/components/Select/types.ts +0 -22
  88. package/src/lib/components/Spacer/Spacer.svelte +0 -14
  89. package/src/lib/components/Spacer/index.ts +0 -2
  90. package/src/lib/components/Spacer/types.ts +0 -5
  91. package/src/lib/components/Stage/components/AnnotationLayer/AnnotationLayer.svelte +0 -445
  92. package/src/lib/components/Stage/components/AnnotationLayer/AnnotationMaterial.svelte +0 -167
  93. package/src/lib/components/Stage/components/AnnotationLayer/types.ts +0 -196
  94. package/src/lib/components/Stage/components/CursorLayer/CursorLayer.svelte +0 -148
  95. package/src/lib/components/Stage/components/CursorLayer/cursor.svg +0 -26
  96. package/src/lib/components/Stage/components/CursorLayer/index.ts +0 -2
  97. package/src/lib/components/Stage/components/CursorLayer/types.ts +0 -23
  98. package/src/lib/components/Stage/components/DrawingLayer/DrawingMaterial.svelte +0 -364
  99. package/src/lib/components/Stage/components/DrawingLayer/types.ts +0 -65
  100. package/src/lib/components/Stage/components/EdgeOverlayLayer/EdgeOverlayLayer.svelte +0 -72
  101. package/src/lib/components/Stage/components/EdgeOverlayLayer/types.ts +0 -34
  102. package/src/lib/components/Stage/components/FogLayer/FogLayer.svelte +0 -75
  103. package/src/lib/components/Stage/components/FogLayer/types.ts +0 -51
  104. package/src/lib/components/Stage/components/FogOfWarLayer/FogOfWarLayer.svelte +0 -249
  105. package/src/lib/components/Stage/components/FogOfWarLayer/FogOfWarMaterial.svelte +0 -200
  106. package/src/lib/components/Stage/components/FogOfWarLayer/types.ts +0 -116
  107. package/src/lib/components/Stage/components/GridLayer/GridLayer.svelte +0 -20
  108. package/src/lib/components/Stage/components/GridLayer/GridMaterial.svelte +0 -69
  109. package/src/lib/components/Stage/components/GridLayer/types.ts +0 -79
  110. package/src/lib/components/Stage/components/LayerInput/LayerInput.svelte +0 -300
  111. package/src/lib/components/Stage/components/MapLayer/MapLayer.svelte +0 -196
  112. package/src/lib/components/Stage/components/MapLayer/dataSources/GifDataSource.ts +0 -265
  113. package/src/lib/components/Stage/components/MapLayer/dataSources/IMapDataSource.ts +0 -55
  114. package/src/lib/components/Stage/components/MapLayer/dataSources/ImageDataSource.ts +0 -87
  115. package/src/lib/components/Stage/components/MapLayer/dataSources/VideoDataSource.ts +0 -150
  116. package/src/lib/components/Stage/components/MapLayer/dataSources/dataSourceFactory.ts +0 -48
  117. package/src/lib/components/Stage/components/MapLayer/dataSources/index.ts +0 -16
  118. package/src/lib/components/Stage/components/MapLayer/types.ts +0 -58
  119. package/src/lib/components/Stage/components/MarkerLayer/MarkerLayer.svelte +0 -398
  120. package/src/lib/components/Stage/components/MarkerLayer/MarkerToken.svelte +0 -262
  121. package/src/lib/components/Stage/components/MarkerLayer/types.ts +0 -126
  122. package/src/lib/components/Stage/components/MeasurementLayer/MeasurementLayer.svelte +0 -364
  123. package/src/lib/components/Stage/components/MeasurementLayer/MeasurementManager.svelte +0 -473
  124. package/src/lib/components/Stage/components/MeasurementLayer/measurements/BaseMeasurement.ts +0 -427
  125. package/src/lib/components/Stage/components/MeasurementLayer/measurements/BeamMeasurement.ts +0 -105
  126. package/src/lib/components/Stage/components/MeasurementLayer/measurements/CircleMeasurement.ts +0 -98
  127. package/src/lib/components/Stage/components/MeasurementLayer/measurements/ConeMeasurement.ts +0 -163
  128. package/src/lib/components/Stage/components/MeasurementLayer/measurements/LineMeasurement.ts +0 -102
  129. package/src/lib/components/Stage/components/MeasurementLayer/measurements/RectangleMeasurement.ts +0 -120
  130. package/src/lib/components/Stage/components/MeasurementLayer/measurements/index.ts +0 -7
  131. package/src/lib/components/Stage/components/MeasurementLayer/types.ts +0 -94
  132. package/src/lib/components/Stage/components/MeasurementLayer/utils/canvasDrawing.ts +0 -357
  133. package/src/lib/components/Stage/components/MeasurementLayer/utils/distanceCalculations.ts +0 -170
  134. package/src/lib/components/Stage/components/ParticleSystem/ParticleSystem.svelte +0 -220
  135. package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/ash.png +0 -0
  136. package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/leaves.png +0 -0
  137. package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/rain.png +0 -0
  138. package/src/lib/components/Stage/components/ParticleSystem/particles/atlases/snow.png +0 -0
  139. package/src/lib/components/Stage/components/ParticleSystem/rng.js +0 -20
  140. package/src/lib/components/Stage/components/ParticleSystem/types.ts +0 -95
  141. package/src/lib/components/Stage/components/PerformanceDebugger/PerformanceDebugger.svelte +0 -144
  142. package/src/lib/components/Stage/components/PerformanceDebugger/index.ts +0 -1
  143. package/src/lib/components/Stage/components/PerformanceOverlay/PerformanceOverlay.svelte +0 -208
  144. package/src/lib/components/Stage/components/PerformanceOverlay/index.ts +0 -1
  145. package/src/lib/components/Stage/components/PointerInputManager/PointerInputManager.svelte +0 -201
  146. package/src/lib/components/Stage/components/Scene/Scene.svelte +0 -651
  147. package/src/lib/components/Stage/components/Scene/luts.ts +0 -24
  148. package/src/lib/components/Stage/components/Scene/types.ts +0 -225
  149. package/src/lib/components/Stage/components/Stage/Stage.svelte +0 -332
  150. package/src/lib/components/Stage/components/Stage/types.ts +0 -136
  151. package/src/lib/components/Stage/components/WeatherLayer/WeatherLayer.svelte +0 -135
  152. package/src/lib/components/Stage/components/WeatherLayer/presets/AshPreset.ts +0 -71
  153. package/src/lib/components/Stage/components/WeatherLayer/presets/LeavesPreset.ts +0 -70
  154. package/src/lib/components/Stage/components/WeatherLayer/presets/RainPreset.ts +0 -68
  155. package/src/lib/components/Stage/components/WeatherLayer/presets/SnowPreset.ts +0 -70
  156. package/src/lib/components/Stage/components/WeatherLayer/presets/index.ts +0 -6
  157. package/src/lib/components/Stage/components/WeatherLayer/types.ts +0 -35
  158. package/src/lib/components/Stage/helpers/clippingPlaneStore.svelte.ts +0 -28
  159. package/src/lib/components/Stage/helpers/debugState.svelte.ts +0 -18
  160. package/src/lib/components/Stage/helpers/grid.ts +0 -548
  161. package/src/lib/components/Stage/helpers/lazyBrush.ts +0 -171
  162. package/src/lib/components/Stage/helpers/performanceMetrics.svelte.ts +0 -220
  163. package/src/lib/components/Stage/helpers/utils.ts +0 -21
  164. package/src/lib/components/Stage/index.ts +0 -49
  165. package/src/lib/components/Stage/shaders/AnnotationEffects.frag +0 -1070
  166. package/src/lib/components/Stage/shaders/Annotations.frag +0 -29
  167. package/src/lib/components/Stage/shaders/Drawing.frag +0 -83
  168. package/src/lib/components/Stage/shaders/Drawing.vert +0 -5
  169. package/src/lib/components/Stage/shaders/Fog.frag +0 -147
  170. package/src/lib/components/Stage/shaders/FractalNoise.frag +0 -96
  171. package/src/lib/components/Stage/shaders/GridShader.frag +0 -174
  172. package/src/lib/components/Stage/shaders/Overlay.frag +0 -23
  173. package/src/lib/components/Stage/shaders/Overlay.vert +0 -0
  174. package/src/lib/components/Stage/shaders/Particles.frag +0 -27
  175. package/src/lib/components/Stage/shaders/Particles.vert +0 -51
  176. package/src/lib/components/Stage/shaders/ToolOutline.frag +0 -59
  177. package/src/lib/components/Stage/shaders/default.vert +0 -8
  178. package/src/lib/components/Stage/types.ts +0 -4
  179. package/src/lib/components/Table/Table.svelte +0 -16
  180. package/src/lib/components/Table/Td.svelte +0 -17
  181. package/src/lib/components/Table/Th.svelte +0 -18
  182. package/src/lib/components/Table/index.ts +0 -4
  183. package/src/lib/components/Table/types.ts +0 -14
  184. package/src/lib/components/Text/Text.svelte +0 -23
  185. package/src/lib/components/Text/index.ts +0 -2
  186. package/src/lib/components/Text/types.ts +0 -12
  187. package/src/lib/components/Title/Title.svelte +0 -54
  188. package/src/lib/components/Title/index.ts +0 -2
  189. package/src/lib/components/Title/types.ts +0 -9
  190. package/src/lib/components/Toast/Toast.svelte +0 -155
  191. package/src/lib/components/Toast/index.ts +0 -5
  192. package/src/lib/components/Toast/toastCookie.ts +0 -24
  193. package/src/lib/components/Toast/types.ts +0 -6
  194. package/src/lib/components/ToolTip/ToolTip.svelte +0 -70
  195. package/src/lib/components/ToolTip/index.ts +0 -2
  196. package/src/lib/components/ToolTip/types.ts +0 -14
  197. package/src/lib/components/index.ts +0 -32
  198. package/src/lib/components/types.ts +0 -0
  199. package/src/lib/index.ts +0 -2
  200. package/src/lib/styles/globals.css +0 -108
  201. package/src/lib/styles/normalize.css +0 -9
  202. package/src/lib/styles/reset.css +0 -133
  203. package/src/lib/styles/utilities.css +0 -179
  204. package/src/lib/styles/vars.css +0 -1103
  205. package/src/lib/types/awareness.ts +0 -17
  206. package/src/lib/utils/rle.ts +0 -217
@@ -1,445 +0,0 @@
1
- <script lang="ts">
2
- import * as THREE from 'three';
3
- import { getContext, onDestroy } from 'svelte';
4
- import { T } from '@threlte/core';
5
- import { type AnnotationLayerData, type AnnotationsLayerProps, AnnotationEffect } from './types';
6
- import { StageMode, type Callbacks, type DisplayProps } from '../Stage/types';
7
- import LayerInput from '../LayerInput/LayerInput.svelte';
8
- import { SceneLayer, SceneLayerOrder } from '../Scene/types';
9
- import AnnotationMaterial from './AnnotationMaterial.svelte';
10
- import { LazyBrushManager } from '../../helpers/lazyBrush';
11
- import { ToolType } from '../DrawingLayer/types';
12
- import toolOutlineVertexShader from '../../shaders/default.vert?raw';
13
- import toolOutlineFragmentShader from '../../shaders/ToolOutline.frag?raw';
14
-
15
- interface Props {
16
- props: AnnotationsLayerProps;
17
- mode: StageMode;
18
- isActive: boolean;
19
- display: DisplayProps;
20
- sceneZoom: number;
21
- }
22
-
23
- const { props, mode, isActive, display, sceneZoom }: Props = $props();
24
-
25
- const onAnnotationUpdate = getContext<Callbacks>('callbacks').onAnnotationUpdate;
26
-
27
- // Outline styling (same as fog of war)
28
- const OUTLINE_COLOR = '#FFFFFF';
29
- const OUTLINE_OPACITY = 1;
30
- const OUTLINE_THICKNESS = 2;
31
-
32
- // Pre-allocated vector for display center offset to avoid GC pressure
33
- const displayCenterOffset = new THREE.Vector2();
34
-
35
- // Convert percentage-based lineWidth to texture pixels for outline
36
- const lineWidthPixels = $derived.by(() => {
37
- const textureSize = Math.min(display.resolution.x, display.resolution.y);
38
- return Math.round(textureSize * ((props.lineWidth ?? 2.0) / 100));
39
- });
40
-
41
- let mesh: THREE.Mesh = $state(new THREE.Mesh());
42
- let outlineMesh: THREE.Mesh = $state(new THREE.Mesh());
43
- let drawing = false;
44
-
45
- // Export drawing state so parent can check it
46
- export function isDrawing() {
47
- return drawing;
48
- }
49
-
50
- // If mouse leaves the drawing area, we need to reset the start position
51
- // when it re-enters the drawing area to prevent the drawing from "jumping"
52
- // to the new point
53
- let lastPos: THREE.Vector2 | null = null;
54
-
55
- // Track the last screen position for the persist button
56
- let lastScreenPos: { x: number; y: number } | null = null;
57
-
58
- // Track if cursors are hidden to avoid redundant resets
59
- let cursorsHidden = false;
60
-
61
- // Initialize lazy brush for smooth drawing
62
- // Base values for zoom level 1.0
63
- const BASE_RADIUS = 20;
64
- const BASE_FRICTION = 0.05;
65
-
66
- // Smoothing disabled by default for more responsive drawing
67
- const smoothingEnabled = $derived(props.smoothingEnabled ?? false);
68
-
69
- const lazyBrush = new LazyBrushManager({
70
- radius: BASE_RADIUS,
71
- enabled: smoothingEnabled,
72
- friction: BASE_FRICTION
73
- });
74
-
75
- // Outline material for brush cursor (same as fog of war)
76
- const outlineMaterial = new THREE.ShaderMaterial({
77
- uniforms: {
78
- uStart: { value: new THREE.Vector2(Infinity, Infinity) },
79
- uEnd: { value: new THREE.Vector2(Infinity, Infinity) },
80
- uBrushSize: { value: lineWidthPixels },
81
- uTextureSize: { value: new THREE.Vector2(display.resolution.x, display.resolution.y) },
82
- uShapeType: { value: ToolType.Brush },
83
- uOutlineColor: { value: new THREE.Color(OUTLINE_COLOR) },
84
- uOutlineOpacity: { value: OUTLINE_OPACITY },
85
- uOutlineThickness: { value: OUTLINE_THICKNESS }
86
- },
87
- vertexShader: toolOutlineVertexShader,
88
- fragmentShader: toolOutlineFragmentShader,
89
- transparent: true,
90
- depthTest: false
91
- });
92
-
93
- onDestroy(() => {
94
- outlineMaterial.dispose();
95
- });
96
-
97
- // Adjust lazy brush settings based on zoom level and smoothing toggle
98
- $effect(() => {
99
- // Scale radius inversely with zoom - less smoothing when zoomed in
100
- // At zoom 2x, radius is 25 (half)
101
- // At zoom 0.5x, radius is 100 (double)
102
- const adjustedRadius = BASE_RADIUS / sceneZoom;
103
-
104
- // Adjust friction based on zoom - more responsive when zoomed in
105
- // At high zoom (>2), reduce friction for more immediate response
106
- // At low zoom (<0.5), increase friction for smoother lines
107
- const adjustedFriction =
108
- sceneZoom > 2 ? BASE_FRICTION * 0.5 : sceneZoom < 0.5 ? BASE_FRICTION * 1.5 : BASE_FRICTION;
109
-
110
- lazyBrush.updateConfig({
111
- radius: Math.max(5, Math.min(100, adjustedRadius)), // Clamp between 5 and 100
112
- friction: adjustedFriction,
113
- enabled: smoothingEnabled
114
- });
115
- });
116
-
117
- // Update outline material uniforms and center offset when props change
118
- $effect(() => {
119
- // Use .set() to avoid allocating new objects
120
- outlineMaterial.uniforms.uTextureSize.value.set(display.resolution.x, display.resolution.y);
121
- outlineMaterial.uniforms.uBrushSize.value = lineWidthPixels;
122
- displayCenterOffset.set(display.resolution.x / 2, display.resolution.y / 2);
123
- });
124
-
125
- // Hide outline when tool is not active
126
- $effect(() => {
127
- if (!isActive || !props.activeLayer) {
128
- outlineMesh.visible = false;
129
- outlineMaterial.uniforms.uStart.value.set(Infinity, Infinity);
130
- outlineMaterial.uniforms.uEnd.value.set(Infinity, Infinity);
131
- }
132
- });
133
-
134
- // Reference to the child layers
135
- let layers: AnnotationMaterial[] = $state([]);
136
-
137
- // Get the currently active layer
138
- let activeLayer = $derived(
139
- layers.find((layer) => {
140
- if (!layer) return false;
141
- return layer.getId() === props.activeLayer;
142
- })
143
- );
144
-
145
- // Whenever the tool type changes, we need to reset the drawing state
146
- $effect(() => {
147
- if (!isActive) {
148
- lastPos = null;
149
- drawing = false;
150
- lazyBrush.reset();
151
- // Reset cursor for all layers to ensure no ghosting
152
- if (!cursorsHidden) {
153
- layers.forEach((layer) => {
154
- if (layer) {
155
- layer.revertChanges();
156
- layer.resetCursor();
157
- }
158
- });
159
- cursorsHidden = true;
160
- }
161
- } else {
162
- // Tool is active again
163
- cursorsHidden = false;
164
- }
165
- });
166
-
167
- // Also reset cursor when active layer becomes null
168
- $effect(() => {
169
- if (!props.activeLayer && layers.length > 0) {
170
- // No active layer selected, reset all cursors and revert changes
171
- lastPos = null; // Reset last position to prevent cursor from appearing
172
- if (!cursorsHidden) {
173
- layers.forEach((layer) => {
174
- if (layer) {
175
- layer.revertChanges();
176
- layer.resetCursor();
177
- }
178
- });
179
- cursorsHidden = true;
180
- }
181
- } else if (props.activeLayer) {
182
- // Active layer selected again
183
- cursorsHidden = false;
184
- }
185
- });
186
-
187
- function onMouseDown(e: Event, p: THREE.Vector2 | null) {
188
- e.preventDefault();
189
- lastPos = p;
190
- drawing = true;
191
-
192
- // Track screen position for persist button
193
- if (e instanceof MouseEvent) {
194
- lastScreenPos = { x: e.clientX, y: e.clientY };
195
- } else if (e instanceof TouchEvent && e.touches[0]) {
196
- lastScreenPos = { x: e.touches[0].clientX, y: e.touches[0].clientY };
197
- }
198
-
199
- // Start a new stroke with lazy brush
200
- if (p) {
201
- // Need to adjust for display offset before starting stroke
202
- const adjustedP = p.clone();
203
- adjustedP.add(displayCenterOffset);
204
- lazyBrush.startStroke(adjustedP);
205
- }
206
-
207
- draw(e, p);
208
- }
209
-
210
- function onMouseUp() {
211
- // If we have just finished drawing, save the annotation
212
- if (props.activeLayer && drawing) {
213
- onAnnotationUpdate(props.activeLayer, toPng(), lastScreenPos || undefined);
214
- }
215
-
216
- // Reset the drawing state
217
- drawing = false;
218
- lazyBrush.endStroke();
219
- // Don't reset lastPos here to prevent cursor jumping
220
- }
221
-
222
- function onMouseLeave() {
223
- lastPos = null;
224
- drawing = false;
225
- lazyBrush.reset();
226
-
227
- // Revert changes and hide cursor
228
- if (activeLayer && !cursorsHidden) {
229
- activeLayer.revertChanges();
230
- activeLayer.resetCursor();
231
- }
232
-
233
- // Hide outline
234
- outlineMesh.visible = false;
235
- outlineMaterial.uniforms.uStart.value.set(Infinity, Infinity);
236
- outlineMaterial.uniforms.uEnd.value.set(Infinity, Infinity);
237
- }
238
-
239
- function draw(e: Event, p: THREE.Vector2 | null) {
240
- // Track screen position during drawing for persist button
241
- if (drawing) {
242
- if (e instanceof MouseEvent) {
243
- lastScreenPos = { x: e.clientX, y: e.clientY };
244
- } else if (e instanceof TouchEvent && e.touches[0]) {
245
- lastScreenPos = { x: e.touches[0].clientX, y: e.touches[0].clientY };
246
- }
247
- }
248
-
249
- // If the mouse is not within the drawing area, hide cursor and outline
250
- if (!p) {
251
- // Reset cursor for all layers when mouse leaves (only if not already hidden)
252
- if (!cursorsHidden) {
253
- layers.forEach((layer) => {
254
- if (layer) {
255
- layer.resetCursor();
256
- }
257
- });
258
- }
259
- // Hide outline
260
- outlineMesh.visible = false;
261
- outlineMaterial.uniforms.uStart.value.set(Infinity, Infinity);
262
- outlineMaterial.uniforms.uEnd.value.set(Infinity, Infinity);
263
- return;
264
- }
265
-
266
- // Only process if we have an active layer and the annotation tool is active
267
- if (!activeLayer || !isActive || !props.activeLayer) {
268
- // Make sure all cursors are hidden when not active (only if not already hidden)
269
- if (!cursorsHidden) {
270
- layers.forEach((layer) => {
271
- if (layer) {
272
- layer.resetCursor();
273
- }
274
- });
275
- cursorsHidden = true;
276
- }
277
- // Hide outline
278
- outlineMesh.visible = false;
279
- outlineMaterial.uniforms.uStart.value.set(Infinity, Infinity);
280
- outlineMaterial.uniforms.uEnd.value.set(Infinity, Infinity);
281
- return;
282
- }
283
-
284
- // Tool is active and we have a valid position
285
- cursorsHidden = false;
286
-
287
- p.add(displayCenterOffset);
288
-
289
- // Show outline at cursor position
290
- outlineMesh.visible = true;
291
- outlineMaterial.uniforms.uStart.value.copy(p);
292
- outlineMaterial.uniforms.uEnd.value.copy(p);
293
-
294
- // Use lazy brush for smooth drawing when drawing is active
295
- if (drawing && lazyBrush.enabled) {
296
- // Update lazy brush and get smoothed points
297
- const segments = lazyBrush.updateStroke(p);
298
-
299
- // Draw each segment (segments come as pairs: [lastPoint, newPoint])
300
- for (let i = 0; i < segments.length; i += 2) {
301
- if (segments[i] && segments[i + 1]) {
302
- // Draw from last point to new point
303
- activeLayer.drawPath(segments[i + 1], segments[i], true);
304
- }
305
- }
306
-
307
- // Update cursor to show brush position
308
- const brushPos = lazyBrush.getBrushPosition();
309
- if (brushPos) {
310
- activeLayer.drawPath(brushPos, brushPos, false);
311
- // Update outline to follow lazy brush position
312
- outlineMaterial.uniforms.uStart.value.copy(brushPos);
313
- outlineMaterial.uniforms.uEnd.value.copy(brushPos);
314
- } else {
315
- // Show cursor at actual position if no brush position
316
- activeLayer.drawPath(p, p, false);
317
- }
318
- } else if (drawing && !lazyBrush.enabled) {
319
- // Drawing but lazy brush is disabled
320
- if (!lastPos) {
321
- lastPos = p.clone();
322
- }
323
- activeLayer.drawPath(p, lastPos, true);
324
- lastPos = p.clone();
325
- } else {
326
- // Just hovering, show cursor
327
- activeLayer.drawPath(p, p, false);
328
- }
329
- }
330
-
331
- function isVisible(layer: AnnotationLayerData) {
332
- // Don't show DM layers to players
333
- return !(mode === StageMode.Player && layer.visibility === StageMode.DM);
334
- }
335
-
336
- function hasEffect(layer: AnnotationLayerData) {
337
- // Check if the layer has an effect (not None)
338
- return layer.effect?.type !== undefined && layer.effect.type !== AnnotationEffect.None;
339
- }
340
-
341
- /**
342
- * Clears the annotation layer
343
- */
344
- export function clear(layerId: string) {
345
- if (layerId) {
346
- const layer = layers.find((layer) => layer.getId() === layerId);
347
- if (layer) {
348
- layer.clear();
349
- onAnnotationUpdate(layerId, toPng());
350
- }
351
- }
352
- }
353
-
354
- /**
355
- * Serializes the annotation layer image data into a binary buffer
356
- * @return A binary buffer
357
- */
358
- export async function toPng(): Promise<Blob> {
359
- // For now, return the active layer's PNG or an empty blob
360
- return (await activeLayer?.toPng()) ?? new Blob();
361
- }
362
-
363
- /**
364
- * Exports the active annotation layer state as RLE-encoded data
365
- * @returns RLE encoded Uint8Array
366
- */
367
- export async function toRLE(): Promise<Uint8Array> {
368
- return (await activeLayer?.toRLE()) ?? new Uint8Array();
369
- }
370
-
371
- /**
372
- * Loads RLE-encoded data into the active annotation layer
373
- * @param rleData RLE encoded data
374
- * @param width Image width
375
- * @param height Image height
376
- */
377
- export async function fromRLE(rleData: Uint8Array, width: number, height: number) {
378
- return activeLayer?.fromRLE(rleData, width, height);
379
- }
380
-
381
- /**
382
- * Loads RLE-encoded data into a specific annotation layer by ID
383
- * @param layerId The ID of the annotation layer
384
- * @param rleData RLE encoded data
385
- */
386
- export async function loadMask(layerId: string, rleData: Uint8Array) {
387
- // Filter out null entries that may exist before components are rendered
388
- const layer = layers.find((layer) => layer && layer.getId() === layerId);
389
- if (layer) {
390
- return layer.fromRLE(rleData, 1024, 1024);
391
- }
392
- }
393
- </script>
394
-
395
- <LayerInput
396
- id="annotation"
397
- {isActive}
398
- layerSize={{ width: 1, height: 1 }}
399
- target={mesh}
400
- {onMouseDown}
401
- onMouseMove={draw}
402
- {onMouseUp}
403
- {onMouseLeave}
404
- />
405
-
406
- <!--
407
- Invisible mesh used for input detection.
408
- The plane geometry is larger than the map size to allow cursor
409
- events to be detected outside of the fog of war layer.
410
- -->
411
- <T.Mesh bind:ref={mesh} name="annotationInput" layers={isActive ? [SceneLayer.Input] : undefined}>
412
- <T.MeshBasicMaterial visible={false} />
413
- <T.PlaneGeometry args={[2 * display.resolution.x, 2 * display.resolution.y]} />
414
- </T.Mesh>
415
-
416
- <!-- Brush outline for annotation tool -->
417
- <T.Mesh
418
- bind:ref={outlineMesh}
419
- name="annotationToolOutline"
420
- layers={[SceneLayer.Overlay]}
421
- scale={[display.resolution.x, display.resolution.y, 1]}
422
- renderOrder={SceneLayerOrder.Cursor}
423
- >
424
- <T is={outlineMaterial} transparent={true} depthTest={false} />
425
- <T.PlaneGeometry />
426
- </T.Mesh>
427
-
428
- <!--
429
- Effect annotations render on Main layer (under fog, with post-processing).
430
- Color annotations render on Overlay layer (over fog, no post-processing).
431
- -->
432
- <T.Mesh name="annotationLayer" scale={[display.resolution.x, display.resolution.y, 1]}>
433
- {#each props.layers as layer, index (layer.id)}
434
- <T.Mesh
435
- name={layer.id}
436
- visible={isVisible(layer)}
437
- position.z={(props.layers.length - index) * 0.001}
438
- layers={hasEffect(layer) ? [SceneLayer.Main] : [SceneLayer.Overlay]}
439
- renderOrder={hasEffect(layer) ? SceneLayerOrder.EffectAnnotation : SceneLayerOrder.Annotation}
440
- >
441
- <AnnotationMaterial bind:this={layers[index]} props={layer} {display} lineWidth={props.lineWidth} />
442
- <T.PlaneGeometry />
443
- </T.Mesh>
444
- {/each}
445
- </T.Mesh>
@@ -1,167 +0,0 @@
1
- <script lang="ts">
2
- import * as THREE from 'three';
3
- import { T, useTask } from '@threlte/core';
4
- import { onDestroy } from 'svelte';
5
- import chroma from 'chroma-js';
6
- import DrawingMaterial from '../DrawingLayer/DrawingMaterial.svelte';
7
- import { type AnnotationLayerData, AnnotationEffect } from './types';
8
- import { clippingPlaneStore } from '../../helpers/clippingPlaneStore.svelte';
9
- import { DrawMode, ToolType, InitialState } from '../DrawingLayer/types';
10
- import type { DisplayProps } from '../Stage/types';
11
-
12
- import annotationEffectsFragmentShader from '../../shaders/AnnotationEffects.frag?raw';
13
- import annotationVertexShader from '../../shaders/default.vert?raw';
14
-
15
- interface Props {
16
- props: AnnotationLayerData;
17
- display: DisplayProps;
18
- lineWidth?: number;
19
- }
20
-
21
- const { props, display, lineWidth = 2.0 }: Props = $props();
22
-
23
- const lineWidthPixels = $derived.by(() => {
24
- const textureSize = Math.min(display.resolution.x, display.resolution.y);
25
- return Math.round(textureSize * (lineWidth / 100));
26
- });
27
-
28
- let size = $derived({ width: display.resolution.x, height: display.resolution.y });
29
-
30
- let drawMaterial: DrawingMaterial;
31
-
32
- const hexToRGB = (hex: string): THREE.Vector3 => {
33
- const [r, g, b] = chroma(hex).gl();
34
- return new THREE.Vector3(r, g, b);
35
- };
36
-
37
- // Hardcoded color for Magic effect (saturated purple)
38
- const MAGIC_EFFECT_COLOR = '#9333ea';
39
-
40
- // Use hardcoded color for Magic effect, otherwise use layer color
41
- let colorUniform = $derived(
42
- props.effect?.type === AnnotationEffect.Magic ? hexToRGB(MAGIC_EFFECT_COLOR) : hexToRGB(props.color)
43
- );
44
-
45
- const getEffectType = () => props.effect?.type ?? AnnotationEffect.None;
46
- const getEffectSpeed = () => props.effect?.speed ?? 1.0;
47
- const getEffectIntensity = () => props.effect?.intensity ?? 1.0;
48
- const getEffectSoftness = () => props.effect?.softness ?? 0.5;
49
- const getEffectBorder = () => props.effect?.border ?? 0.5;
50
- const getEffectRoughness = () => props.effect?.roughness ?? 0.0;
51
-
52
- let material = new THREE.ShaderMaterial({
53
- defines: {
54
- NUM_CLIPPING_PLANES: 4
55
- },
56
- uniforms: {
57
- uMaskTexture: { value: null },
58
- uTime: { value: 0.0 },
59
- uEffectType: { value: getEffectType() },
60
- uBaseColor: { value: hexToRGB(props.color) },
61
- uOpacity: { value: props.opacity },
62
- uSpeed: { value: getEffectSpeed() },
63
- uIntensity: { value: getEffectIntensity() },
64
- uSoftness: { value: getEffectSoftness() },
65
- uBorder: { value: getEffectBorder() },
66
- uRoughness: { value: getEffectRoughness() },
67
- uEdgeMinMipMapLevel: { value: 0 },
68
- uEdgeMaxMipMapLevel: { value: 4 },
69
- uClippingPlanes: new THREE.Uniform(
70
- clippingPlaneStore.value.map((p) => new THREE.Vector4(p.normal.x, p.normal.y, p.normal.z, p.constant))
71
- )
72
- },
73
- transparent: true,
74
- depthWrite: false, // Prevent transparent overlay from affecting depth buffer
75
- fragmentShader: annotationEffectsFragmentShader,
76
- vertexShader: annotationVertexShader
77
- });
78
-
79
- $effect(() => {
80
- material.uniforms.uBaseColor.value.copy(colorUniform);
81
- material.uniforms.uOpacity.value = props.opacity;
82
- material.uniforms.uEffectType.value = getEffectType();
83
- material.uniforms.uSpeed.value = getEffectSpeed();
84
- material.uniforms.uIntensity.value = getEffectIntensity();
85
- material.uniforms.uSoftness.value = getEffectSoftness();
86
- material.uniforms.uBorder.value = getEffectBorder();
87
- material.uniforms.uRoughness.value = getEffectRoughness();
88
- // Update clipping planes in place to avoid allocating new Vector4 objects
89
- const planes = clippingPlaneStore.value;
90
- for (let i = 0; i < planes.length; i++) {
91
- const p = planes[i];
92
- material.uniforms.uClippingPlanes.value[i].set(p.normal.x, p.normal.y, p.normal.z, p.constant);
93
- }
94
- material.uniformsNeedUpdate = true;
95
- });
96
-
97
- useTask((delta) => {
98
- material.uniforms.uTime.value += delta;
99
- });
100
-
101
- export const getId = () => props.id;
102
-
103
- export const revertChanges = () => {
104
- drawMaterial.revert();
105
- };
106
-
107
- export const resetCursor = () => {
108
- if (drawMaterial) {
109
- drawMaterial.resetCursor();
110
- }
111
- };
112
-
113
- export const clear = () => {
114
- drawMaterial.clear();
115
- };
116
-
117
- export const drawPath = (start: THREE.Vector2, last: THREE.Vector2 | null = null, persist: boolean = false) => {
118
- drawMaterial.drawPath(start, last, persist);
119
- };
120
-
121
- export const toPng = async (): Promise<Blob> => {
122
- return drawMaterial.toPng();
123
- };
124
-
125
- export const toRLE = async (): Promise<Uint8Array> => {
126
- return drawMaterial.toRLE();
127
- };
128
-
129
- export const fromRLE = async (rleData: Uint8Array, width: number, height: number) => {
130
- return drawMaterial.fromRLE(rleData, width, height);
131
- };
132
-
133
- onDestroy(() => {
134
- material.dispose();
135
- });
136
- </script>
137
-
138
- <DrawingMaterial
139
- bind:this={drawMaterial}
140
- props={{
141
- url: props.url,
142
- opacity: {
143
- dm: props.opacity,
144
- player: props.opacity
145
- },
146
- tool: {
147
- mode: DrawMode.Draw,
148
- size: lineWidthPixels,
149
- type: ToolType.Brush
150
- }
151
- }}
152
- initialState={InitialState.Clear}
153
- {size}
154
- onRender={(texture) => {
155
- material.uniforms.uBaseColor.value.copy(colorUniform);
156
- material.uniforms.uMaskTexture.value = texture;
157
- material.uniformsNeedUpdate = true;
158
- }}
159
- />
160
-
161
- {#snippet attachMaterial()}
162
- {material}
163
- {/snippet}
164
-
165
- <T is={material}>
166
- {@render attachMaterial()}
167
- </T>