@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,265 @@
|
|
|
1
|
+
import { decompressFrames, parseGIF } from 'gifuct-js';
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import type { Size } from '../../../types';
|
|
4
|
+
import type { IMapDataSource } from './IMapDataSource';
|
|
5
|
+
|
|
6
|
+
interface GifFrame {
|
|
7
|
+
dims: {
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
left: number;
|
|
11
|
+
top: number;
|
|
12
|
+
};
|
|
13
|
+
patch: Uint8ClampedArray;
|
|
14
|
+
delay: number;
|
|
15
|
+
disposalType?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Data source for loading and animating GIF images as textures in a 3D scene.
|
|
20
|
+
*
|
|
21
|
+
* This class implements the IMapDataSource interface to provide GIF animation
|
|
22
|
+
* capabilities for map layers. It handles GIF parsing, frame decompression,
|
|
23
|
+
* and real-time animation rendering using HTML5 Canvas and Three.js textures.
|
|
24
|
+
*/
|
|
25
|
+
export class GifDataSource implements IMapDataSource {
|
|
26
|
+
/** Canvas element used for rendering the GIF frames */
|
|
27
|
+
private gifCanvas: HTMLCanvasElement | null = null;
|
|
28
|
+
/** 2D rendering context for the main GIF canvas */
|
|
29
|
+
private gifCtx: CanvasRenderingContext2D | null = null;
|
|
30
|
+
/** Temporary canvas used for patch rendering of individual frames */
|
|
31
|
+
private tempCanvas: HTMLCanvasElement | null = null;
|
|
32
|
+
/** 2D rendering context for the temporary canvas */
|
|
33
|
+
private tempCtx: CanvasRenderingContext2D | null = null;
|
|
34
|
+
/** Three.js texture created from the GIF canvas */
|
|
35
|
+
private texture: THREE.CanvasTexture | null = null;
|
|
36
|
+
/** Dimensions of the GIF image */
|
|
37
|
+
private size: Size | null = null;
|
|
38
|
+
/** Array of decompressed GIF frames */
|
|
39
|
+
private frames: GifFrame[] = [];
|
|
40
|
+
/** Index of the currently displayed frame */
|
|
41
|
+
private currentFrameIndex = 0;
|
|
42
|
+
/** Animation frame ID for canceling the animation loop */
|
|
43
|
+
private animationId: number | null = null;
|
|
44
|
+
/** Timestamp when the animation started for timing calculations */
|
|
45
|
+
private startTime = 0;
|
|
46
|
+
/** Timestamp of the last frame render */
|
|
47
|
+
private lastFrameTime = 0;
|
|
48
|
+
/** The total time the animation has been playing */
|
|
49
|
+
private totalPlayTime = 0;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Gets the Three.js texture containing the animated GIF.
|
|
53
|
+
*
|
|
54
|
+
* @returns The canvas texture with the current frame, or null if not loaded
|
|
55
|
+
*/
|
|
56
|
+
getTexture(): THREE.Texture | null {
|
|
57
|
+
return this.texture;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Gets the dimensions of the GIF image.
|
|
62
|
+
*
|
|
63
|
+
* @returns The width and height of the GIF, or null if not loaded
|
|
64
|
+
*/
|
|
65
|
+
getSize(): Size | null {
|
|
66
|
+
return this.size;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Loads and initializes a GIF from a URL.
|
|
71
|
+
*
|
|
72
|
+
* This method fetches the GIF data, parses it, decompresses the frames,
|
|
73
|
+
* sets up the rendering canvases, and starts the animation loop.
|
|
74
|
+
*
|
|
75
|
+
* @param url - The URL of the GIF file to load
|
|
76
|
+
* @returns A promise that resolves when the GIF is loaded and ready
|
|
77
|
+
* @throws Error if the GIF cannot be fetched, parsed, or has no frames
|
|
78
|
+
*/
|
|
79
|
+
async load(url: string): Promise<void> {
|
|
80
|
+
// Dispose of previous resources
|
|
81
|
+
this.dispose();
|
|
82
|
+
|
|
83
|
+
return new Promise(async (resolve, reject) => {
|
|
84
|
+
try {
|
|
85
|
+
// Fetch the GIF data
|
|
86
|
+
const response = await fetch(url);
|
|
87
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
88
|
+
|
|
89
|
+
// Parse the GIF
|
|
90
|
+
const gif = parseGIF(arrayBuffer);
|
|
91
|
+
this.frames = decompressFrames(gif, true);
|
|
92
|
+
|
|
93
|
+
if (this.frames.length === 0) {
|
|
94
|
+
throw new Error('No frames found in GIF');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Get dimensions from the first frame
|
|
98
|
+
const firstFrame = this.frames[0];
|
|
99
|
+
this.size = {
|
|
100
|
+
width: firstFrame.dims.width,
|
|
101
|
+
height: firstFrame.dims.height
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// Create canvas for rendering
|
|
105
|
+
this.gifCanvas = document.createElement('canvas');
|
|
106
|
+
this.gifCanvas.width = this.size.width;
|
|
107
|
+
this.gifCanvas.height = this.size.height;
|
|
108
|
+
|
|
109
|
+
// Create temporary canvas for patch rendering
|
|
110
|
+
this.tempCanvas = document.createElement('canvas');
|
|
111
|
+
this.tempCtx = this.tempCanvas.getContext('2d')!;
|
|
112
|
+
|
|
113
|
+
// Create texture from canvas
|
|
114
|
+
this.texture = new THREE.CanvasTexture(this.gifCanvas);
|
|
115
|
+
this.texture.colorSpace = THREE.SRGBColorSpace;
|
|
116
|
+
|
|
117
|
+
// Start animation
|
|
118
|
+
this.startAnimation();
|
|
119
|
+
|
|
120
|
+
resolve();
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.error('Failed to load GIF:', error);
|
|
123
|
+
reject(error);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Starts the GIF animation loop.
|
|
130
|
+
*
|
|
131
|
+
* This method initializes the animation by setting up the rendering context,
|
|
132
|
+
* starting the timing mechanism, and beginning the animation frame loop.
|
|
133
|
+
* The animation automatically loops when all frames have been displayed.
|
|
134
|
+
*/
|
|
135
|
+
private startAnimation(): void {
|
|
136
|
+
if (!this.gifCanvas || this.frames.length === 0) return;
|
|
137
|
+
|
|
138
|
+
this.gifCtx = this.gifCanvas.getContext('2d')!;
|
|
139
|
+
this.startTime = performance.now();
|
|
140
|
+
this.lastFrameTime = this.startTime;
|
|
141
|
+
this.currentFrameIndex = -1;
|
|
142
|
+
this.totalPlayTime = 0;
|
|
143
|
+
|
|
144
|
+
const animate = () => {
|
|
145
|
+
this.animationId = requestAnimationFrame(animate);
|
|
146
|
+
|
|
147
|
+
const currentTime = performance.now();
|
|
148
|
+
const elapsedTime = currentTime - this.lastFrameTime;
|
|
149
|
+
this.lastFrameTime = currentTime;
|
|
150
|
+
|
|
151
|
+
const currentFrame = this.frames[this.currentFrameIndex];
|
|
152
|
+
const frameDelay = currentFrame?.delay ?? 0;
|
|
153
|
+
|
|
154
|
+
this.totalPlayTime += elapsedTime;
|
|
155
|
+
|
|
156
|
+
// If the current frame has played for its duration, advance to the next frame
|
|
157
|
+
if (this.totalPlayTime >= frameDelay) {
|
|
158
|
+
this.totalPlayTime -= frameDelay;
|
|
159
|
+
this.currentFrameIndex++;
|
|
160
|
+
|
|
161
|
+
// Loop back to the beginning
|
|
162
|
+
if (this.currentFrameIndex >= this.frames.length) {
|
|
163
|
+
this.currentFrameIndex = 0;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
this.renderFrame(this.currentFrameIndex);
|
|
167
|
+
|
|
168
|
+
// Update texture
|
|
169
|
+
if (this.texture) {
|
|
170
|
+
this.texture.needsUpdate = true;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// Start the animation loop
|
|
176
|
+
this.animationId = requestAnimationFrame(animate);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Renders a specific frame of the GIF animation.
|
|
181
|
+
*
|
|
182
|
+
* This method handles frame disposal methods and delegates the actual
|
|
183
|
+
* drawing to the drawPatch method.
|
|
184
|
+
*
|
|
185
|
+
* @param frameIndex - The index of the frame to render
|
|
186
|
+
*/
|
|
187
|
+
private renderFrame(frameIndex: number): void {
|
|
188
|
+
const frame = this.frames[frameIndex];
|
|
189
|
+
|
|
190
|
+
// Clear canvas if disposal method requires it (like the example)
|
|
191
|
+
if (frame.disposalType === 2) {
|
|
192
|
+
this.gifCtx!.clearRect(0, 0, this.gifCanvas!.width, this.gifCanvas!.height);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Draw the patch using the temporary canvas approach
|
|
196
|
+
this.drawPatch(frame);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Draws a frame patch onto the main canvas.
|
|
201
|
+
*
|
|
202
|
+
* This method uses a temporary canvas to efficiently render individual
|
|
203
|
+
* frame patches at their correct positions within the GIF.
|
|
204
|
+
*
|
|
205
|
+
* @param frame - The frame object containing patch data and dimensions
|
|
206
|
+
*/
|
|
207
|
+
private drawPatch(frame: GifFrame): void {
|
|
208
|
+
const dims = frame.dims;
|
|
209
|
+
|
|
210
|
+
// Resize temp canvas if needed
|
|
211
|
+
if (!this.tempCanvas || dims.width !== this.tempCanvas.width || dims.height !== this.tempCanvas.height) {
|
|
212
|
+
this.tempCanvas!.width = dims.width;
|
|
213
|
+
this.tempCanvas!.height = dims.height;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Create ImageData for the patch
|
|
217
|
+
const frameImageData = this.tempCtx!.createImageData(dims.width, dims.height);
|
|
218
|
+
|
|
219
|
+
// Set the patch data
|
|
220
|
+
frameImageData.data.set(frame.patch);
|
|
221
|
+
|
|
222
|
+
// Put the patch data on the temp canvas
|
|
223
|
+
this.tempCtx!.putImageData(frameImageData, 0, 0);
|
|
224
|
+
|
|
225
|
+
// Draw the temp canvas onto the main canvas at the correct position
|
|
226
|
+
this.gifCtx!.drawImage(this.tempCanvas!, dims.left, dims.top);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Disposes of all resources used by this data source.
|
|
231
|
+
*
|
|
232
|
+
* This method stops the animation loop, disposes of the Three.js texture,
|
|
233
|
+
* clears all canvas references, and resets internal state. It should be
|
|
234
|
+
* called before loading a new GIF or when the data source is no longer needed.
|
|
235
|
+
*/
|
|
236
|
+
dispose(): void {
|
|
237
|
+
// Stop animation
|
|
238
|
+
if (this.animationId) {
|
|
239
|
+
cancelAnimationFrame(this.animationId);
|
|
240
|
+
this.animationId = null;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Dispose of texture
|
|
244
|
+
if (this.texture) {
|
|
245
|
+
this.texture.dispose();
|
|
246
|
+
this.texture = null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Clear canvas
|
|
250
|
+
if (this.gifCanvas) {
|
|
251
|
+
this.gifCanvas = null;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Clear temp canvas
|
|
255
|
+
if (this.tempCanvas) {
|
|
256
|
+
this.tempCanvas = null;
|
|
257
|
+
this.tempCtx = null;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Clear frames
|
|
261
|
+
this.frames = [];
|
|
262
|
+
this.currentFrameIndex = 0;
|
|
263
|
+
this.size = null;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type * as THREE from 'three';
|
|
2
|
+
import type { Size } from '../../../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Interface for map data sources that provide textures for map layers.
|
|
6
|
+
*
|
|
7
|
+
* This interface defines the contract that all map data sources must implement.
|
|
8
|
+
* It provides a unified way to handle different types of media (images, videos, GIFs)
|
|
9
|
+
* as textures in a 3D map environment.
|
|
10
|
+
*/
|
|
11
|
+
export interface IMapDataSource {
|
|
12
|
+
/**
|
|
13
|
+
* Gets the texture to be displayed on the map plane.
|
|
14
|
+
*
|
|
15
|
+
* This can be a static texture, a video texture, or a canvas texture
|
|
16
|
+
* depending on the implementation. The texture is used to render the
|
|
17
|
+
* data source on a 3D plane in the scene.
|
|
18
|
+
*
|
|
19
|
+
* @returns The texture to be displayed on the map plane, or null if not loaded
|
|
20
|
+
*/
|
|
21
|
+
getTexture(): THREE.Texture | null;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Gets the dimensions of the map source.
|
|
25
|
+
*
|
|
26
|
+
* Returns the width and height of the data source, which is used
|
|
27
|
+
* to properly size and position the map layer in the 3D scene.
|
|
28
|
+
*
|
|
29
|
+
* @returns The dimensions of the map source, or null if not loaded
|
|
30
|
+
*/
|
|
31
|
+
getSize(): Size | null;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Loads the data source from a URL.
|
|
35
|
+
*
|
|
36
|
+
* This method handles the loading of different media types (images, videos, GIFs)
|
|
37
|
+
* from a given URL. The implementation should handle any necessary parsing,
|
|
38
|
+
* decompression, or setup required for the specific media type.
|
|
39
|
+
*
|
|
40
|
+
* @param url - The URL of the data source to load
|
|
41
|
+
* @returns A promise that resolves when the data source is loaded and ready
|
|
42
|
+
* @throws Error if the data source cannot be loaded or processed
|
|
43
|
+
*/
|
|
44
|
+
load(url: string): Promise<void>;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Cleans up resources used by the data source.
|
|
48
|
+
*
|
|
49
|
+
* This method should dispose of any textures, canvases, video elements,
|
|
50
|
+
* or other resources that were created during the loading process.
|
|
51
|
+
* It should be called when the data source is no longer needed to
|
|
52
|
+
* prevent memory leaks.
|
|
53
|
+
*/
|
|
54
|
+
dispose(): void;
|
|
55
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import type { Size } from '../../../types';
|
|
3
|
+
import type { IMapDataSource } from './IMapDataSource';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Data source for loading static images as textures in a 3D scene.
|
|
7
|
+
*
|
|
8
|
+
* This class implements the IMapDataSource interface to provide static image
|
|
9
|
+
* loading capabilities for map layers. It uses Three.js TextureLoader to load
|
|
10
|
+
* various image formats and create textures suitable for 3D rendering.
|
|
11
|
+
*/
|
|
12
|
+
export class ImageDataSource implements IMapDataSource {
|
|
13
|
+
/** The loaded texture from the image file */
|
|
14
|
+
private texture: THREE.Texture | null = null;
|
|
15
|
+
/** Dimensions of the loaded image */
|
|
16
|
+
private size: Size | null = null;
|
|
17
|
+
/** Three.js texture loader instance for loading images */
|
|
18
|
+
private loader = new THREE.TextureLoader();
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Gets the Three.js texture containing the loaded image.
|
|
22
|
+
*
|
|
23
|
+
* @returns The texture with the loaded image, or null if not loaded
|
|
24
|
+
*/
|
|
25
|
+
getTexture(): THREE.Texture | null {
|
|
26
|
+
return this.texture;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Gets the dimensions of the loaded image.
|
|
31
|
+
*
|
|
32
|
+
* @returns The width and height of the image, or null if not loaded
|
|
33
|
+
*/
|
|
34
|
+
getSize(): Size | null {
|
|
35
|
+
return this.size;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Loads an image from a URL and creates a texture.
|
|
40
|
+
*
|
|
41
|
+
* This method uses Three.js TextureLoader to load various image formats
|
|
42
|
+
* (JPG, PNG, WebP, etc.) and creates a texture with proper color space
|
|
43
|
+
* settings for 3D rendering.
|
|
44
|
+
*
|
|
45
|
+
* @param url - The URL of the image file to load
|
|
46
|
+
* @returns A promise that resolves when the image is loaded and ready
|
|
47
|
+
* @throws Error if the image cannot be loaded or processed
|
|
48
|
+
*/
|
|
49
|
+
async load(url: string): Promise<void> {
|
|
50
|
+
// Dispose of previous texture if it exists
|
|
51
|
+
this.dispose();
|
|
52
|
+
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
this.loader.load(
|
|
55
|
+
url,
|
|
56
|
+
(texture) => {
|
|
57
|
+
texture.colorSpace = THREE.SRGBColorSpace;
|
|
58
|
+
this.texture = texture;
|
|
59
|
+
this.size = {
|
|
60
|
+
width: texture.image.width,
|
|
61
|
+
height: texture.image.height
|
|
62
|
+
};
|
|
63
|
+
resolve();
|
|
64
|
+
},
|
|
65
|
+
undefined,
|
|
66
|
+
(error) => {
|
|
67
|
+
console.error('Failed to load image:', error);
|
|
68
|
+
reject(error);
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Disposes of the loaded texture and resets internal state.
|
|
76
|
+
*
|
|
77
|
+
* This method cleans up the Three.js texture to prevent memory leaks
|
|
78
|
+
* and resets the size information.
|
|
79
|
+
*/
|
|
80
|
+
dispose(): void {
|
|
81
|
+
if (this.texture) {
|
|
82
|
+
this.texture.dispose();
|
|
83
|
+
this.texture = null;
|
|
84
|
+
}
|
|
85
|
+
this.size = null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import type { Size } from '../../../types';
|
|
3
|
+
import type { IMapDataSource } from './IMapDataSource';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Data source for loading and playing video files as textures in a 3D scene.
|
|
7
|
+
*
|
|
8
|
+
* This class implements the IMapDataSource interface to provide video playback
|
|
9
|
+
* capabilities for map layers. It creates an HTML video element, sets up
|
|
10
|
+
* proper video attributes for web playback, and creates a Three.js VideoTexture
|
|
11
|
+
* for real-time video rendering in 3D space.
|
|
12
|
+
*/
|
|
13
|
+
export class VideoDataSource implements IMapDataSource {
|
|
14
|
+
/** HTML video element used for video playback */
|
|
15
|
+
private videoElement: HTMLVideoElement | null = null;
|
|
16
|
+
/** Three.js video texture created from the video element */
|
|
17
|
+
private texture: THREE.VideoTexture | null = null;
|
|
18
|
+
/** Dimensions of the video */
|
|
19
|
+
private size: Size | null = null;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Gets the Three.js video texture containing the playing video.
|
|
23
|
+
*
|
|
24
|
+
* @returns The video texture with the current video frame, or null if not loaded
|
|
25
|
+
*/
|
|
26
|
+
getTexture(): THREE.Texture | null {
|
|
27
|
+
return this.texture;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Gets the dimensions of the loaded video.
|
|
32
|
+
*
|
|
33
|
+
* @returns The width and height of the video, or null if not loaded
|
|
34
|
+
*/
|
|
35
|
+
getSize(): Size | null {
|
|
36
|
+
return this.size;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Loads a video from a URL and starts playback.
|
|
41
|
+
*
|
|
42
|
+
* This method creates an HTML video element with appropriate attributes
|
|
43
|
+
* for web playback (autoplay, muted, loop, etc.), sets up event listeners
|
|
44
|
+
* for loading and error handling, and creates a Three.js VideoTexture
|
|
45
|
+
* for real-time rendering in 3D space.
|
|
46
|
+
*
|
|
47
|
+
* @param url - The URL of the video file to load
|
|
48
|
+
* @returns A promise that resolves when the video is loaded and ready to play
|
|
49
|
+
* @throws Error if the video cannot be loaded or played
|
|
50
|
+
*/
|
|
51
|
+
async load(url: string): Promise<void> {
|
|
52
|
+
// Dispose of previous resources
|
|
53
|
+
this.dispose();
|
|
54
|
+
|
|
55
|
+
return new Promise((resolve, reject) => {
|
|
56
|
+
// Create video element
|
|
57
|
+
this.videoElement = document.createElement('video');
|
|
58
|
+
// Set crossOrigin to 'anonymous' for CORS-enabled servers
|
|
59
|
+
// This is required for THREE.VideoTexture to work with cross-origin videos
|
|
60
|
+
this.videoElement.crossOrigin = 'anonymous';
|
|
61
|
+
this.videoElement.loop = true;
|
|
62
|
+
this.videoElement.muted = true;
|
|
63
|
+
this.videoElement.playsInline = true;
|
|
64
|
+
this.videoElement.autoplay = true;
|
|
65
|
+
// Preload the video to ensure it's ready
|
|
66
|
+
this.videoElement.preload = 'auto';
|
|
67
|
+
|
|
68
|
+
// Wait for enough data to be loaded before creating texture
|
|
69
|
+
// 'canplaythrough' ensures the video has enough data buffered
|
|
70
|
+
const handleCanPlay = () => {
|
|
71
|
+
if (this.videoElement && this.videoElement.readyState >= 2) {
|
|
72
|
+
this.size = {
|
|
73
|
+
width: this.videoElement.videoWidth,
|
|
74
|
+
height: this.videoElement.videoHeight
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// Create video texture only when video is ready
|
|
78
|
+
this.texture = new THREE.VideoTexture(this.videoElement);
|
|
79
|
+
this.texture.colorSpace = THREE.SRGBColorSpace;
|
|
80
|
+
// Set texture parameters for better compatibility
|
|
81
|
+
this.texture.minFilter = THREE.LinearFilter;
|
|
82
|
+
this.texture.magFilter = THREE.LinearFilter;
|
|
83
|
+
this.texture.format = THREE.RGBAFormat;
|
|
84
|
+
// Disable mipmaps to prevent power-of-two issues
|
|
85
|
+
this.texture.generateMipmaps = false;
|
|
86
|
+
// Force texture update on every frame for videos
|
|
87
|
+
this.texture.needsUpdate = true;
|
|
88
|
+
|
|
89
|
+
// Start playback
|
|
90
|
+
this.videoElement.play().catch((e) => {
|
|
91
|
+
console.warn('Video autoplay failed:', e);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
resolve();
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// Use canplaythrough for Chrome compatibility
|
|
99
|
+
this.videoElement.addEventListener('canplaythrough', handleCanPlay, { once: true });
|
|
100
|
+
|
|
101
|
+
// Fallback: also listen for loadeddata as some browsers may not fire canplaythrough
|
|
102
|
+
this.videoElement.addEventListener(
|
|
103
|
+
'loadeddata',
|
|
104
|
+
() => {
|
|
105
|
+
// Give it a small delay to ensure the first frame is ready
|
|
106
|
+
setTimeout(() => {
|
|
107
|
+
if (!this.texture && this.videoElement && this.videoElement.readyState >= 2) {
|
|
108
|
+
handleCanPlay();
|
|
109
|
+
}
|
|
110
|
+
}, 100);
|
|
111
|
+
},
|
|
112
|
+
{ once: true }
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
this.videoElement.addEventListener('error', (error) => {
|
|
116
|
+
console.error('Failed to load video:', error);
|
|
117
|
+
reject(error);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Set source with cache busting
|
|
121
|
+
// Force reload by ensuring the URL is unique
|
|
122
|
+
this.videoElement.src = url;
|
|
123
|
+
// Force the browser to reload the video
|
|
124
|
+
this.videoElement.load();
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Disposes of the video element and texture, stopping playback.
|
|
130
|
+
*
|
|
131
|
+
* This method stops video playback, removes the video source,
|
|
132
|
+
* disposes of the Three.js texture, and cleans up all references
|
|
133
|
+
* to prevent memory leaks.
|
|
134
|
+
*/
|
|
135
|
+
dispose(): void {
|
|
136
|
+
if (this.videoElement) {
|
|
137
|
+
this.videoElement.pause();
|
|
138
|
+
this.videoElement.removeAttribute('src');
|
|
139
|
+
this.videoElement.load();
|
|
140
|
+
this.videoElement = null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (this.texture) {
|
|
144
|
+
this.texture.dispose();
|
|
145
|
+
this.texture = null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
this.size = null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { GifDataSource } from './GifDataSource';
|
|
2
|
+
import { ImageDataSource } from './ImageDataSource';
|
|
3
|
+
import type { IMapDataSource } from './IMapDataSource';
|
|
4
|
+
import { VideoDataSource } from './VideoDataSource';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Factory function that creates the appropriate data source based on file extension.
|
|
8
|
+
*
|
|
9
|
+
* This function analyzes the URL's file extension to determine which type of
|
|
10
|
+
* data source to create. It supports various media formats:
|
|
11
|
+
* - Video formats (mp4, webm, mov, avi) → VideoDataSource
|
|
12
|
+
* - GIF animations → GifDataSource
|
|
13
|
+
* - Image formats (jpg, jpeg, png, webp, bmp, tiff) → ImageDataSource
|
|
14
|
+
* - Unknown formats default to ImageDataSource
|
|
15
|
+
*
|
|
16
|
+
* @param url - The URL of the media file to load
|
|
17
|
+
* @returns An instance of the appropriate data source implementation
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const dataSource = createDataSource('https://example.com/image.jpg');
|
|
22
|
+
* await dataSource.load('https://example.com/image.jpg');
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function createDataSource(url: string): IMapDataSource {
|
|
26
|
+
const urlWithoutParams = url.split('?')[0];
|
|
27
|
+
const extension = urlWithoutParams.split('.').pop()?.toLowerCase() || '';
|
|
28
|
+
|
|
29
|
+
switch (extension) {
|
|
30
|
+
case 'mp4':
|
|
31
|
+
case 'webm':
|
|
32
|
+
case 'mov':
|
|
33
|
+
case 'avi':
|
|
34
|
+
return new VideoDataSource();
|
|
35
|
+
|
|
36
|
+
case 'gif':
|
|
37
|
+
return new GifDataSource();
|
|
38
|
+
|
|
39
|
+
case 'jpg':
|
|
40
|
+
case 'jpeg':
|
|
41
|
+
case 'png':
|
|
42
|
+
case 'webp':
|
|
43
|
+
case 'bmp':
|
|
44
|
+
case 'tiff':
|
|
45
|
+
default:
|
|
46
|
+
return new ImageDataSource();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map Layer Data Sources Module
|
|
3
|
+
*
|
|
4
|
+
* This module provides a unified interface for loading different types of media
|
|
5
|
+
* as textures in 3D map layers. It includes implementations for static images,
|
|
6
|
+
* video files, and animated GIFs, along with a factory function to automatically
|
|
7
|
+
* select the appropriate data source based on file extension.
|
|
8
|
+
*
|
|
9
|
+
* @module MapLayerDataSources
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export { createDataSource } from './dataSourceFactory';
|
|
13
|
+
export { GifDataSource } from './GifDataSource';
|
|
14
|
+
export { ImageDataSource } from './ImageDataSource';
|
|
15
|
+
export type { IMapDataSource } from './IMapDataSource';
|
|
16
|
+
export { VideoDataSource } from './VideoDataSource';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
|
|
3
|
+
export enum MapLayerType {
|
|
4
|
+
None = 0,
|
|
5
|
+
FogOfWar = 1,
|
|
6
|
+
Marker = 2,
|
|
7
|
+
Annotation = 3,
|
|
8
|
+
Measurement = 4
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Props for the Map layer
|
|
13
|
+
*/
|
|
14
|
+
export interface MapLayerProps {
|
|
15
|
+
/**
|
|
16
|
+
* The position of the map relative to the scene
|
|
17
|
+
*/
|
|
18
|
+
offset: {
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Rotation of the map relative to the scene in degrees
|
|
25
|
+
*/
|
|
26
|
+
rotation: number;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Url for the map image
|
|
30
|
+
*/
|
|
31
|
+
url: string;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Indicates if the map should autoplay (for video assets)
|
|
35
|
+
* @default true
|
|
36
|
+
*/
|
|
37
|
+
autoplay?: boolean;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The scale of the map relative to the scene
|
|
41
|
+
*/
|
|
42
|
+
zoom: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface MapLayerExports {
|
|
46
|
+
getCompositeMapTexture: () => THREE.Texture | null;
|
|
47
|
+
fit: () => void;
|
|
48
|
+
fill: () => void;
|
|
49
|
+
mapSize: { width: number; height: number } | null;
|
|
50
|
+
fogOfWar: {
|
|
51
|
+
clear: () => void;
|
|
52
|
+
reset: () => void;
|
|
53
|
+
toPng: () => Promise<Blob>;
|
|
54
|
+
toRLE: () => Promise<Uint8Array>;
|
|
55
|
+
fromRLE: (rleData: Uint8Array, width: number, height: number) => Promise<void>;
|
|
56
|
+
isDrawing: () => boolean;
|
|
57
|
+
};
|
|
58
|
+
}
|