@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,196 @@
|
|
|
1
|
+
import type { StageMode } from '../Stage/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Visual effect types for annotation layers
|
|
5
|
+
*/
|
|
6
|
+
export enum AnnotationEffect {
|
|
7
|
+
None = 0,
|
|
8
|
+
Fire = 1,
|
|
9
|
+
SpaceTear = 2,
|
|
10
|
+
Water = 3,
|
|
11
|
+
Magic = 4,
|
|
12
|
+
Grease = 5,
|
|
13
|
+
Ice = 6
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Properties for annotation visual effects
|
|
18
|
+
*/
|
|
19
|
+
export interface AnnotationEffectProps {
|
|
20
|
+
/**
|
|
21
|
+
* The type of visual effect to apply
|
|
22
|
+
*/
|
|
23
|
+
type: AnnotationEffect;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Animation speed multiplier (0.0 - 2.0)
|
|
27
|
+
*/
|
|
28
|
+
speed: number;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Intensity of the effect (0.0 - 1.0)
|
|
32
|
+
*/
|
|
33
|
+
intensity: number;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Edge softness - how much the effect fades at the boundaries (0.0 - 1.0)
|
|
37
|
+
* Higher values create a more gradual fade to transparent
|
|
38
|
+
*/
|
|
39
|
+
softness: number;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Border/edge effect intensity (0.0 - 1.0)
|
|
43
|
+
* Controls foam, glow, nebula wisps, etc. at the edges
|
|
44
|
+
*/
|
|
45
|
+
border: number;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Edge roughness - adds random noise to effect edges (0.0 - 1.0)
|
|
49
|
+
* Higher values create more jagged, organic-looking boundaries
|
|
50
|
+
*/
|
|
51
|
+
roughness: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The properties for the annotations layer
|
|
56
|
+
*/
|
|
57
|
+
export interface AnnotationsLayerProps {
|
|
58
|
+
/**
|
|
59
|
+
* The layers to display
|
|
60
|
+
*/
|
|
61
|
+
layers: AnnotationLayerData[];
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The id of the active layer
|
|
65
|
+
*/
|
|
66
|
+
activeLayer: string | null;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The line width for drawing (global setting)
|
|
70
|
+
*/
|
|
71
|
+
lineWidth?: number;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Whether to enable brush smoothing for drawing
|
|
75
|
+
* When true, uses lazy brush algorithm for smoother lines
|
|
76
|
+
* Default: true in editor, false in play view
|
|
77
|
+
*/
|
|
78
|
+
smoothingEnabled?: boolean;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The properties for an individual annotation drawing layer
|
|
83
|
+
*/
|
|
84
|
+
export interface AnnotationLayerData {
|
|
85
|
+
/**
|
|
86
|
+
* The ID of the annotation layer
|
|
87
|
+
*/
|
|
88
|
+
id: string;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The name of the annotation layer
|
|
92
|
+
*/
|
|
93
|
+
name?: string;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* The opacity of the annotation layer
|
|
97
|
+
*/
|
|
98
|
+
opacity: number;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The color of the annotation layer
|
|
102
|
+
*/
|
|
103
|
+
color: string;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The URL of the texture to use for the annotation layer
|
|
107
|
+
*/
|
|
108
|
+
url: string | null;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Version timestamp for mask data changes (for real-time sync)
|
|
112
|
+
*/
|
|
113
|
+
maskVersion?: number;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Control who can see the layer
|
|
117
|
+
*/
|
|
118
|
+
visibility: StageMode;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Visual effect settings for this annotation layer (experimental, not persisted)
|
|
122
|
+
*/
|
|
123
|
+
effect?: AnnotationEffectProps;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface AnnotationExports {
|
|
127
|
+
clear: (layerId: string) => void;
|
|
128
|
+
toPng: () => Promise<Blob>;
|
|
129
|
+
toRLE: () => Promise<Uint8Array>;
|
|
130
|
+
fromRLE: (rleData: Uint8Array, width: number, height: number) => Promise<void>;
|
|
131
|
+
loadMask: (layerId: string, rleData: Uint8Array) => Promise<void>;
|
|
132
|
+
isDrawing: () => boolean;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Default effect properties for each annotation effect type
|
|
137
|
+
*/
|
|
138
|
+
export const AnnotationEffectDefaults: Record<AnnotationEffect, Omit<AnnotationEffectProps, 'type'>> = {
|
|
139
|
+
[AnnotationEffect.None]: {
|
|
140
|
+
speed: 1.0,
|
|
141
|
+
intensity: 1.0,
|
|
142
|
+
softness: 0.5,
|
|
143
|
+
border: 0.5,
|
|
144
|
+
roughness: 0.0
|
|
145
|
+
},
|
|
146
|
+
[AnnotationEffect.Fire]: {
|
|
147
|
+
speed: 0.94,
|
|
148
|
+
intensity: 1.04,
|
|
149
|
+
softness: 0.37,
|
|
150
|
+
border: 0.4,
|
|
151
|
+
roughness: 0.62
|
|
152
|
+
},
|
|
153
|
+
[AnnotationEffect.SpaceTear]: {
|
|
154
|
+
speed: 1.5,
|
|
155
|
+
intensity: 1.96,
|
|
156
|
+
softness: 0.35,
|
|
157
|
+
border: 0.36,
|
|
158
|
+
roughness: 0.34
|
|
159
|
+
},
|
|
160
|
+
[AnnotationEffect.Water]: {
|
|
161
|
+
speed: 0.42,
|
|
162
|
+
intensity: 1.06,
|
|
163
|
+
softness: 0.0,
|
|
164
|
+
border: 0.36,
|
|
165
|
+
roughness: 0.32
|
|
166
|
+
},
|
|
167
|
+
[AnnotationEffect.Magic]: {
|
|
168
|
+
speed: 0.5,
|
|
169
|
+
intensity: 0.98,
|
|
170
|
+
softness: 0.24,
|
|
171
|
+
border: 0.18,
|
|
172
|
+
roughness: 0.5
|
|
173
|
+
},
|
|
174
|
+
[AnnotationEffect.Grease]: {
|
|
175
|
+
speed: 0.26,
|
|
176
|
+
intensity: 1.52,
|
|
177
|
+
softness: 0.13,
|
|
178
|
+
border: 0.57,
|
|
179
|
+
roughness: 0.26
|
|
180
|
+
},
|
|
181
|
+
[AnnotationEffect.Ice]: {
|
|
182
|
+
speed: 0.92,
|
|
183
|
+
intensity: 1.2,
|
|
184
|
+
softness: 0.32,
|
|
185
|
+
border: 0.44,
|
|
186
|
+
roughness: 0.55
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Get the default effect properties for a given effect type
|
|
192
|
+
*/
|
|
193
|
+
export const getDefaultEffectProps = (effectType: AnnotationEffect): AnnotationEffectProps => ({
|
|
194
|
+
type: effectType,
|
|
195
|
+
...AnnotationEffectDefaults[effectType]
|
|
196
|
+
});
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { T, useTask, useThrelte } from '@threlte/core';
|
|
4
|
+
import type { CursorData, CursorLayerProps } from './types';
|
|
5
|
+
import { SceneLayer, SceneLayerOrder } from '../Scene/types';
|
|
6
|
+
import { onMount } from 'svelte';
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
props: CursorLayerProps;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const { props }: Props = $props();
|
|
13
|
+
const { invalidate } = useThrelte();
|
|
14
|
+
|
|
15
|
+
// Track current time for fade calculations
|
|
16
|
+
let currentTime = $state(Date.now());
|
|
17
|
+
|
|
18
|
+
useTask(() => {
|
|
19
|
+
currentTime = Date.now();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Calculate opacity for each cursor based on fade settings
|
|
23
|
+
const getCursorOpacity = (cursor: CursorData): number => {
|
|
24
|
+
const timeSinceUpdate = currentTime - cursor.lastUpdateTime;
|
|
25
|
+
|
|
26
|
+
if (timeSinceUpdate < props.fadeOutDelay) {
|
|
27
|
+
return cursor.opacity;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const fadeProgress = (timeSinceUpdate - props.fadeOutDelay) / props.fadeOutDuration;
|
|
31
|
+
if (fadeProgress >= 1) {
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return cursor.opacity * (1 - fadeProgress);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Calculate cursor size based on grid spacing and display dimensions
|
|
39
|
+
const calculateCursorSize = () => {
|
|
40
|
+
if (!props.gridSpacing || !props.displaySize || !props.displayResolution) {
|
|
41
|
+
return 50;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const worldUnitsPerInch = props.displayResolution.x / props.displaySize.x;
|
|
45
|
+
const gridSizeInWorldUnits = props.gridSpacing * worldUnitsPerInch;
|
|
46
|
+
const sceneZoom = props.sceneZoom || 1;
|
|
47
|
+
const adjustedSize = gridSizeInWorldUnits / sceneZoom;
|
|
48
|
+
const targetScale = 0.6;
|
|
49
|
+
const finalSize = adjustedSize * targetScale;
|
|
50
|
+
|
|
51
|
+
return finalSize;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const targetDiameter = $derived(calculateCursorSize());
|
|
55
|
+
|
|
56
|
+
// Create plane geometry for the cursor
|
|
57
|
+
const planeGeometry = new THREE.PlaneGeometry(1, 1);
|
|
58
|
+
|
|
59
|
+
// Load and create textures for each cursor color
|
|
60
|
+
const textureCache = new Map<string, THREE.Texture>();
|
|
61
|
+
|
|
62
|
+
const createCursorTexture = (color: string): THREE.Texture => {
|
|
63
|
+
// Check cache first
|
|
64
|
+
if (textureCache.has(color)) {
|
|
65
|
+
return textureCache.get(color)!;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Create SVG with the specified color
|
|
69
|
+
const svg = `
|
|
70
|
+
<svg width="64" height="64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
|
71
|
+
<defs>
|
|
72
|
+
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
|
|
73
|
+
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
|
|
74
|
+
<feOffset dx="0" dy="1" result="offsetblur"/>
|
|
75
|
+
<feFlood flood-color="#000000" flood-opacity="0.2"/>
|
|
76
|
+
<feComposite in2="offsetblur" operator="in"/>
|
|
77
|
+
<feMerge>
|
|
78
|
+
<feMergeNode/>
|
|
79
|
+
<feMergeNode in="SourceGraphic"/>
|
|
80
|
+
</feMerge>
|
|
81
|
+
</filter>
|
|
82
|
+
</defs>
|
|
83
|
+
<circle
|
|
84
|
+
cx="32"
|
|
85
|
+
cy="32"
|
|
86
|
+
r="20"
|
|
87
|
+
fill="${color}"
|
|
88
|
+
stroke="white"
|
|
89
|
+
stroke-width="4"
|
|
90
|
+
filter="url(#shadow)"
|
|
91
|
+
/>
|
|
92
|
+
</svg>
|
|
93
|
+
`;
|
|
94
|
+
|
|
95
|
+
// Convert SVG to data URL
|
|
96
|
+
const svgDataUrl = 'data:image/svg+xml;base64,' + btoa(svg);
|
|
97
|
+
|
|
98
|
+
// Create texture from SVG
|
|
99
|
+
const loader = new THREE.TextureLoader();
|
|
100
|
+
const texture = loader.load(svgDataUrl, () => {
|
|
101
|
+
invalidate();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Configure texture for best quality
|
|
105
|
+
texture.minFilter = THREE.LinearFilter;
|
|
106
|
+
texture.magFilter = THREE.LinearFilter;
|
|
107
|
+
texture.generateMipmaps = false;
|
|
108
|
+
texture.needsUpdate = true;
|
|
109
|
+
|
|
110
|
+
// Cache the texture
|
|
111
|
+
textureCache.set(color, texture);
|
|
112
|
+
|
|
113
|
+
return texture;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// Cleanup textures on unmount
|
|
117
|
+
onMount(() => {
|
|
118
|
+
return () => {
|
|
119
|
+
textureCache.forEach((texture) => texture.dispose());
|
|
120
|
+
textureCache.clear();
|
|
121
|
+
};
|
|
122
|
+
});
|
|
123
|
+
</script>
|
|
124
|
+
|
|
125
|
+
{#each props.cursors as cursor, index (cursor.id)}
|
|
126
|
+
{@const opacity = getCursorOpacity(cursor)}
|
|
127
|
+
{@const cursorColor = index === 0 ? '#000000' : cursor.color}
|
|
128
|
+
|
|
129
|
+
{#if opacity > 0}
|
|
130
|
+
{@const texture = createCursorTexture(cursorColor)}
|
|
131
|
+
|
|
132
|
+
<T.Group
|
|
133
|
+
position={[cursor.worldPosition.x, cursor.worldPosition.y, cursor.worldPosition.z + 0.1]}
|
|
134
|
+
layers={[SceneLayer.Overlay]}
|
|
135
|
+
>
|
|
136
|
+
<T.Mesh geometry={planeGeometry} scale={[targetDiameter, targetDiameter, 1]} renderOrder={SceneLayerOrder.Cursor}>
|
|
137
|
+
<T.MeshBasicMaterial
|
|
138
|
+
map={texture}
|
|
139
|
+
transparent={true}
|
|
140
|
+
{opacity}
|
|
141
|
+
depthTest={false}
|
|
142
|
+
depthWrite={false}
|
|
143
|
+
alphaTest={0.01}
|
|
144
|
+
/>
|
|
145
|
+
</T.Mesh>
|
|
146
|
+
</T.Group>
|
|
147
|
+
{/if}
|
|
148
|
+
{/each}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<svg width="64" height="64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<!-- Drop shadow -->
|
|
3
|
+
<defs>
|
|
4
|
+
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
|
|
5
|
+
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
|
|
6
|
+
<feOffset dx="0" dy="1" result="offsetblur"/>
|
|
7
|
+
<feFlood flood-color="#000000" flood-opacity="0.2"/>
|
|
8
|
+
<feComposite in2="offsetblur" operator="in"/>
|
|
9
|
+
<feMerge>
|
|
10
|
+
<feMergeNode/>
|
|
11
|
+
<feMergeNode in="SourceGraphic"/>
|
|
12
|
+
</feMerge>
|
|
13
|
+
</filter>
|
|
14
|
+
</defs>
|
|
15
|
+
|
|
16
|
+
<!-- Main circle with white stroke -->
|
|
17
|
+
<circle
|
|
18
|
+
cx="32"
|
|
19
|
+
cy="32"
|
|
20
|
+
r="20"
|
|
21
|
+
fill="currentColor"
|
|
22
|
+
stroke="white"
|
|
23
|
+
stroke-width="4"
|
|
24
|
+
filter="url(#shadow)"
|
|
25
|
+
/>
|
|
26
|
+
</svg>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface CursorData {
|
|
2
|
+
id: string; // Unique identifier for the cursor (userId or sessionId)
|
|
3
|
+
worldPosition: {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
z: number;
|
|
7
|
+
};
|
|
8
|
+
color: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
opacity: number; // For fade-out effect
|
|
11
|
+
lastUpdateTime: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface CursorLayerProps {
|
|
15
|
+
cursors: CursorData[];
|
|
16
|
+
showLabels: boolean;
|
|
17
|
+
fadeOutDelay: number; // Time in ms before cursor starts fading
|
|
18
|
+
fadeOutDuration: number; // Time in ms for fade animation
|
|
19
|
+
gridSpacing?: number; // Grid spacing in inches (for sizing cursor)
|
|
20
|
+
displaySize?: { x: number; y: number }; // Display size in inches
|
|
21
|
+
displayResolution?: { x: number; y: number }; // Display resolution in pixels
|
|
22
|
+
sceneZoom?: number; // Current scene zoom level (to compensate for scaling)
|
|
23
|
+
}
|