@gradio/imageeditor 0.15.5 → 0.16.0
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/CHANGELOG.md +14 -0
- package/ImageEditor.stories.svelte +0 -1
- package/Index.svelte +3 -3
- package/InteractiveImageEditor.svelte +1 -1
- package/dist/Index.svelte +1 -2
- package/dist/Index.svelte.d.ts +4 -3
- package/dist/InteractiveImageEditor.svelte +1 -1
- package/dist/InteractiveImageEditor.svelte.d.ts +1 -1
- package/dist/shared/ImageEditor.svelte +62 -10
- package/dist/shared/ImageEditor.svelte.d.ts +1 -3
- package/dist/shared/brush/brush-textures.d.ts +42 -9
- package/dist/shared/brush/brush-textures.js +211 -74
- package/dist/shared/brush/brush.js +8 -3
- package/dist/shared/core/commands.d.ts +7 -6
- package/dist/shared/core/commands.js +26 -15
- package/dist/shared/core/editor.d.ts +1 -1
- package/dist/shared/core/editor.js +19 -11
- package/dist/shared/core/layers.d.ts +3 -3
- package/dist/shared/core/layers.js +22 -5
- package/dist/shared/image/image.d.ts +1 -1
- package/dist/shared/image/image.js +4 -1
- package/dist/shared/resize/resize.d.ts +1 -1
- package/dist/shared/resize/resize.js +4 -1
- package/package.json +9 -9
- package/shared/ImageEditor.svelte +85 -17
- package/shared/brush/BrushOptions.svelte +0 -3
- package/shared/brush/ColorPicker.svelte +2 -2
- package/shared/brush/brush-textures.ts +296 -107
- package/shared/brush/brush.ts +14 -3
- package/shared/core/commands.ts +36 -20
- package/shared/core/editor.ts +22 -13
- package/shared/core/layers.ts +29 -5
- package/shared/image/image.ts +5 -1
- package/shared/resize/resize.ts +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @gradio/imageeditor
|
|
2
2
|
|
|
3
|
+
## 0.16.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- [#11427](https://github.com/gradio-app/gradio/pull/11427) [`6b2bcd0`](https://github.com/gradio-app/gradio/commit/6b2bcd097ae5ef999a7fb273ecf7c7e4c0eab305) - Improve load times of the Gradio front-end. Thanks @pngwn!
|
|
8
|
+
|
|
9
|
+
### Dependency updates
|
|
10
|
+
|
|
11
|
+
- @gradio/atoms@0.16.3
|
|
12
|
+
- @gradio/statustracker@0.10.14
|
|
13
|
+
- @gradio/upload@0.16.10
|
|
14
|
+
- @gradio/client@1.15.5
|
|
15
|
+
- @gradio/image@0.22.12
|
|
16
|
+
|
|
3
17
|
## 0.15.5
|
|
4
18
|
|
|
5
19
|
### Dependency updates
|
package/Index.svelte
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
Source,
|
|
20
20
|
WebcamOptions
|
|
21
21
|
} from "./shared/types";
|
|
22
|
+
import type { CommandNode } from "./shared/core/commands";
|
|
22
23
|
|
|
23
24
|
export let elem_id = "";
|
|
24
25
|
export let elem_classes: string[] = [];
|
|
@@ -57,7 +58,7 @@
|
|
|
57
58
|
export let canvas_size: [number, number];
|
|
58
59
|
export let fixed_canvas = false;
|
|
59
60
|
export let show_fullscreen_button = true;
|
|
60
|
-
export let full_history:
|
|
61
|
+
export let full_history: CommandNode | null = null;
|
|
61
62
|
export let gradio: Gradio<{
|
|
62
63
|
change: never;
|
|
63
64
|
error: string;
|
|
@@ -199,7 +200,6 @@
|
|
|
199
200
|
|
|
200
201
|
<InteractiveImageEditor
|
|
201
202
|
{border_region}
|
|
202
|
-
on:history={(e) => (full_history = e.detail)}
|
|
203
203
|
bind:is_dragging
|
|
204
204
|
{canvas_size}
|
|
205
205
|
on:change={() => handle_history_change()}
|
|
@@ -242,7 +242,7 @@
|
|
|
242
242
|
layer_options={layers}
|
|
243
243
|
upload={(...args) => gradio.client.upload(...args)}
|
|
244
244
|
{placeholder}
|
|
245
|
-
|
|
245
|
+
bind:full_history
|
|
246
246
|
{webcam_options}
|
|
247
247
|
{show_download_button}
|
|
248
248
|
{theme_mode}
|
|
@@ -223,7 +223,6 @@
|
|
|
223
223
|
on:clear={() => dispatch("clear")}
|
|
224
224
|
on:download_error
|
|
225
225
|
{sources}
|
|
226
|
-
{full_history}
|
|
227
226
|
bind:background_image
|
|
228
227
|
bind:current_tool
|
|
229
228
|
brush_options={brush}
|
|
@@ -240,6 +239,7 @@
|
|
|
240
239
|
{show_download_button}
|
|
241
240
|
{theme_mode}
|
|
242
241
|
bind:can_undo
|
|
242
|
+
bind:full_history
|
|
243
243
|
>
|
|
244
244
|
{#if current_tool === "image" && !can_undo}
|
|
245
245
|
<div class="empty wrap">
|
package/dist/Index.svelte
CHANGED
|
@@ -152,7 +152,6 @@ $:
|
|
|
152
152
|
|
|
153
153
|
<InteractiveImageEditor
|
|
154
154
|
{border_region}
|
|
155
|
-
on:history={(e) => (full_history = e.detail)}
|
|
156
155
|
bind:is_dragging
|
|
157
156
|
{canvas_size}
|
|
158
157
|
on:change={() => handle_history_change()}
|
|
@@ -195,7 +194,7 @@ $:
|
|
|
195
194
|
layer_options={layers}
|
|
196
195
|
upload={(...args) => gradio.client.upload(...args)}
|
|
197
196
|
{placeholder}
|
|
198
|
-
|
|
197
|
+
bind:full_history
|
|
199
198
|
{webcam_options}
|
|
200
199
|
{show_download_button}
|
|
201
200
|
{theme_mode}
|
package/dist/Index.svelte.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { EditorData, ImageBlobs } from "./InteractiveImageEditor.svelte";
|
|
|
4
4
|
import type { Gradio, SelectData } from "@gradio/utils";
|
|
5
5
|
import type { LoadingStatus } from "@gradio/statustracker";
|
|
6
6
|
import type { LayerOptions, Transform, Source, WebcamOptions } from "./shared/types";
|
|
7
|
+
import type { CommandNode } from "./shared/core/commands";
|
|
7
8
|
declare const __propDef: {
|
|
8
9
|
props: {
|
|
9
10
|
elem_id?: string | undefined;
|
|
@@ -37,7 +38,7 @@ declare const __propDef: {
|
|
|
37
38
|
canvas_size: [number, number];
|
|
38
39
|
fixed_canvas?: boolean | undefined;
|
|
39
40
|
show_fullscreen_button?: boolean | undefined;
|
|
40
|
-
full_history?:
|
|
41
|
+
full_history?: (CommandNode | null) | undefined;
|
|
41
42
|
gradio: Gradio<{
|
|
42
43
|
change: never;
|
|
43
44
|
error: string;
|
|
@@ -163,9 +164,9 @@ export default class Index extends SvelteComponent<IndexProps, IndexEvents, Inde
|
|
|
163
164
|
get show_fullscreen_button(): boolean | undefined;
|
|
164
165
|
/**accessor*/
|
|
165
166
|
set show_fullscreen_button(_: boolean | undefined);
|
|
166
|
-
get full_history():
|
|
167
|
+
get full_history(): CommandNode | null | undefined;
|
|
167
168
|
/**accessor*/
|
|
168
|
-
set full_history(_:
|
|
169
|
+
set full_history(_: CommandNode | null | undefined);
|
|
169
170
|
get gradio(): Gradio<{
|
|
170
171
|
change: never;
|
|
171
172
|
error: string;
|
|
@@ -173,7 +173,6 @@ let current_tool;
|
|
|
173
173
|
on:clear={() => dispatch("clear")}
|
|
174
174
|
on:download_error
|
|
175
175
|
{sources}
|
|
176
|
-
{full_history}
|
|
177
176
|
bind:background_image
|
|
178
177
|
bind:current_tool
|
|
179
178
|
brush_options={brush}
|
|
@@ -190,6 +189,7 @@ let current_tool;
|
|
|
190
189
|
{show_download_button}
|
|
191
190
|
{theme_mode}
|
|
192
191
|
bind:can_undo
|
|
192
|
+
bind:full_history
|
|
193
193
|
>
|
|
194
194
|
{#if current_tool === "image" && !can_undo}
|
|
195
195
|
<div class="empty wrap">
|
|
@@ -45,7 +45,7 @@ declare const __propDef: {
|
|
|
45
45
|
image_id?: (null | string) | undefined;
|
|
46
46
|
};
|
|
47
47
|
events: {
|
|
48
|
-
history: CustomEvent<
|
|
48
|
+
history: CustomEvent<any>;
|
|
49
49
|
save: CustomEvent<void>;
|
|
50
50
|
download_error: CustomEvent<string>;
|
|
51
51
|
clear?: CustomEvent<undefined> | undefined;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
</script>
|
|
3
3
|
|
|
4
4
|
<script>import { onMount, createEventDispatcher, tick } from "svelte";
|
|
5
|
+
import { get } from "svelte/store";
|
|
5
6
|
import Toolbar, {} from "./Toolbar.svelte";
|
|
6
7
|
import { CropTool } from "./crop/crop";
|
|
7
8
|
import { ResizeTool } from "./resize/resize";
|
|
@@ -21,7 +22,6 @@ import IconButton from "./IconButton.svelte";
|
|
|
21
22
|
const { drag, open_file_upload } = create_drag();
|
|
22
23
|
const dispatch = createEventDispatcher();
|
|
23
24
|
export const antialias = true;
|
|
24
|
-
export const full_history = null;
|
|
25
25
|
export let changeable = false;
|
|
26
26
|
export let sources = ["upload", "webcam", "clipboard"];
|
|
27
27
|
export let transforms = ["crop", "resize"];
|
|
@@ -43,6 +43,7 @@ export let current_tool;
|
|
|
43
43
|
export let webcam_options;
|
|
44
44
|
export let show_download_button = false;
|
|
45
45
|
export let theme_mode;
|
|
46
|
+
export let full_history = null;
|
|
46
47
|
let pixi_target;
|
|
47
48
|
let pixi_target_crop;
|
|
48
49
|
$:
|
|
@@ -53,9 +54,34 @@ $:
|
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
function refresh_tools() {
|
|
57
|
+
if (!editor || !ready)
|
|
58
|
+
return;
|
|
56
59
|
editor.set_tool(current_tool);
|
|
57
60
|
editor.set_subtool(current_subtool);
|
|
58
61
|
}
|
|
62
|
+
$:
|
|
63
|
+
if (editor && ready && editor.layers) {
|
|
64
|
+
const current_layers = get(editor.layers);
|
|
65
|
+
if (current_layers.layers.length > 0 && !current_layers.active_layer) {
|
|
66
|
+
refresh_tools_for_layer_changes(current_layers);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function refresh_tools_for_layer_changes(current_layers) {
|
|
70
|
+
if (!editor || !ready)
|
|
71
|
+
return;
|
|
72
|
+
if (current_layers.layers.length > 0 && !current_layers.active_layer) {
|
|
73
|
+
editor.set_layer(current_layers.layers[0].id);
|
|
74
|
+
}
|
|
75
|
+
if (current_tool) {
|
|
76
|
+
editor.set_tool(current_tool);
|
|
77
|
+
if (current_subtool) {
|
|
78
|
+
editor.set_subtool(current_subtool);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (brush && (current_tool === "draw" || current_tool === "erase")) {
|
|
82
|
+
brush.set_tool(current_tool, current_subtool);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
59
85
|
function check_if_should_init() {
|
|
60
86
|
return layer_options && editor && ready;
|
|
61
87
|
}
|
|
@@ -148,7 +174,17 @@ onMount(() => {
|
|
|
148
174
|
});
|
|
149
175
|
intersection_observer.observe(pixi_target);
|
|
150
176
|
resize_observer.observe(pixi_target);
|
|
177
|
+
setTimeout(() => {
|
|
178
|
+
if (full_history && editor) {
|
|
179
|
+
editor.command_manager.replay(full_history, editor.context).then(() => {
|
|
180
|
+
refresh_tools_after_history();
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}, 0);
|
|
151
184
|
});
|
|
185
|
+
if (typeof window !== "undefined") {
|
|
186
|
+
window.editor = editor;
|
|
187
|
+
}
|
|
152
188
|
return () => {
|
|
153
189
|
if (intersection_observer) {
|
|
154
190
|
intersection_observer.disconnect();
|
|
@@ -161,6 +197,24 @@ onMount(() => {
|
|
|
161
197
|
}
|
|
162
198
|
};
|
|
163
199
|
});
|
|
200
|
+
function refresh_tools_after_history() {
|
|
201
|
+
if (!editor || !ready)
|
|
202
|
+
return;
|
|
203
|
+
const current_layers = get(editor.layers);
|
|
204
|
+
if (current_layers.layers.length > 0 && !current_layers.active_layer) {
|
|
205
|
+
editor.set_layer(current_layers.layers[0].id);
|
|
206
|
+
}
|
|
207
|
+
if (current_tool) {
|
|
208
|
+
editor.set_tool(current_tool);
|
|
209
|
+
if (current_subtool) {
|
|
210
|
+
editor.set_subtool(current_subtool);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (brush && (current_tool === "draw" || current_tool === "erase")) {
|
|
214
|
+
brush.set_tool(current_tool, current_subtool);
|
|
215
|
+
}
|
|
216
|
+
full_history = editor.command_manager.history;
|
|
217
|
+
}
|
|
164
218
|
let crop;
|
|
165
219
|
let crop_zoom;
|
|
166
220
|
export let can_undo = false;
|
|
@@ -201,6 +255,10 @@ async function init_image_editor() {
|
|
|
201
255
|
editor.dimensions.subscribe((dimensions) => {
|
|
202
256
|
last_dimensions = { ...dimensions };
|
|
203
257
|
});
|
|
258
|
+
editor.command_manager.current_history.subscribe((history) => {
|
|
259
|
+
can_undo = history.previous !== null;
|
|
260
|
+
can_redo = history.next !== null;
|
|
261
|
+
});
|
|
204
262
|
await Promise.all([editor.ready, crop.ready]).then(() => {
|
|
205
263
|
handle_tool_change({ tool: "image" });
|
|
206
264
|
ready = true;
|
|
@@ -213,8 +271,7 @@ async function init_image_editor() {
|
|
|
213
271
|
});
|
|
214
272
|
editor.on("change", () => {
|
|
215
273
|
dispatch("change");
|
|
216
|
-
|
|
217
|
-
can_redo = editor.command_manager.history.next !== null;
|
|
274
|
+
full_history = editor.command_manager.history;
|
|
218
275
|
});
|
|
219
276
|
if (background || layers.length > 0) {
|
|
220
277
|
if (background) {
|
|
@@ -228,10 +285,10 @@ async function init_image_editor() {
|
|
|
228
285
|
await add_image_from_url(composite);
|
|
229
286
|
handle_tool_change({ tool: "draw" });
|
|
230
287
|
}
|
|
288
|
+
refresh_tools();
|
|
231
289
|
}
|
|
232
290
|
$:
|
|
233
291
|
if (background == null && layers.length == 0 && composite == null && editor && ready) {
|
|
234
|
-
editor.reset_canvas();
|
|
235
292
|
handle_tool_change({ tool: "image" });
|
|
236
293
|
background_image = false;
|
|
237
294
|
has_drawn = false;
|
|
@@ -243,6 +300,7 @@ async function handle_files(files) {
|
|
|
243
300
|
return;
|
|
244
301
|
if (!sources.includes("upload"))
|
|
245
302
|
return;
|
|
303
|
+
editor.reset_canvas();
|
|
246
304
|
const _file = Array.isArray(files) ? files[0] : files;
|
|
247
305
|
await editor.add_image({ image: _file });
|
|
248
306
|
await crop.add_image({ image: _file });
|
|
@@ -252,8 +310,6 @@ async function handle_files(files) {
|
|
|
252
310
|
dispatch("upload");
|
|
253
311
|
dispatch("input");
|
|
254
312
|
dispatch("change");
|
|
255
|
-
can_undo = editor.command_manager.history.previous !== null;
|
|
256
|
-
can_redo = editor.command_manager.history.next !== null;
|
|
257
313
|
}
|
|
258
314
|
$:
|
|
259
315
|
background_image = can_undo && editor.command_manager.contains("AddImage");
|
|
@@ -418,13 +474,9 @@ async function handle_download() {
|
|
|
418
474
|
}
|
|
419
475
|
function handle_undo() {
|
|
420
476
|
editor.undo();
|
|
421
|
-
can_undo = editor.command_manager.history.previous !== null;
|
|
422
|
-
can_redo = editor.command_manager.history.next !== null;
|
|
423
477
|
}
|
|
424
478
|
function handle_redo() {
|
|
425
479
|
editor.redo();
|
|
426
|
-
can_undo = editor.command_manager.history.previous !== null;
|
|
427
|
-
can_redo = editor.command_manager.history.next !== null;
|
|
428
480
|
}
|
|
429
481
|
</script>
|
|
430
482
|
|
|
@@ -11,7 +11,6 @@ import { type ImageBlobs } from "./types";
|
|
|
11
11
|
declare const __propDef: {
|
|
12
12
|
props: {
|
|
13
13
|
antialias?: true | undefined;
|
|
14
|
-
full_history?: (CommandNode | null) | undefined;
|
|
15
14
|
changeable?: boolean | undefined;
|
|
16
15
|
sources?: Source[] | undefined;
|
|
17
16
|
transforms?: Transform[] | undefined;
|
|
@@ -33,6 +32,7 @@ declare const __propDef: {
|
|
|
33
32
|
webcam_options: WebcamOptions;
|
|
34
33
|
show_download_button?: boolean | undefined;
|
|
35
34
|
theme_mode: "dark" | "light";
|
|
35
|
+
full_history?: (CommandNode | null) | undefined;
|
|
36
36
|
has_drawn?: boolean | undefined;
|
|
37
37
|
get_blobs?: (() => Promise<ImageBlobs>) | undefined;
|
|
38
38
|
add_image?: ((image: Blob | File) => void) | undefined;
|
|
@@ -51,7 +51,6 @@ declare const __propDef: {
|
|
|
51
51
|
clear?: CustomEvent<undefined> | undefined;
|
|
52
52
|
save: CustomEvent<void>;
|
|
53
53
|
change: CustomEvent<void>;
|
|
54
|
-
history: CustomEvent<import("svelte/store").Writable<CommandNode>>;
|
|
55
54
|
upload: CustomEvent<void>;
|
|
56
55
|
input: CustomEvent<void>;
|
|
57
56
|
download_error: CustomEvent<string>;
|
|
@@ -67,7 +66,6 @@ export type ImageEditorEvents = typeof __propDef.events;
|
|
|
67
66
|
export type ImageEditorSlots = typeof __propDef.slots;
|
|
68
67
|
export default class ImageEditor extends SvelteComponent<ImageEditorProps, ImageEditorEvents, ImageEditorSlots> {
|
|
69
68
|
get antialias(): true;
|
|
70
|
-
get full_history(): CommandNode;
|
|
71
69
|
get get_blobs(): () => Promise<ImageBlobs>;
|
|
72
70
|
get add_image(): (image: Blob | File) => void;
|
|
73
71
|
get add_image_from_url(): (source: string | {
|
|
@@ -1,18 +1,46 @@
|
|
|
1
1
|
import { Application, Texture } from "pixi.js";
|
|
2
2
|
import { type ImageEditorContext } from "../core/editor";
|
|
3
3
|
import { type Command } from "../core/commands";
|
|
4
|
+
/**
|
|
5
|
+
* Represents a single drawing segment with all its parameters
|
|
6
|
+
*/
|
|
7
|
+
interface BrushSegment {
|
|
8
|
+
from_x: number;
|
|
9
|
+
from_y: number;
|
|
10
|
+
to_x: number;
|
|
11
|
+
to_y: number;
|
|
12
|
+
size: number;
|
|
13
|
+
color: string;
|
|
14
|
+
opacity: number;
|
|
15
|
+
mode: "draw" | "erase";
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Represents a complete brush stroke containing multiple segments
|
|
19
|
+
*/
|
|
20
|
+
interface BrushStroke {
|
|
21
|
+
segments: BrushSegment[];
|
|
22
|
+
layer_id: string;
|
|
23
|
+
}
|
|
4
24
|
export declare class BrushCommand implements Command {
|
|
25
|
+
private stroke_data;
|
|
5
26
|
private context;
|
|
6
|
-
private layer_id;
|
|
7
27
|
private original_texture;
|
|
8
|
-
private final_texture;
|
|
9
28
|
name: string;
|
|
10
|
-
constructor(context: ImageEditorContext,
|
|
29
|
+
constructor(context: ImageEditorContext, stroke_data: BrushStroke, original_texture?: Texture);
|
|
11
30
|
/**
|
|
12
31
|
* Creates a new texture with the same content as the source texture
|
|
13
32
|
*/
|
|
14
|
-
private
|
|
15
|
-
|
|
33
|
+
private create_texture_from;
|
|
34
|
+
/**
|
|
35
|
+
* Recreates the stroke by rendering all segments from the stored parameters
|
|
36
|
+
* Preserves the exact order of draw/erase operations
|
|
37
|
+
*/
|
|
38
|
+
private render_stroke_from_data;
|
|
39
|
+
/**
|
|
40
|
+
* Renders a segment to a graphics object (extracted from renderSegment)
|
|
41
|
+
*/
|
|
42
|
+
private render_segment_to_graphics;
|
|
43
|
+
execute(context: ImageEditorContext): Promise<void>;
|
|
16
44
|
undo(): Promise<void>;
|
|
17
45
|
}
|
|
18
46
|
/**
|
|
@@ -20,8 +48,6 @@ export declare class BrushCommand implements Command {
|
|
|
20
48
|
* Simplified to work directly with layer textures.
|
|
21
49
|
*/
|
|
22
50
|
export declare class BrushTextures {
|
|
23
|
-
private image_editor_context;
|
|
24
|
-
private app;
|
|
25
51
|
private stroke_texture;
|
|
26
52
|
private erase_texture;
|
|
27
53
|
private display_container;
|
|
@@ -30,11 +56,13 @@ export declare class BrushTextures {
|
|
|
30
56
|
private preview_sprite;
|
|
31
57
|
private erase_graphics;
|
|
32
58
|
private dimensions;
|
|
59
|
+
private image_editor_context;
|
|
60
|
+
private app;
|
|
33
61
|
private is_new_stroke;
|
|
34
62
|
private current_opacity;
|
|
35
|
-
private current_mode;
|
|
36
63
|
private original_layer_texture;
|
|
37
64
|
private active_layer_id;
|
|
65
|
+
private current_stroke_segments;
|
|
38
66
|
constructor(image_editor_context: ImageEditorContext, app: Application);
|
|
39
67
|
/**
|
|
40
68
|
* Initializes textures needed for the brush tool.
|
|
@@ -63,7 +91,7 @@ export declare class BrushTextures {
|
|
|
63
91
|
/**
|
|
64
92
|
* Calculates the distance between two points.
|
|
65
93
|
*/
|
|
66
|
-
private
|
|
94
|
+
private calculate_distance;
|
|
67
95
|
/**
|
|
68
96
|
* Draws a segment for the current stroke using a simple "stamp" approach.
|
|
69
97
|
*/
|
|
@@ -75,8 +103,13 @@ export declare class BrushTextures {
|
|
|
75
103
|
width: number;
|
|
76
104
|
height: number;
|
|
77
105
|
};
|
|
106
|
+
/**
|
|
107
|
+
* Checks if textures are properly initialized.
|
|
108
|
+
*/
|
|
109
|
+
get textures_initialized(): boolean;
|
|
78
110
|
/**
|
|
79
111
|
* Cleanup all resources.
|
|
80
112
|
*/
|
|
81
113
|
cleanup(): void;
|
|
82
114
|
}
|
|
115
|
+
export {};
|