@gradio/imageeditor 0.13.0 → 0.14.1
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 +33 -0
- package/ImageEditor.stories.svelte +9 -1
- package/Index.svelte +13 -1
- package/InteractiveImageEditor.svelte +10 -1
- package/README.md +2 -0
- package/dist/Index.svelte +6 -0
- package/dist/Index.svelte.d.ts +9 -1
- package/dist/InteractiveImageEditor.svelte +7 -0
- package/dist/InteractiveImageEditor.svelte.d.ts +5 -1
- package/dist/shared/Controls.svelte +13 -1
- package/dist/shared/Controls.svelte.d.ts +2 -0
- package/dist/shared/ImageEditor.svelte +29 -3
- package/dist/shared/ImageEditor.svelte.d.ts +5 -2
- package/dist/shared/Layers.svelte +29 -2
- package/dist/shared/Layers.svelte.d.ts +2 -0
- package/dist/shared/SecondaryToolbar.svelte +1 -0
- package/dist/shared/SecondaryToolbar.svelte.d.ts +2 -0
- package/dist/shared/brush/brush-textures.d.ts +0 -6
- package/dist/shared/brush/brush-textures.js +0 -19
- package/dist/shared/brush/brush.js +3 -2
- package/dist/shared/core/editor.d.ts +15 -6
- package/dist/shared/core/editor.js +76 -33
- package/dist/shared/image/image.js +2 -4
- package/dist/shared/types.d.ts +4 -0
- package/dist/shared/zoom/zoom.js +1 -1
- package/package.json +9 -9
- package/shared/Controls.svelte +14 -40
- package/shared/ImageEditor.svelte +33 -4
- package/shared/Layers.svelte +36 -3
- package/shared/SecondaryToolbar.svelte +7 -1
- package/shared/brush/brush-textures.ts +0 -23
- package/shared/brush/brush.ts +6 -2
- package/shared/core/editor.ts +102 -44
- package/shared/image/image.ts +2 -4
- package/shared/types.ts +5 -0
- package/shared/zoom/zoom.ts +1 -1
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
export let layers: Writable<{
|
|
6
6
|
active_layer: string;
|
|
7
|
-
layers: {
|
|
7
|
+
layers: {
|
|
8
|
+
name: string;
|
|
9
|
+
id: string;
|
|
10
|
+
user_created: boolean;
|
|
11
|
+
visible: boolean;
|
|
12
|
+
}[];
|
|
8
13
|
}>;
|
|
9
14
|
|
|
10
15
|
export let enable_additional_layers = true;
|
|
@@ -24,6 +29,7 @@
|
|
|
24
29
|
on:change_layer
|
|
25
30
|
on:move_layer
|
|
26
31
|
on:delete_layer
|
|
32
|
+
on:toggle_layer_visibility
|
|
27
33
|
/>
|
|
28
34
|
{/if}
|
|
29
35
|
</div>
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
Graphics,
|
|
6
6
|
Application
|
|
7
7
|
} from "pixi.js";
|
|
8
|
-
import { safe_destroy, safe_remove_child } from "./brush-utils";
|
|
9
8
|
import { type ImageEditorContext } from "../core/editor";
|
|
10
9
|
|
|
11
10
|
/**
|
|
@@ -26,22 +25,12 @@ export class BrushTextures {
|
|
|
26
25
|
// Track if a new stroke is starting
|
|
27
26
|
private is_new_stroke = true;
|
|
28
27
|
|
|
29
|
-
// Current scale factor
|
|
30
|
-
private scale = 1;
|
|
31
|
-
|
|
32
28
|
// Track the current drawing opacity
|
|
33
29
|
private current_opacity = 1.0;
|
|
34
30
|
|
|
35
31
|
// Track current drawing mode
|
|
36
32
|
private current_mode: "draw" | "erase" = "draw";
|
|
37
33
|
|
|
38
|
-
// Store last drawing parameters for eraser recreation
|
|
39
|
-
private last_from_x: number | null = null;
|
|
40
|
-
private last_from_y: number | null = null;
|
|
41
|
-
private last_to_x: number | null = null;
|
|
42
|
-
private last_to_y: number | null = null;
|
|
43
|
-
private last_size: number | null = null;
|
|
44
|
-
|
|
45
34
|
constructor(
|
|
46
35
|
private image_editor_context: ImageEditorContext,
|
|
47
36
|
private app: Application
|
|
@@ -50,11 +39,6 @@ export class BrushTextures {
|
|
|
50
39
|
width: this.image_editor_context.image_container.width,
|
|
51
40
|
height: this.image_editor_context.image_container.height
|
|
52
41
|
};
|
|
53
|
-
|
|
54
|
-
// Subscribe to scale changes
|
|
55
|
-
this.image_editor_context.scale.subscribe((scale) => {
|
|
56
|
-
this.scale = scale;
|
|
57
|
-
});
|
|
58
42
|
}
|
|
59
43
|
|
|
60
44
|
/**
|
|
@@ -336,13 +320,6 @@ export class BrushTextures {
|
|
|
336
320
|
this.current_opacity =
|
|
337
321
|
mode === "draw" ? Math.min(Math.max(opacity, 0), 1) : 0.5;
|
|
338
322
|
|
|
339
|
-
// Store parameters for potential eraser recreation
|
|
340
|
-
this.last_from_x = from_x;
|
|
341
|
-
this.last_from_y = from_y;
|
|
342
|
-
this.last_to_x = to_x;
|
|
343
|
-
this.last_to_y = to_y;
|
|
344
|
-
this.last_size = size;
|
|
345
|
-
|
|
346
323
|
// Apply scale to brush size for consistent rendering
|
|
347
324
|
const scaled_size = size;
|
|
348
325
|
|
package/shared/brush/brush.ts
CHANGED
|
@@ -213,8 +213,12 @@ export class BrushTool implements Tool {
|
|
|
213
213
|
* @private
|
|
214
214
|
*/
|
|
215
215
|
private on_pointer_down(event: FederatedPointerEvent): void {
|
|
216
|
-
|
|
217
|
-
|
|
216
|
+
const current_layer =
|
|
217
|
+
this.image_editor_context.layer_manager.get_active_layer();
|
|
218
|
+
if (
|
|
219
|
+
!current_layer?.visible ||
|
|
220
|
+
(this.current_tool !== "erase" && this.current_tool !== "draw")
|
|
221
|
+
) {
|
|
218
222
|
return;
|
|
219
223
|
}
|
|
220
224
|
|
package/shared/core/editor.ts
CHANGED
|
@@ -79,12 +79,19 @@ export class LayerManager {
|
|
|
79
79
|
id: string;
|
|
80
80
|
container: Container;
|
|
81
81
|
user_created: boolean;
|
|
82
|
+
visible: boolean;
|
|
82
83
|
}[] = [];
|
|
83
84
|
private active_layer: Container | null = null;
|
|
85
|
+
private active_layer_id: string | null = null;
|
|
84
86
|
private draw_textures: Map<Container, RenderTexture> = new Map();
|
|
85
87
|
layer_store: Writable<{
|
|
86
88
|
active_layer: string;
|
|
87
|
-
layers: {
|
|
89
|
+
layers: {
|
|
90
|
+
name: string;
|
|
91
|
+
id: string;
|
|
92
|
+
user_created: boolean;
|
|
93
|
+
visible: boolean;
|
|
94
|
+
}[];
|
|
88
95
|
}> = writable({
|
|
89
96
|
active_layer: "",
|
|
90
97
|
|
|
@@ -113,6 +120,18 @@ export class LayerManager {
|
|
|
113
120
|
this.layer_options = layer_options;
|
|
114
121
|
}
|
|
115
122
|
|
|
123
|
+
toggle_layer_visibility(id: string): void {
|
|
124
|
+
const layer = this.layers.find((l) => l.id === id);
|
|
125
|
+
if (layer) {
|
|
126
|
+
layer.container.visible = !layer.container.visible;
|
|
127
|
+
layer.visible = layer.container.visible;
|
|
128
|
+
this.layer_store.update((state) => ({
|
|
129
|
+
active_layer: state.active_layer,
|
|
130
|
+
layers: this.layers
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
116
135
|
create_background_layer(width: number, height: number): Container {
|
|
117
136
|
if (this.background_layer) {
|
|
118
137
|
this.background_layer.destroy();
|
|
@@ -277,22 +296,27 @@ export class LayerManager {
|
|
|
277
296
|
width,
|
|
278
297
|
height,
|
|
279
298
|
layer_name,
|
|
280
|
-
user_created
|
|
299
|
+
user_created,
|
|
300
|
+
layer_id = undefined,
|
|
301
|
+
make_active = false
|
|
281
302
|
}: {
|
|
282
303
|
width: number;
|
|
283
304
|
height: number;
|
|
284
305
|
layer_name?: string;
|
|
285
306
|
user_created: boolean;
|
|
307
|
+
layer_id?: string;
|
|
308
|
+
make_active?: boolean;
|
|
286
309
|
}): Container {
|
|
287
310
|
const layer = new Container();
|
|
288
|
-
const
|
|
311
|
+
const _layer_id = layer_id || Math.random().toString(36).substring(2, 15);
|
|
289
312
|
const _layer_name = layer_name || `Layer ${this.layers.length + 1}`;
|
|
290
313
|
|
|
291
314
|
this.layers.push({
|
|
292
315
|
name: _layer_name,
|
|
293
|
-
id:
|
|
316
|
+
id: _layer_id,
|
|
294
317
|
container: layer,
|
|
295
|
-
user_created
|
|
318
|
+
user_created,
|
|
319
|
+
visible: true
|
|
296
320
|
});
|
|
297
321
|
|
|
298
322
|
this.image_container.addChild(layer);
|
|
@@ -325,9 +349,12 @@ export class LayerManager {
|
|
|
325
349
|
this.draw_textures.set(layer, draw_texture);
|
|
326
350
|
|
|
327
351
|
this.update_layer_order();
|
|
328
|
-
|
|
352
|
+
if (make_active) {
|
|
353
|
+
this.set_active_layer(_layer_id);
|
|
354
|
+
}
|
|
355
|
+
|
|
329
356
|
this.layer_store.set({
|
|
330
|
-
active_layer:
|
|
357
|
+
active_layer: this.active_layer_id || "",
|
|
331
358
|
layers: this.layers
|
|
332
359
|
});
|
|
333
360
|
return layer;
|
|
@@ -436,6 +463,7 @@ export class LayerManager {
|
|
|
436
463
|
this.layers.find((l) => l.id === id)?.container ||
|
|
437
464
|
this.layers[0]?.container ||
|
|
438
465
|
null;
|
|
466
|
+
this.active_layer_id = id;
|
|
439
467
|
this.layer_store.set({
|
|
440
468
|
active_layer: id,
|
|
441
469
|
layers: this.layers
|
|
@@ -469,8 +497,9 @@ export class LayerManager {
|
|
|
469
497
|
}
|
|
470
498
|
this.layers[index].container.destroy();
|
|
471
499
|
if (this.active_layer === this.layers[index].container) {
|
|
472
|
-
this.
|
|
473
|
-
|
|
500
|
+
const new_active_layer = this.layers[Math.max(0, index - 1)] || null;
|
|
501
|
+
this.active_layer = new_active_layer?.container || null;
|
|
502
|
+
this.active_layer_id = new_active_layer?.id || null;
|
|
474
503
|
}
|
|
475
504
|
this.layers = this.layers.filter((l) => l.id !== id);
|
|
476
505
|
|
|
@@ -849,21 +878,34 @@ export class LayerManager {
|
|
|
849
878
|
|
|
850
879
|
reset_layers(width: number, height: number, persist = false): void {
|
|
851
880
|
const _layers_to_recreate = persist
|
|
852
|
-
? this.layers.map((layer) => layer.name)
|
|
853
|
-
: this.layer_options.layers;
|
|
881
|
+
? this.layers.map((layer) => [layer.name, layer.id])
|
|
882
|
+
: this.layer_options.layers.map((layer) => [layer, undefined]);
|
|
854
883
|
|
|
855
884
|
this.layers.forEach((layer) => {
|
|
856
885
|
this.delete_layer(layer.id);
|
|
857
886
|
});
|
|
858
887
|
|
|
859
|
-
for (const
|
|
888
|
+
for (const [layer_name, layer_id] of _layers_to_recreate) {
|
|
860
889
|
this.create_layer({
|
|
861
890
|
width,
|
|
862
891
|
height,
|
|
863
|
-
layer_name:
|
|
864
|
-
user_created: this.layer_options.layers.
|
|
892
|
+
layer_name: layer_name,
|
|
893
|
+
user_created: this.layer_options.layers.find((l) => l === layer_name)
|
|
894
|
+
? false
|
|
895
|
+
: true,
|
|
896
|
+
layer_id: layer_id
|
|
865
897
|
});
|
|
866
898
|
}
|
|
899
|
+
|
|
900
|
+
if (!persist) {
|
|
901
|
+
this.active_layer = this.layers[0].container;
|
|
902
|
+
this.active_layer_id = this.layers[0].id;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
this.layer_store.update((state) => ({
|
|
906
|
+
active_layer: this.active_layer_id || this.layers[0].id,
|
|
907
|
+
layers: this.layers
|
|
908
|
+
}));
|
|
867
909
|
}
|
|
868
910
|
|
|
869
911
|
init_layers(width: number, height: number): void {
|
|
@@ -880,8 +922,9 @@ export class LayerManager {
|
|
|
880
922
|
}
|
|
881
923
|
|
|
882
924
|
this.active_layer = this.layers[0].container;
|
|
925
|
+
this.active_layer_id = this.layers[0].id;
|
|
883
926
|
this.layer_store.update((_layers) => ({
|
|
884
|
-
active_layer:
|
|
927
|
+
active_layer: this.layers[0].id,
|
|
885
928
|
layers: this.layers
|
|
886
929
|
}));
|
|
887
930
|
}
|
|
@@ -899,6 +942,7 @@ interface ImageEditorOptions {
|
|
|
899
942
|
border_region?: number;
|
|
900
943
|
layer_options?: LayerOptions;
|
|
901
944
|
pad_bottom?: number;
|
|
945
|
+
theme_mode?: "dark" | "light";
|
|
902
946
|
}
|
|
903
947
|
|
|
904
948
|
const core_tool_map = {
|
|
@@ -922,8 +966,8 @@ export interface ImageEditorContext {
|
|
|
922
966
|
scale?: number;
|
|
923
967
|
position?: { x: number; y: number };
|
|
924
968
|
animate?: boolean;
|
|
925
|
-
}) => void
|
|
926
|
-
execute_command: (command: Command) => void;
|
|
969
|
+
}) => Promise<void>;
|
|
970
|
+
execute_command: (command: Command) => Promise<void> | void;
|
|
927
971
|
resize_canvas: (width: number, height: number) => void;
|
|
928
972
|
reset: () => void;
|
|
929
973
|
set_background_image: (image: Sprite) => void;
|
|
@@ -1034,7 +1078,12 @@ export class ImageEditor {
|
|
|
1034
1078
|
};
|
|
1035
1079
|
layers: Writable<{
|
|
1036
1080
|
active_layer: string;
|
|
1037
|
-
layers: {
|
|
1081
|
+
layers: {
|
|
1082
|
+
name: string;
|
|
1083
|
+
id: string;
|
|
1084
|
+
user_created: boolean;
|
|
1085
|
+
visible: boolean;
|
|
1086
|
+
}[];
|
|
1038
1087
|
}> = writable({
|
|
1039
1088
|
active_layer: "",
|
|
1040
1089
|
layers: []
|
|
@@ -1051,14 +1100,15 @@ export class ImageEditor {
|
|
|
1051
1100
|
private overlay_container!: Container;
|
|
1052
1101
|
private overlay_graphics!: Graphics;
|
|
1053
1102
|
private pad_bottom: number;
|
|
1103
|
+
private theme_mode: "dark" | "light";
|
|
1054
1104
|
constructor(options: ImageEditorOptions) {
|
|
1055
1105
|
this.pad_bottom = options.pad_bottom || 0;
|
|
1056
1106
|
this.dark = options.dark || false;
|
|
1107
|
+
this.theme_mode = options.theme_mode || "dark";
|
|
1057
1108
|
this.target_element = options.target_element;
|
|
1058
1109
|
this.width = options.width;
|
|
1059
1110
|
this.height = options.height;
|
|
1060
1111
|
this.command_manager = new CommandManager();
|
|
1061
|
-
// this.layers = writable([]);
|
|
1062
1112
|
this.ready = new Promise((resolve) => {
|
|
1063
1113
|
this.ready_resolve = resolve;
|
|
1064
1114
|
});
|
|
@@ -1142,7 +1192,7 @@ export class ImageEditor {
|
|
|
1142
1192
|
width: container_box.width,
|
|
1143
1193
|
height: container_box.height,
|
|
1144
1194
|
backgroundAlpha: this.dark ? 0 : 1,
|
|
1145
|
-
backgroundColor: this.dark ?
|
|
1195
|
+
backgroundColor: this.theme_mode === "dark" ? "#27272a" : "#ffffff",
|
|
1146
1196
|
resolution: window.devicePixelRatio,
|
|
1147
1197
|
autoDensity: true,
|
|
1148
1198
|
antialias: true,
|
|
@@ -1385,12 +1435,6 @@ export class ImageEditor {
|
|
|
1385
1435
|
this.layers = this.layer_manager.layer_store;
|
|
1386
1436
|
}
|
|
1387
1437
|
|
|
1388
|
-
// private resize_image(width: number, height: number): void {
|
|
1389
|
-
// // Implement image resizing logic here
|
|
1390
|
-
// this.image_container.width = width;
|
|
1391
|
-
// this.image_container.height = height;
|
|
1392
|
-
// }
|
|
1393
|
-
|
|
1394
1438
|
resize_canvas(width: number, height: number): void {
|
|
1395
1439
|
if (this.app.renderer) {
|
|
1396
1440
|
this.app.renderer.resize(width, height);
|
|
@@ -1417,33 +1461,42 @@ export class ImageEditor {
|
|
|
1417
1461
|
}
|
|
1418
1462
|
}
|
|
1419
1463
|
|
|
1420
|
-
set_image_properties(properties: {
|
|
1464
|
+
async set_image_properties(properties: {
|
|
1421
1465
|
width?: number;
|
|
1422
1466
|
height?: number;
|
|
1423
1467
|
scale?: number;
|
|
1424
1468
|
position?: { x: number; y: number };
|
|
1425
1469
|
animate?: boolean;
|
|
1426
|
-
}): void {
|
|
1470
|
+
}): Promise<void> {
|
|
1427
1471
|
let hard =
|
|
1428
1472
|
typeof properties.animate !== "undefined" ? !properties.animate : true;
|
|
1429
1473
|
if (properties.position) {
|
|
1430
|
-
this.position.set(properties.position, { hard });
|
|
1474
|
+
const pos = this.position.set(properties.position, { hard });
|
|
1475
|
+
if (hard) {
|
|
1476
|
+
await pos;
|
|
1477
|
+
}
|
|
1431
1478
|
}
|
|
1432
1479
|
if (properties.scale) {
|
|
1433
|
-
this.scale.set(properties.scale, { hard });
|
|
1480
|
+
const scale = this.scale.set(properties.scale, { hard });
|
|
1481
|
+
if (hard) {
|
|
1482
|
+
await scale;
|
|
1483
|
+
}
|
|
1434
1484
|
}
|
|
1435
1485
|
if (properties.width && properties.height) {
|
|
1436
1486
|
this.width = properties.width;
|
|
1437
1487
|
this.height = properties.height;
|
|
1438
|
-
this.dimensions.set(
|
|
1488
|
+
const dimensions = this.dimensions.set(
|
|
1439
1489
|
{ width: properties.width, height: properties.height },
|
|
1440
1490
|
{ hard }
|
|
1441
1491
|
);
|
|
1492
|
+
if (hard) {
|
|
1493
|
+
await dimensions;
|
|
1494
|
+
}
|
|
1442
1495
|
}
|
|
1443
1496
|
}
|
|
1444
1497
|
|
|
1445
|
-
execute_command(command: Command): void {
|
|
1446
|
-
this.command_manager.execute(command);
|
|
1498
|
+
async execute_command(command: Command): Promise<void> {
|
|
1499
|
+
await this.command_manager.execute(command);
|
|
1447
1500
|
}
|
|
1448
1501
|
|
|
1449
1502
|
undo(): void {
|
|
@@ -1463,15 +1516,12 @@ export class ImageEditor {
|
|
|
1463
1516
|
image: Blob | File;
|
|
1464
1517
|
resize?: boolean;
|
|
1465
1518
|
}): Promise<void> {
|
|
1466
|
-
const
|
|
1467
|
-
|
|
1519
|
+
const image_tool = this.tools.get("image") as ImageTool;
|
|
1520
|
+
await image_tool.add_image({
|
|
1468
1521
|
image,
|
|
1469
|
-
this.fixed_canvas,
|
|
1470
|
-
this.border_region
|
|
1471
|
-
);
|
|
1472
|
-
|
|
1473
|
-
await image_command.start();
|
|
1474
|
-
this.context.execute_command(image_command);
|
|
1522
|
+
fixed_canvas: this.fixed_canvas,
|
|
1523
|
+
border_region: this.border_region
|
|
1524
|
+
});
|
|
1475
1525
|
}
|
|
1476
1526
|
|
|
1477
1527
|
/**
|
|
@@ -1517,14 +1567,14 @@ export class ImageEditor {
|
|
|
1517
1567
|
this.background_image = image;
|
|
1518
1568
|
}
|
|
1519
1569
|
|
|
1520
|
-
reset_canvas(): void {
|
|
1570
|
+
async reset_canvas(): Promise<void> {
|
|
1521
1571
|
this.layer_manager.reset_layers(this.width, this.height);
|
|
1522
1572
|
// Clear background image
|
|
1523
1573
|
this.background_image = undefined;
|
|
1524
1574
|
this.background_image_present.set(false);
|
|
1525
1575
|
|
|
1526
1576
|
// Reset position, scale and dimensions to default values
|
|
1527
|
-
this.set_image_properties({
|
|
1577
|
+
await this.set_image_properties({
|
|
1528
1578
|
width: this.width,
|
|
1529
1579
|
height: this.height,
|
|
1530
1580
|
scale: 1,
|
|
@@ -1559,7 +1609,9 @@ export class ImageEditor {
|
|
|
1559
1609
|
width: this.width,
|
|
1560
1610
|
height: this.height,
|
|
1561
1611
|
layer_name: undefined,
|
|
1562
|
-
user_created: true
|
|
1612
|
+
user_created: true,
|
|
1613
|
+
layer_id: undefined,
|
|
1614
|
+
make_active: true
|
|
1563
1615
|
});
|
|
1564
1616
|
this.notify("change");
|
|
1565
1617
|
}
|
|
@@ -1586,6 +1638,8 @@ export class ImageEditor {
|
|
|
1586
1638
|
await this.layer_manager.add_layer_from_url(url);
|
|
1587
1639
|
}
|
|
1588
1640
|
|
|
1641
|
+
this.layer_manager.set_active_layer(_layers[0].id);
|
|
1642
|
+
|
|
1589
1643
|
// Update resize tool if present with border region
|
|
1590
1644
|
const resize_tool = this.tools.get("resize") as any;
|
|
1591
1645
|
if (resize_tool && typeof resize_tool.set_border_region === "function") {
|
|
@@ -1727,4 +1781,8 @@ export class ImageEditor {
|
|
|
1727
1781
|
this.height
|
|
1728
1782
|
);
|
|
1729
1783
|
}
|
|
1784
|
+
|
|
1785
|
+
toggle_layer_visibility(id: string): void {
|
|
1786
|
+
this.layer_manager.toggle_layer_visibility(id);
|
|
1787
|
+
}
|
|
1730
1788
|
}
|
package/shared/image/image.ts
CHANGED
|
@@ -52,8 +52,7 @@ export class ImageTool implements Tool {
|
|
|
52
52
|
border_region
|
|
53
53
|
);
|
|
54
54
|
|
|
55
|
-
await
|
|
56
|
-
this.context.execute_command(image_command);
|
|
55
|
+
await this.context.execute_command(image_command);
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
set_tool(tool: ToolbarTool, subtool: Subtool): void {
|
|
@@ -162,7 +161,7 @@ export class AddImageCommand implements BgImageCommand {
|
|
|
162
161
|
const [width, height] = await this.start();
|
|
163
162
|
|
|
164
163
|
// Update image properties with the original dimensions and center in viewport
|
|
165
|
-
this.context.set_image_properties({
|
|
164
|
+
await this.context.set_image_properties({
|
|
166
165
|
scale: 1, // Start at 1:1 scale
|
|
167
166
|
position: {
|
|
168
167
|
x: this.context.app.screen.width / 2,
|
|
@@ -196,7 +195,6 @@ export class AddImageCommand implements BgImageCommand {
|
|
|
196
195
|
if (this.sprite) {
|
|
197
196
|
this.sprite.destroy();
|
|
198
197
|
}
|
|
199
|
-
// The background layer will be automatically cleaned up when a new image is added
|
|
200
198
|
}
|
|
201
199
|
}
|
|
202
200
|
|
package/shared/types.ts
CHANGED
package/shared/zoom/zoom.ts
CHANGED
|
@@ -142,7 +142,7 @@ export class ZoomTool implements Tool {
|
|
|
142
142
|
this.setup_event_listeners();
|
|
143
143
|
|
|
144
144
|
// Update context with initial values
|
|
145
|
-
this.image_editor_context.set_image_properties({
|
|
145
|
+
await this.image_editor_context.set_image_properties({
|
|
146
146
|
scale: min_zoom,
|
|
147
147
|
position: { x: initial_x, y: initial_y }
|
|
148
148
|
});
|