@gradio/imageeditor 0.12.14 → 0.13.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/Example.svelte +1 -1
- package/IMAGE_EDITOR_OVERVIEW.md +224 -0
- package/ImageEditor.stories.svelte +4 -4
- package/Index.svelte +35 -46
- package/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +56 -103
- package/dist/Example.svelte.d.ts +1 -1
- package/dist/Index.svelte +29 -33
- package/dist/Index.svelte.d.ts +17 -16
- package/dist/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +47 -88
- package/dist/{shared/InteractiveImageEditor.svelte.d.ts → InteractiveImageEditor.svelte.d.ts} +13 -15
- package/dist/shared/Anchor.svelte +311 -0
- package/dist/shared/Anchor.svelte.d.ts +18 -0
- package/dist/shared/Controls.svelte +162 -23
- package/dist/shared/Controls.svelte.d.ts +7 -2
- package/dist/shared/{tools/IconButton.svelte → IconButton.svelte} +19 -3
- package/dist/shared/{tools/IconButton.svelte.d.ts → IconButton.svelte.d.ts} +4 -1
- package/dist/shared/ImageEditor.svelte +546 -289
- package/dist/shared/ImageEditor.svelte.d.ts +51 -56
- package/dist/shared/Layers.svelte +233 -0
- package/dist/shared/Layers.svelte.d.ts +35 -0
- package/dist/shared/Resize.svelte +218 -0
- package/dist/shared/Resize.svelte.d.ts +29 -0
- package/dist/shared/SecondaryToolbar.svelte +54 -0
- package/dist/shared/SecondaryToolbar.svelte.d.ts +35 -0
- package/dist/shared/Toolbar.svelte +337 -0
- package/dist/shared/Toolbar.svelte.d.ts +42 -0
- package/dist/shared/{tools → brush}/BrushOptions.svelte +68 -64
- package/dist/shared/{tools → brush}/BrushOptions.svelte.d.ts +9 -9
- package/dist/shared/{tools → brush}/BrushSize.svelte +2 -27
- package/dist/shared/{tools → brush}/ColorField.svelte +2 -1
- package/dist/shared/{tools → brush}/ColorField.svelte.d.ts +1 -0
- package/dist/shared/{tools → brush}/ColorPicker.svelte +81 -9
- package/dist/shared/{tools → brush}/ColorPicker.svelte.d.ts +1 -0
- package/dist/shared/{tools → brush}/ColorSwatch.svelte +78 -38
- package/dist/shared/{tools → brush}/ColorSwatch.svelte.d.ts +6 -2
- package/dist/shared/brush/brush-cursor.d.ts +101 -0
- package/dist/shared/brush/brush-cursor.js +327 -0
- package/dist/shared/brush/brush-textures.d.ts +71 -0
- package/dist/shared/brush/brush-textures.js +404 -0
- package/dist/shared/brush/brush-utils.d.ts +32 -0
- package/dist/shared/brush/brush-utils.js +59 -0
- package/dist/shared/brush/brush.d.ts +152 -0
- package/dist/shared/brush/brush.js +396 -0
- package/dist/shared/brush/types.d.ts +37 -0
- package/dist/shared/brush/types.js +1 -0
- package/dist/shared/core/editor.d.ts +252 -0
- package/dist/shared/core/editor.js +1221 -0
- package/dist/shared/crop/crop.d.ts +201 -0
- package/dist/shared/crop/crop.js +727 -0
- package/dist/shared/image/image.d.ts +89 -0
- package/dist/shared/image/image.js +185 -0
- package/dist/shared/resize/resize.d.ts +270 -0
- package/dist/shared/resize/resize.js +1413 -0
- package/dist/shared/types.d.ts +12 -0
- package/dist/shared/utils/pixi.d.ts +16 -57
- package/dist/shared/utils/pixi.js +15 -113
- package/dist/shared/zoom/zoom.d.ts +136 -0
- package/dist/shared/zoom/zoom.js +548 -0
- package/package.json +10 -9
- package/shared/Anchor.svelte +384 -0
- package/shared/Controls.svelte +194 -27
- package/shared/{tools/IconButton.svelte → IconButton.svelte} +21 -4
- package/shared/ImageEditor.svelte +682 -349
- package/shared/Layers.svelte +249 -0
- package/shared/Resize.svelte +239 -0
- package/shared/SecondaryToolbar.svelte +61 -0
- package/shared/Toolbar.svelte +386 -0
- package/shared/brush/BRUSH_TOOL.md +134 -0
- package/shared/brush/BrushOptions.svelte +200 -0
- package/shared/{tools → brush}/BrushSize.svelte +2 -30
- package/shared/{tools → brush}/ColorField.svelte +3 -1
- package/shared/{tools → brush}/ColorPicker.svelte +86 -9
- package/shared/{tools → brush}/ColorSwatch.svelte +95 -42
- package/shared/brush/brush-cursor.ts +408 -0
- package/shared/brush/brush-textures.ts +508 -0
- package/shared/brush/brush-utils.ts +76 -0
- package/shared/brush/brush.ts +506 -0
- package/shared/brush/types.ts +41 -0
- package/shared/core/EDITOR.md +182 -0
- package/shared/core/editor.ts +1730 -0
- package/shared/crop/CROP.md +139 -0
- package/shared/crop/crop.ts +1027 -0
- package/shared/image/IMAGE.md +135 -0
- package/shared/image/image.ts +300 -0
- package/shared/resize/resize.ts +1894 -0
- package/shared/types.ts +14 -0
- package/shared/utils/pixi.ts +19 -246
- package/shared/zoom/zoom.ts +729 -0
- package/dist/shared/layers/Layers.svelte +0 -231
- package/dist/shared/layers/Layers.svelte.d.ts +0 -18
- package/dist/shared/layers/utils.d.ts +0 -73
- package/dist/shared/layers/utils.js +0 -156
- package/dist/shared/tools/Brush.svelte +0 -215
- package/dist/shared/tools/Brush.svelte.d.ts +0 -29
- package/dist/shared/tools/Crop.svelte +0 -155
- package/dist/shared/tools/Crop.svelte.d.ts +0 -16
- package/dist/shared/tools/Cropper.svelte +0 -271
- package/dist/shared/tools/Cropper.svelte.d.ts +0 -41
- package/dist/shared/tools/Handle.svelte +0 -260
- package/dist/shared/tools/Handle.svelte.d.ts +0 -29
- package/dist/shared/tools/Sources.svelte +0 -257
- package/dist/shared/tools/Sources.svelte.d.ts +0 -34
- package/dist/shared/tools/Tools.svelte +0 -102
- package/dist/shared/tools/Tools.svelte.d.ts +0 -48
- package/dist/shared/tools/brush.d.ts +0 -62
- package/dist/shared/tools/brush.js +0 -133
- package/dist/shared/tools/crop.d.ts +0 -15
- package/dist/shared/tools/crop.js +0 -154
- package/dist/shared/tools/index.d.ts +0 -5
- package/dist/shared/tools/index.js +0 -5
- package/dist/shared/tools/sources.d.ts +0 -46
- package/dist/shared/tools/sources.js +0 -121
- package/dist/shared/tools/types.d.ts +0 -1
- package/shared/layers/Layers.svelte +0 -250
- package/shared/layers/utils.ts +0 -294
- package/shared/tools/Brush.svelte +0 -280
- package/shared/tools/BrushOptions.svelte +0 -180
- package/shared/tools/Crop.svelte +0 -189
- package/shared/tools/Cropper.svelte +0 -346
- package/shared/tools/Handle.svelte +0 -289
- package/shared/tools/Sources.svelte +0 -283
- package/shared/tools/Tools.svelte +0 -162
- package/shared/tools/brush.ts +0 -247
- package/shared/tools/crop.ts +0 -213
- package/shared/tools/index.ts +0 -5
- package/shared/tools/sources.ts +0 -195
- package/shared/tools/types.ts +0 -1
- /package/dist/shared/{tools → brush}/BrushSize.svelte.d.ts +0 -0
- /package/dist/shared/{tools/types.js → types.js} +0 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { Container, Graphics, Sprite } from "pixi.js";
|
|
2
|
+
import {} from "../core/editor";
|
|
3
|
+
import {} from "./types";
|
|
4
|
+
import tinycolor from "tinycolor2";
|
|
5
|
+
import { clear_timeout } from "./brush-utils";
|
|
6
|
+
/**
|
|
7
|
+
* Class to handle all cursor preview-related functionality for the brush tool.
|
|
8
|
+
*/
|
|
9
|
+
export class BrushCursor {
|
|
10
|
+
image_editor_context;
|
|
11
|
+
state;
|
|
12
|
+
scale;
|
|
13
|
+
// Cursor-related properties
|
|
14
|
+
cursor_graphics = null;
|
|
15
|
+
cursor_container = null;
|
|
16
|
+
brush_preview_container = null;
|
|
17
|
+
brush_preview_graphics = null;
|
|
18
|
+
is_preview_visible = false;
|
|
19
|
+
is_cursor_over_image = false;
|
|
20
|
+
cursor_position_check_timeout = null;
|
|
21
|
+
is_brush_or_erase_active = false;
|
|
22
|
+
// Event handlers
|
|
23
|
+
_bound_update_cursor = null;
|
|
24
|
+
_bound_check_cursor_over_image = null;
|
|
25
|
+
constructor(image_editor_context, state, scale) {
|
|
26
|
+
this.image_editor_context = image_editor_context;
|
|
27
|
+
this.state = state;
|
|
28
|
+
this.scale = scale;
|
|
29
|
+
this.initialize_cursor();
|
|
30
|
+
this.initialize_brush_preview();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Returns whether the cursor is currently over the image.
|
|
34
|
+
*/
|
|
35
|
+
is_over_image() {
|
|
36
|
+
return this.is_cursor_over_image;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Sets up cursor-related event listeners.
|
|
40
|
+
*/
|
|
41
|
+
setup_event_listeners() {
|
|
42
|
+
// Clean up any existing listeners
|
|
43
|
+
this.cleanup_event_listeners();
|
|
44
|
+
// Create bound event handlers
|
|
45
|
+
this._bound_update_cursor = this.update_cursor_position.bind(this);
|
|
46
|
+
this._bound_check_cursor_over_image =
|
|
47
|
+
this.check_cursor_over_image.bind(this);
|
|
48
|
+
// Add event listeners using Pixi event system
|
|
49
|
+
// Use app.stage for global events like pointermove
|
|
50
|
+
const stage = this.image_editor_context.app.stage;
|
|
51
|
+
stage.on("pointermove", this._bound_update_cursor);
|
|
52
|
+
stage.on("pointermove", this._bound_check_cursor_over_image);
|
|
53
|
+
// Add event listeners to the image container for enter/leave events
|
|
54
|
+
this.image_editor_context.image_container.on("pointerenter", this.on_image_container_pointer_enter.bind(this));
|
|
55
|
+
this.image_editor_context.image_container.on("pointerleave", this.on_image_container_pointer_leave.bind(this));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Removes all cursor-related event listeners.
|
|
59
|
+
*/
|
|
60
|
+
cleanup_event_listeners() {
|
|
61
|
+
// Use Pixi event system for removal
|
|
62
|
+
const stage = this.image_editor_context.app.stage;
|
|
63
|
+
// Remove event listeners if they exist
|
|
64
|
+
if (this._bound_update_cursor) {
|
|
65
|
+
stage.off("pointermove", this._bound_update_cursor);
|
|
66
|
+
this._bound_update_cursor = null;
|
|
67
|
+
}
|
|
68
|
+
if (this._bound_check_cursor_over_image) {
|
|
69
|
+
stage.off("pointermove", this._bound_check_cursor_over_image);
|
|
70
|
+
this._bound_check_cursor_over_image = null;
|
|
71
|
+
}
|
|
72
|
+
// Remove image container event listeners
|
|
73
|
+
this.image_editor_context.image_container.off("pointerenter");
|
|
74
|
+
this.image_editor_context.image_container.off("pointerleave");
|
|
75
|
+
// Clear timeout
|
|
76
|
+
this.cursor_position_check_timeout = clear_timeout(this.cursor_position_check_timeout);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* initializes the cursor for the brush tool.
|
|
80
|
+
*/
|
|
81
|
+
initialize_cursor() {
|
|
82
|
+
// clean up existing cursor if it exists
|
|
83
|
+
if (this.cursor_container) {
|
|
84
|
+
if (this.cursor_container.parent) {
|
|
85
|
+
this.cursor_container.parent.removeChild(this.cursor_container);
|
|
86
|
+
}
|
|
87
|
+
this.cursor_container.destroy({ children: true });
|
|
88
|
+
this.cursor_container = null;
|
|
89
|
+
}
|
|
90
|
+
// create new cursor container and add to ui container
|
|
91
|
+
this.cursor_container = new Container();
|
|
92
|
+
this.image_editor_context.ui_container.addChild(this.cursor_container);
|
|
93
|
+
// create cursor graphics
|
|
94
|
+
this.cursor_graphics = new Graphics();
|
|
95
|
+
this.cursor_container.addChild(this.cursor_graphics);
|
|
96
|
+
// draw initial cursor
|
|
97
|
+
this.update_cursor_appearance();
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* updates the appearance of the cursor.
|
|
101
|
+
*/
|
|
102
|
+
update_cursor_appearance() {
|
|
103
|
+
if (!this.cursor_graphics)
|
|
104
|
+
return;
|
|
105
|
+
// clear previous graphics
|
|
106
|
+
this.cursor_graphics.clear();
|
|
107
|
+
// set color based on mode
|
|
108
|
+
const cursor_color = this.state.mode === "draw"
|
|
109
|
+
? tinycolor(this.state.color).toString()
|
|
110
|
+
: 0xffffff;
|
|
111
|
+
// draw circle with current brush size
|
|
112
|
+
this.cursor_graphics
|
|
113
|
+
.circle(0, 0, this.state.brush_size * this.scale)
|
|
114
|
+
.stroke({
|
|
115
|
+
width: 1.5,
|
|
116
|
+
color: cursor_color,
|
|
117
|
+
alpha: 0.8
|
|
118
|
+
});
|
|
119
|
+
// add a small dot in the center for precision
|
|
120
|
+
this.cursor_graphics.circle(0, 0, 1).fill({
|
|
121
|
+
color: cursor_color,
|
|
122
|
+
alpha: 0.8
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* updates the position of the cursor.
|
|
127
|
+
* @param {FederatedPointerEvent} event - The pointer event.
|
|
128
|
+
*/
|
|
129
|
+
update_cursor_position(event) {
|
|
130
|
+
if (!this.cursor_container)
|
|
131
|
+
return;
|
|
132
|
+
// get position in image coordinates
|
|
133
|
+
const local_pos = this.image_editor_context.image_container.toLocal(event.global);
|
|
134
|
+
// convert to ui coordinates
|
|
135
|
+
const ui_pos = this.image_editor_context.ui_container.toLocal(this.image_editor_context.image_container.toGlobal(local_pos));
|
|
136
|
+
// update cursor position
|
|
137
|
+
this.cursor_container.position.set(ui_pos.x, ui_pos.y);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* checks if the cursor is over the image container.
|
|
141
|
+
* @param {FederatedPointerEvent} event - The pointer event.
|
|
142
|
+
*/
|
|
143
|
+
check_cursor_over_image(event) {
|
|
144
|
+
// cancel any pending timeout
|
|
145
|
+
if (this.cursor_position_check_timeout !== null) {
|
|
146
|
+
window.clearTimeout(this.cursor_position_check_timeout);
|
|
147
|
+
this.cursor_position_check_timeout = null;
|
|
148
|
+
}
|
|
149
|
+
// get the image container bounds in global coordinates
|
|
150
|
+
const image_container = this.image_editor_context.image_container;
|
|
151
|
+
const bounds = image_container.getBounds();
|
|
152
|
+
// check if cursor is over image
|
|
153
|
+
const was_over_image = this.is_cursor_over_image;
|
|
154
|
+
this.is_cursor_over_image =
|
|
155
|
+
event.global.x >= bounds.x &&
|
|
156
|
+
event.global.x <= bounds.x + bounds.width &&
|
|
157
|
+
event.global.y >= bounds.y &&
|
|
158
|
+
event.global.y <= bounds.y + bounds.height;
|
|
159
|
+
// update visibility if state changed
|
|
160
|
+
if (was_over_image !== this.is_cursor_over_image) {
|
|
161
|
+
this.update_cursor_and_preview_visibility();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* updates the size of the cursor.
|
|
166
|
+
*/
|
|
167
|
+
update_cursor_size() {
|
|
168
|
+
this.update_cursor_appearance();
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Updates whether brush or erase tool is active
|
|
172
|
+
*/
|
|
173
|
+
set_active(is_active) {
|
|
174
|
+
this.is_brush_or_erase_active = is_active;
|
|
175
|
+
this.update_cursor_and_preview_visibility();
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* updates the visibility of the cursor.
|
|
179
|
+
*/
|
|
180
|
+
update_cursor_visibility() {
|
|
181
|
+
if (this.cursor_container) {
|
|
182
|
+
this.cursor_container.visible =
|
|
183
|
+
this.is_cursor_over_image && this.is_brush_or_erase_active;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Shows or hides the brush preview.
|
|
188
|
+
* @param {boolean} show - Whether to show the preview.
|
|
189
|
+
*/
|
|
190
|
+
preview_brush(show) {
|
|
191
|
+
this.is_preview_visible = show;
|
|
192
|
+
if (this.brush_preview_container) {
|
|
193
|
+
this.brush_preview_container.visible =
|
|
194
|
+
show && this.is_brush_or_erase_active;
|
|
195
|
+
}
|
|
196
|
+
if (show) {
|
|
197
|
+
// update preview appearance and position
|
|
198
|
+
this.update_brush_preview();
|
|
199
|
+
this.update_brush_preview_position();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* initializes the brush preview.
|
|
204
|
+
*/
|
|
205
|
+
initialize_brush_preview() {
|
|
206
|
+
// clean up existing preview if it exists
|
|
207
|
+
if (this.brush_preview_container) {
|
|
208
|
+
if (this.brush_preview_container.parent) {
|
|
209
|
+
this.brush_preview_container.parent.removeChild(this.brush_preview_container);
|
|
210
|
+
}
|
|
211
|
+
this.brush_preview_container.destroy({ children: true });
|
|
212
|
+
this.brush_preview_container = null;
|
|
213
|
+
}
|
|
214
|
+
// create new preview container and add to ui container
|
|
215
|
+
this.brush_preview_container = new Container();
|
|
216
|
+
this.image_editor_context.ui_container.addChild(this.brush_preview_container);
|
|
217
|
+
// create preview graphics
|
|
218
|
+
this.brush_preview_graphics = new Graphics();
|
|
219
|
+
this.brush_preview_container.addChild(this.brush_preview_graphics);
|
|
220
|
+
// set initial visibility
|
|
221
|
+
this.brush_preview_container.visible = false;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* updates the brush preview appearance.
|
|
225
|
+
*/
|
|
226
|
+
update_brush_preview() {
|
|
227
|
+
if (!this.brush_preview_graphics)
|
|
228
|
+
return;
|
|
229
|
+
// clear previous graphics
|
|
230
|
+
this.brush_preview_graphics.clear();
|
|
231
|
+
// draw brush preview based on current settings
|
|
232
|
+
const preview_size = this.state.brush_size * this.scale;
|
|
233
|
+
const preview_color = this.state.mode === "draw"
|
|
234
|
+
? tinycolor(this.state.color).setAlpha(this.state.opacity).toString()
|
|
235
|
+
: 0xffffff;
|
|
236
|
+
// draw circle with current brush settings
|
|
237
|
+
this.brush_preview_graphics.circle(0, 0, preview_size).fill({
|
|
238
|
+
color: preview_color,
|
|
239
|
+
alpha: this.state.mode === "draw" ? this.state.opacity : 0.3
|
|
240
|
+
});
|
|
241
|
+
// add outline
|
|
242
|
+
this.brush_preview_graphics.circle(0, 0, preview_size + 1).stroke({
|
|
243
|
+
width: 1,
|
|
244
|
+
color: 0x000000,
|
|
245
|
+
alpha: 0.5
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* updates the position of the brush preview to center of canvas.
|
|
250
|
+
*/
|
|
251
|
+
update_brush_preview_position() {
|
|
252
|
+
if (!this.brush_preview_container)
|
|
253
|
+
return;
|
|
254
|
+
// get the center of the image in global coordinates
|
|
255
|
+
const image_container = this.image_editor_context.image_container;
|
|
256
|
+
const center_x = image_container.width / 2;
|
|
257
|
+
const center_y = image_container.height / 2;
|
|
258
|
+
const global_pos = image_container.toGlobal({ x: center_x, y: center_y });
|
|
259
|
+
// convert to ui coordinates
|
|
260
|
+
const ui_pos = this.image_editor_context.ui_container.toLocal(global_pos);
|
|
261
|
+
// update preview position
|
|
262
|
+
this.brush_preview_container.position.set(ui_pos.x, ui_pos.y);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Called when the pointer enters the image container.
|
|
266
|
+
*/
|
|
267
|
+
on_image_container_pointer_enter() {
|
|
268
|
+
this.is_cursor_over_image = true;
|
|
269
|
+
this.update_cursor_and_preview_visibility();
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Called when the pointer leaves the image container.
|
|
273
|
+
*/
|
|
274
|
+
on_image_container_pointer_leave() {
|
|
275
|
+
this.is_cursor_over_image = false;
|
|
276
|
+
this.update_cursor_and_preview_visibility();
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Updates both cursor and preview visibility based on cursor position.
|
|
280
|
+
*/
|
|
281
|
+
update_cursor_and_preview_visibility() {
|
|
282
|
+
this.update_cursor_visibility();
|
|
283
|
+
if (this.brush_preview_container) {
|
|
284
|
+
this.brush_preview_container.visible =
|
|
285
|
+
this.is_preview_visible && this.is_brush_or_erase_active;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Cleans up all cursor resources.
|
|
290
|
+
*/
|
|
291
|
+
cleanup() {
|
|
292
|
+
// Reset active state
|
|
293
|
+
this.is_brush_or_erase_active = false;
|
|
294
|
+
// clean up cursor
|
|
295
|
+
if (this.cursor_container) {
|
|
296
|
+
if (this.cursor_container.parent) {
|
|
297
|
+
this.cursor_container.parent.removeChild(this.cursor_container);
|
|
298
|
+
}
|
|
299
|
+
this.cursor_container.destroy({ children: true });
|
|
300
|
+
this.cursor_container = null;
|
|
301
|
+
}
|
|
302
|
+
// clean up preview
|
|
303
|
+
if (this.brush_preview_container) {
|
|
304
|
+
if (this.brush_preview_container.parent) {
|
|
305
|
+
this.brush_preview_container.parent.removeChild(this.brush_preview_container);
|
|
306
|
+
}
|
|
307
|
+
this.brush_preview_container.destroy({ children: true });
|
|
308
|
+
this.brush_preview_container = null;
|
|
309
|
+
}
|
|
310
|
+
// clear timeout
|
|
311
|
+
if (this.cursor_position_check_timeout !== null) {
|
|
312
|
+
window.clearTimeout(this.cursor_position_check_timeout);
|
|
313
|
+
this.cursor_position_check_timeout = null;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Updates the brush state.
|
|
318
|
+
*/
|
|
319
|
+
update_state(state, scale) {
|
|
320
|
+
this.state = state;
|
|
321
|
+
this.scale = scale;
|
|
322
|
+
this.update_cursor_appearance();
|
|
323
|
+
if (this.is_preview_visible) {
|
|
324
|
+
this.update_brush_preview();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Application } from "pixi.js";
|
|
2
|
+
import { type ImageEditorContext } from "../core/editor";
|
|
3
|
+
/**
|
|
4
|
+
* Class to handle texture operations for the brush tool.
|
|
5
|
+
* Simplified to work directly with layer textures.
|
|
6
|
+
*/
|
|
7
|
+
export declare class BrushTextures {
|
|
8
|
+
private image_editor_context;
|
|
9
|
+
private app;
|
|
10
|
+
private stroke_texture;
|
|
11
|
+
private erase_texture;
|
|
12
|
+
private display_container;
|
|
13
|
+
private stroke_container;
|
|
14
|
+
private stroke_graphics;
|
|
15
|
+
private preview_sprite;
|
|
16
|
+
private erase_graphics;
|
|
17
|
+
private dimensions;
|
|
18
|
+
private is_new_stroke;
|
|
19
|
+
private scale;
|
|
20
|
+
private current_opacity;
|
|
21
|
+
private current_mode;
|
|
22
|
+
private last_from_x;
|
|
23
|
+
private last_from_y;
|
|
24
|
+
private last_to_x;
|
|
25
|
+
private last_to_y;
|
|
26
|
+
private last_size;
|
|
27
|
+
constructor(image_editor_context: ImageEditorContext, app: Application);
|
|
28
|
+
/**
|
|
29
|
+
* Initializes textures needed for the brush tool.
|
|
30
|
+
*/
|
|
31
|
+
initialize_textures(): void;
|
|
32
|
+
/**
|
|
33
|
+
* Reinitializes textures when needed (e.g., after resizing).
|
|
34
|
+
*/
|
|
35
|
+
reinitialize(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Cleans up texture resources.
|
|
38
|
+
*/
|
|
39
|
+
cleanup_textures(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Preserve the canvas state when starting a new stroke.
|
|
42
|
+
*/
|
|
43
|
+
preserve_canvas_state(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Resets the eraser mask.
|
|
46
|
+
*/
|
|
47
|
+
reset_eraser_mask(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Commits the current stroke to the active layer.
|
|
50
|
+
*/
|
|
51
|
+
commit_stroke(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Calculates the distance between two points.
|
|
54
|
+
*/
|
|
55
|
+
private calculateDistance;
|
|
56
|
+
/**
|
|
57
|
+
* Draws a segment for the current stroke using a simple "stamp" approach.
|
|
58
|
+
*/
|
|
59
|
+
draw_segment(from_x: number, from_y: number, to_x: number, to_y: number, size: number, color: string, opacity: number, mode: "draw" | "erase"): void;
|
|
60
|
+
/**
|
|
61
|
+
* Gets current dimensions of the texture.
|
|
62
|
+
*/
|
|
63
|
+
get_dimensions(): {
|
|
64
|
+
width: number;
|
|
65
|
+
height: number;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Cleanup all resources.
|
|
69
|
+
*/
|
|
70
|
+
cleanup(): void;
|
|
71
|
+
}
|