@gradio/imageeditor 0.12.14 → 0.14.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.
Files changed (131) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/Example.svelte +1 -1
  3. package/IMAGE_EDITOR_OVERVIEW.md +224 -0
  4. package/ImageEditor.stories.svelte +13 -5
  5. package/Index.svelte +46 -45
  6. package/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +65 -103
  7. package/README.md +2 -0
  8. package/dist/Example.svelte.d.ts +1 -1
  9. package/dist/Index.svelte +35 -33
  10. package/dist/Index.svelte.d.ts +25 -16
  11. package/dist/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +54 -88
  12. package/dist/{shared/InteractiveImageEditor.svelte.d.ts → InteractiveImageEditor.svelte.d.ts} +17 -15
  13. package/dist/shared/Anchor.svelte +311 -0
  14. package/dist/shared/Anchor.svelte.d.ts +18 -0
  15. package/dist/shared/Controls.svelte +169 -18
  16. package/dist/shared/Controls.svelte.d.ts +9 -2
  17. package/dist/shared/{tools/IconButton.svelte → IconButton.svelte} +19 -3
  18. package/dist/shared/{tools/IconButton.svelte.d.ts → IconButton.svelte.d.ts} +4 -1
  19. package/dist/shared/ImageEditor.svelte +572 -289
  20. package/dist/shared/ImageEditor.svelte.d.ts +54 -56
  21. package/dist/shared/Layers.svelte +260 -0
  22. package/dist/shared/Layers.svelte.d.ts +37 -0
  23. package/dist/shared/Resize.svelte +218 -0
  24. package/dist/shared/Resize.svelte.d.ts +29 -0
  25. package/dist/shared/SecondaryToolbar.svelte +55 -0
  26. package/dist/shared/SecondaryToolbar.svelte.d.ts +37 -0
  27. package/dist/shared/Toolbar.svelte +337 -0
  28. package/dist/shared/Toolbar.svelte.d.ts +42 -0
  29. package/dist/shared/{tools → brush}/BrushOptions.svelte +68 -64
  30. package/dist/shared/{tools → brush}/BrushOptions.svelte.d.ts +9 -9
  31. package/dist/shared/{tools → brush}/BrushSize.svelte +2 -27
  32. package/dist/shared/{tools → brush}/ColorField.svelte +2 -1
  33. package/dist/shared/{tools → brush}/ColorField.svelte.d.ts +1 -0
  34. package/dist/shared/{tools → brush}/ColorPicker.svelte +81 -9
  35. package/dist/shared/{tools → brush}/ColorPicker.svelte.d.ts +1 -0
  36. package/dist/shared/{tools → brush}/ColorSwatch.svelte +78 -38
  37. package/dist/shared/{tools → brush}/ColorSwatch.svelte.d.ts +6 -2
  38. package/dist/shared/brush/brush-cursor.d.ts +101 -0
  39. package/dist/shared/brush/brush-cursor.js +327 -0
  40. package/dist/shared/brush/brush-textures.d.ts +65 -0
  41. package/dist/shared/brush/brush-textures.js +385 -0
  42. package/dist/shared/brush/brush-utils.d.ts +32 -0
  43. package/dist/shared/brush/brush-utils.js +59 -0
  44. package/dist/shared/brush/brush.d.ts +152 -0
  45. package/dist/shared/brush/brush.js +397 -0
  46. package/dist/shared/brush/types.d.ts +37 -0
  47. package/dist/shared/brush/types.js +1 -0
  48. package/dist/shared/core/editor.d.ts +261 -0
  49. package/dist/shared/core/editor.js +1264 -0
  50. package/dist/shared/crop/crop.d.ts +201 -0
  51. package/dist/shared/crop/crop.js +727 -0
  52. package/dist/shared/image/image.d.ts +89 -0
  53. package/dist/shared/image/image.js +183 -0
  54. package/dist/shared/resize/resize.d.ts +270 -0
  55. package/dist/shared/resize/resize.js +1413 -0
  56. package/dist/shared/types.d.ts +16 -0
  57. package/dist/shared/utils/pixi.d.ts +16 -57
  58. package/dist/shared/utils/pixi.js +15 -113
  59. package/dist/shared/zoom/zoom.d.ts +136 -0
  60. package/dist/shared/zoom/zoom.js +548 -0
  61. package/package.json +8 -7
  62. package/shared/Anchor.svelte +384 -0
  63. package/shared/Controls.svelte +178 -37
  64. package/shared/{tools/IconButton.svelte → IconButton.svelte} +21 -4
  65. package/shared/ImageEditor.svelte +712 -350
  66. package/shared/Layers.svelte +282 -0
  67. package/shared/Resize.svelte +239 -0
  68. package/shared/SecondaryToolbar.svelte +67 -0
  69. package/shared/Toolbar.svelte +386 -0
  70. package/shared/brush/BRUSH_TOOL.md +134 -0
  71. package/shared/brush/BrushOptions.svelte +200 -0
  72. package/shared/{tools → brush}/BrushSize.svelte +2 -30
  73. package/shared/{tools → brush}/ColorField.svelte +3 -1
  74. package/shared/{tools → brush}/ColorPicker.svelte +86 -9
  75. package/shared/{tools → brush}/ColorSwatch.svelte +95 -42
  76. package/shared/brush/brush-cursor.ts +408 -0
  77. package/shared/brush/brush-textures.ts +485 -0
  78. package/shared/brush/brush-utils.ts +76 -0
  79. package/shared/brush/brush.ts +510 -0
  80. package/shared/brush/types.ts +41 -0
  81. package/shared/core/EDITOR.md +182 -0
  82. package/shared/core/editor.ts +1788 -0
  83. package/shared/crop/CROP.md +139 -0
  84. package/shared/crop/crop.ts +1027 -0
  85. package/shared/image/IMAGE.md +135 -0
  86. package/shared/image/image.ts +298 -0
  87. package/shared/resize/resize.ts +1894 -0
  88. package/shared/types.ts +19 -0
  89. package/shared/utils/pixi.ts +19 -246
  90. package/shared/zoom/zoom.ts +729 -0
  91. package/dist/shared/layers/Layers.svelte +0 -231
  92. package/dist/shared/layers/Layers.svelte.d.ts +0 -18
  93. package/dist/shared/layers/utils.d.ts +0 -73
  94. package/dist/shared/layers/utils.js +0 -156
  95. package/dist/shared/tools/Brush.svelte +0 -215
  96. package/dist/shared/tools/Brush.svelte.d.ts +0 -29
  97. package/dist/shared/tools/Crop.svelte +0 -155
  98. package/dist/shared/tools/Crop.svelte.d.ts +0 -16
  99. package/dist/shared/tools/Cropper.svelte +0 -271
  100. package/dist/shared/tools/Cropper.svelte.d.ts +0 -41
  101. package/dist/shared/tools/Handle.svelte +0 -260
  102. package/dist/shared/tools/Handle.svelte.d.ts +0 -29
  103. package/dist/shared/tools/Sources.svelte +0 -257
  104. package/dist/shared/tools/Sources.svelte.d.ts +0 -34
  105. package/dist/shared/tools/Tools.svelte +0 -102
  106. package/dist/shared/tools/Tools.svelte.d.ts +0 -48
  107. package/dist/shared/tools/brush.d.ts +0 -62
  108. package/dist/shared/tools/brush.js +0 -133
  109. package/dist/shared/tools/crop.d.ts +0 -15
  110. package/dist/shared/tools/crop.js +0 -154
  111. package/dist/shared/tools/index.d.ts +0 -5
  112. package/dist/shared/tools/index.js +0 -5
  113. package/dist/shared/tools/sources.d.ts +0 -46
  114. package/dist/shared/tools/sources.js +0 -121
  115. package/dist/shared/tools/types.d.ts +0 -1
  116. package/shared/layers/Layers.svelte +0 -250
  117. package/shared/layers/utils.ts +0 -294
  118. package/shared/tools/Brush.svelte +0 -280
  119. package/shared/tools/BrushOptions.svelte +0 -180
  120. package/shared/tools/Crop.svelte +0 -189
  121. package/shared/tools/Cropper.svelte +0 -346
  122. package/shared/tools/Handle.svelte +0 -289
  123. package/shared/tools/Sources.svelte +0 -283
  124. package/shared/tools/Tools.svelte +0 -162
  125. package/shared/tools/brush.ts +0 -247
  126. package/shared/tools/crop.ts +0 -213
  127. package/shared/tools/index.ts +0 -5
  128. package/shared/tools/sources.ts +0 -195
  129. package/shared/tools/types.ts +0 -1
  130. /package/dist/shared/{tools → brush}/BrushSize.svelte.d.ts +0 -0
  131. /package/dist/shared/{tools/types.js → types.js} +0 -0
@@ -1,69 +1,59 @@
1
1
  import { SvelteComponent } from "svelte";
2
- import type { Writable } from "svelte/store";
3
- import type { Spring } from "svelte/motion";
4
- import { type PixiApp } from "./utils/pixi";
5
- import { type CommandManager, type CommandNode } from "./utils/commands";
6
2
  export declare const EDITOR_KEY: unique symbol;
7
3
  export type context_type = "bg" | "layers" | "crop" | "draw" | "erase";
8
- import { type tool } from "./tools";
9
- export interface EditorContext {
10
- pixi: Writable<PixiApp | null>;
11
- current_layer: Writable<LayerScene | null>;
12
- dimensions: Writable<[number, number]>;
13
- editor_box: Writable<{
14
- parent_width: number;
15
- parent_height: number;
16
- parent_left: number;
17
- parent_top: number;
18
- parent_right: number;
19
- parent_bottom: number;
20
- child_width: number;
21
- child_height: number;
22
- child_left: number;
23
- child_top: number;
24
- child_right: number;
25
- child_bottom: number;
26
- }>;
27
- active_tool: Writable<tool>;
28
- toolbar_box: Writable<DOMRect | Record<string, never>>;
29
- crop: Writable<[number, number, number, number]>;
30
- position_spring: Spring<{
31
- x: number;
32
- y: number;
33
- }>;
34
- command_manager: CommandManager;
35
- current_history: CommandManager["current_history"];
36
- register_context: (type: context_type, { reset_fn, init_fn }: {
37
- reset_fn?: () => void;
38
- init_fn?: (dimensions?: [number, number]) => void;
39
- }) => void;
40
- reset: (clear_image: boolean, dimensions: [number, number]) => void;
41
- }
42
- import { type LayerScene } from "./layers/utils";
43
- import { type ImageBlobs } from "./utils/pixi";
4
+ import { type Tool as ToolbarTool } from "./Toolbar.svelte";
5
+ import type { I18nFormatter } from "@gradio/utils";
6
+ import type { Client, FileData } from "@gradio/client";
7
+ import { type CommandNode } from "./utils/commands";
8
+ import { type Brush, type Eraser } from "./brush/types";
9
+ import type { LayerOptions, Source, Transform, WebcamOptions } from "./types";
10
+ import { type ImageBlobs } from "./types";
44
11
  declare const __propDef: {
45
12
  props: {
46
- antialias?: boolean | undefined;
47
- crop_size: [number, number] | undefined;
48
- changeable?: boolean | undefined;
49
- history: boolean;
50
- bg?: boolean | undefined;
51
- sources: ("clipboard" | "webcam" | "upload")[];
52
- crop_constraint?: boolean | undefined;
53
- canvas_size: [number, number] | undefined;
54
- parent_height: number;
13
+ antialias?: true | undefined;
55
14
  full_history?: (CommandNode | null) | undefined;
56
- height?: number | undefined;
57
- canvas_height?: number | undefined;
15
+ changeable?: boolean | undefined;
16
+ sources?: Source[] | undefined;
17
+ transforms?: Transform[] | undefined;
18
+ canvas_size: [number, number];
19
+ is_dragging?: boolean | undefined;
20
+ background_image?: boolean | undefined;
21
+ brush_options: Brush;
22
+ eraser_options: Eraser;
23
+ fixed_canvas?: boolean | undefined;
24
+ root: string;
25
+ i18n: I18nFormatter;
26
+ upload: Client["upload"];
27
+ composite: FileData | null;
28
+ layers: FileData[];
29
+ background: FileData | null;
30
+ border_region?: number | undefined;
31
+ layer_options: LayerOptions;
32
+ current_tool: ToolbarTool;
33
+ webcam_options: WebcamOptions;
34
+ show_download_button?: boolean | undefined;
35
+ theme_mode: "dark" | "light";
36
+ has_drawn?: boolean | undefined;
58
37
  get_blobs?: (() => Promise<ImageBlobs>) | undefined;
59
- handle_remove?: (() => void) | undefined;
60
- set_tool?: ((tool: tool) => void) | undefined;
38
+ add_image?: ((image: Blob | File) => void) | undefined;
39
+ add_image_from_url?: ((source: string | {
40
+ url: string;
41
+ meta: {
42
+ _type: string;
43
+ };
44
+ } | any) => Promise<void>) | undefined;
45
+ add_layers_from_url?: ((source: FileData[] | any) => Promise<void>) | undefined;
61
46
  };
62
47
  events: {
48
+ error: CustomEvent<string>;
49
+ drag: CustomEvent<any>;
63
50
  clear?: CustomEvent<undefined> | undefined;
64
51
  save: CustomEvent<void>;
65
52
  change: CustomEvent<void>;
66
- history: CustomEvent<Writable<CommandNode>>;
53
+ history: CustomEvent<import("svelte/store").Writable<CommandNode>>;
54
+ upload: CustomEvent<void>;
55
+ input: CustomEvent<void>;
56
+ download_error: CustomEvent<string>;
67
57
  } & {
68
58
  [evt: string]: CustomEvent<any>;
69
59
  };
@@ -75,8 +65,16 @@ export type ImageEditorProps = typeof __propDef.props;
75
65
  export type ImageEditorEvents = typeof __propDef.events;
76
66
  export type ImageEditorSlots = typeof __propDef.slots;
77
67
  export default class ImageEditor extends SvelteComponent<ImageEditorProps, ImageEditorEvents, ImageEditorSlots> {
68
+ get antialias(): true;
69
+ get full_history(): CommandNode;
78
70
  get get_blobs(): () => Promise<ImageBlobs>;
79
- get handle_remove(): () => void;
80
- get set_tool(): (tool: tool) => void;
71
+ get add_image(): (image: Blob | File) => void;
72
+ get add_image_from_url(): (source: string | {
73
+ url: string;
74
+ meta: {
75
+ _type: string;
76
+ };
77
+ } | any) => Promise<void>;
78
+ get add_layers_from_url(): (source: FileData[] | any) => Promise<void>;
81
79
  }
82
80
  export {};
@@ -0,0 +1,260 @@
1
+ <script>import { click_outside } from "./utils/events";
2
+ import {
3
+ Layers,
4
+ Clear,
5
+ ArrowUp,
6
+ ArrowDown,
7
+ Plus,
8
+ Visibility,
9
+ VisibilityOff
10
+ } from "@gradio/icons";
11
+ import { IconButton } from "@gradio/atoms";
12
+ import { createEventDispatcher } from "svelte";
13
+ const dispatch = createEventDispatcher();
14
+ export let layers;
15
+ export let enable_additional_layers = true;
16
+ export let enable_layers = true;
17
+ export let show_layers = false;
18
+ function new_layer() {
19
+ dispatch("new_layer");
20
+ }
21
+ function change_layer(id) {
22
+ dispatch("change_layer", id);
23
+ show_layers = false;
24
+ }
25
+ function move_layer(id, direction) {
26
+ dispatch("move_layer", { id, direction });
27
+ }
28
+ function delete_layer(id) {
29
+ dispatch("delete_layer", id);
30
+ }
31
+ </script>
32
+
33
+ {#if enable_layers}
34
+ <div
35
+ class="layer-wrap"
36
+ class:closed={!show_layers}
37
+ use:click_outside={() => (show_layers = false)}
38
+ >
39
+ <button
40
+ class="layer-title-button"
41
+ aria-label="Show Layers"
42
+ on:click|stopPropagation={() => (show_layers = !show_layers)}
43
+ >
44
+ {show_layers
45
+ ? "Layers"
46
+ : $layers.layers.find((l) => l.id === $layers.active_layer)?.name}
47
+ <span class="icon"><Layers /></span>
48
+ </button>
49
+ {#if show_layers}
50
+ <ul>
51
+ {#each $layers.layers as { id, name, user_created, visible }, i (i)}
52
+ <li>
53
+ {#if !visible}
54
+ <IconButton
55
+ Icon={VisibilityOff}
56
+ size="small"
57
+ on:click={(e) => {
58
+ e.stopPropagation();
59
+ dispatch("toggle_layer_visibility", id);
60
+ }}
61
+ />
62
+ {:else}
63
+ <IconButton
64
+ Icon={Visibility}
65
+ size="small"
66
+ on:click={(e) => {
67
+ e.stopPropagation();
68
+ dispatch("toggle_layer_visibility", id);
69
+ }}
70
+ />
71
+ {/if}
72
+ <button
73
+ class:selected_layer={$layers.active_layer === id}
74
+ aria-label={`layer-${i + 1}`}
75
+ on:click|stopPropagation={() => change_layer(id)}>{name}</button
76
+ >
77
+ {#if $layers.layers.length > 1}
78
+ <div>
79
+ {#if i > 0}
80
+ <IconButton
81
+ on:click={(e) => {
82
+ e.stopPropagation();
83
+ move_layer(id, "up");
84
+ }}
85
+ Icon={ArrowUp}
86
+ size="x-small"
87
+ />
88
+ {/if}
89
+ {#if i < $layers.layers.length - 1}
90
+ <IconButton
91
+ on:click={(e) => {
92
+ e.stopPropagation();
93
+ move_layer(id, "down");
94
+ }}
95
+ Icon={ArrowDown}
96
+ size="x-small"
97
+ />
98
+ {/if}
99
+ {#if $layers.layers.length > 1 && user_created}
100
+ <IconButton
101
+ on:click={(e) => {
102
+ e.stopPropagation();
103
+ delete_layer(id);
104
+ }}
105
+ Icon={Clear}
106
+ size="x-small"
107
+ />
108
+ {/if}
109
+ </div>
110
+ {/if}
111
+ </li>
112
+ {/each}
113
+ {#if enable_additional_layers}
114
+ <li class="add-layer">
115
+ <IconButton
116
+ Icon={Plus}
117
+ label="Add Layer"
118
+ on:click={(e) => {
119
+ e.stopPropagation();
120
+ new_layer();
121
+ }}
122
+ size="x-small"
123
+ />
124
+ </li>
125
+ {/if}
126
+ </ul>
127
+ {/if}
128
+ </div>
129
+ {/if}
130
+
131
+ <style>
132
+ .add-layer {
133
+ display: flex;
134
+ justify-content: center;
135
+ align-items: center;
136
+ margin: var(--spacing-sm) 0 0 0;
137
+ }
138
+
139
+ .add-layer :global(button) {
140
+ width: 100%;
141
+ }
142
+ .icon {
143
+ width: 14px;
144
+ color: var(--body-text-color);
145
+ transition: color 0.15s ease;
146
+ }
147
+
148
+ .layer-wrap {
149
+ /* position: absolute; */
150
+ display: flex;
151
+ justify-content: center;
152
+ align-items: center;
153
+ /* border: 1px solid var(--border-color-primary); */
154
+ /* z-index: var(--layer-1); */
155
+ /* border-radius: var(--radius-sm); */
156
+ /* background-color: var(--block-background-fill); */
157
+ width: 100%;
158
+ flex-direction: column;
159
+ /* bottom: 5px; */
160
+ /* right: 5px; */
161
+ /* border-bottom: 0;
162
+ border-right: 0; */
163
+ /* box-shadow: var(--shadow-drop); */
164
+ }
165
+
166
+ .layer-wrap button {
167
+ justify-content: space-between;
168
+ align-items: center;
169
+ width: 100%;
170
+ display: flex;
171
+ font-size: var(--text-sm);
172
+ line-height: var(--line-sm);
173
+ transition: all 0.15s ease;
174
+ padding: var(--spacing-md) var(--spacing-lg);
175
+ /* padding-right: var(--spacing-lg); */
176
+ border-radius: var(--radius-sm);
177
+ /* padding-left: 30px; */
178
+ }
179
+
180
+ button.layer-title-button {
181
+ width: 100%;
182
+ /* padding-left: 30px; */
183
+ }
184
+
185
+ .layer-wrap button:hover .icon {
186
+ color: var(--color-accent);
187
+ }
188
+
189
+ .selected_layer {
190
+ color: var(--color-accent);
191
+ font-weight: var(--weight-semibold);
192
+ }
193
+
194
+ ul {
195
+ /* position: absolute; */
196
+ bottom: 0;
197
+ right: 0;
198
+ /* background: var(--block-background-fill); */
199
+ width: 100%;
200
+ /* min-width: 100%; */
201
+ list-style: none;
202
+ z-index: var(--layer-top);
203
+ /* border: 1px solid var(--border-color-primary); */
204
+ /* border-radius: var(--radius-sm); */
205
+ /* box-shadow: var(--shadow-drop-lg); */
206
+ padding: var(--spacing-sm);
207
+ /* transform: translate(-1px, 1px); */
208
+ border-top: 1px solid var(--border-color-primary);
209
+ }
210
+
211
+ /* .sep {
212
+ height: 12px;
213
+ background-color: var(--block-border-color);
214
+ width: 1px;
215
+ display: block;
216
+ margin-left: var(--spacing-xl);
217
+ } */
218
+
219
+ li {
220
+ display: flex;
221
+ justify-content: space-between;
222
+ align-items: center;
223
+ /* border-radius: var(--radius-sm); */
224
+ transition: background-color 0.15s ease;
225
+ border-bottom: 1px solid var(--border-color-primary);
226
+ }
227
+
228
+ .layer-wrap ul > li > button {
229
+ padding-left: calc(var(--spacing-md));
230
+ }
231
+
232
+ li:hover {
233
+ background-color: var(--background-fill-secondary);
234
+ }
235
+
236
+ li:last-child {
237
+ border-bottom: none;
238
+ }
239
+ li:last-child:hover {
240
+ background-color: unset;
241
+ }
242
+
243
+ li div {
244
+ display: flex;
245
+ gap: var(--spacing-sm);
246
+ padding: var(--spacing-sm);
247
+ }
248
+ li > button {
249
+ padding: var(--spacing-sm) var(--spacing-md);
250
+ }
251
+
252
+ /* li > div > button {
253
+ opacity: 0.7;
254
+ transition: opacity 0.15s ease;
255
+ }
256
+
257
+ li > div > button:hover {
258
+ opacity: 1;
259
+ } */
260
+ </style>
@@ -0,0 +1,37 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { Writable } from "svelte/store";
3
+ declare const __propDef: {
4
+ props: {
5
+ layers: Writable<{
6
+ active_layer: string;
7
+ layers: {
8
+ name: string;
9
+ id: string;
10
+ user_created: boolean;
11
+ visible: boolean;
12
+ }[];
13
+ }>;
14
+ enable_additional_layers?: boolean | undefined;
15
+ enable_layers?: boolean | undefined;
16
+ show_layers?: boolean | undefined;
17
+ };
18
+ events: {
19
+ new_layer: CustomEvent<void>;
20
+ change_layer: CustomEvent<string>;
21
+ move_layer: CustomEvent<{
22
+ id: string;
23
+ direction: "up" | "down";
24
+ }>;
25
+ delete_layer: CustomEvent<string>;
26
+ toggle_layer_visibility: CustomEvent<string>;
27
+ } & {
28
+ [evt: string]: CustomEvent<any>;
29
+ };
30
+ slots: {};
31
+ };
32
+ export type LayersProps = typeof __propDef.props;
33
+ export type LayersEvents = typeof __propDef.events;
34
+ export type LayersSlots = typeof __propDef.slots;
35
+ export default class Layers extends SvelteComponent<LayersProps, LayersEvents, LayersSlots> {
36
+ }
37
+ export {};
@@ -0,0 +1,218 @@
1
+ <script context="module"></script>
2
+
3
+ <script>import { createEventDispatcher } from "svelte";
4
+ import Anchor from "./Anchor.svelte";
5
+ export let dimensions;
6
+ const dispatch = createEventDispatcher();
7
+ let selected_anchor = "center";
8
+ let scale = false;
9
+ let new_width = $dimensions?.width;
10
+ let new_height = $dimensions?.height;
11
+ function handle_click() {
12
+ dispatch("change", {
13
+ anchor: selected_anchor,
14
+ scale,
15
+ width: new_width,
16
+ height: new_height
17
+ });
18
+ }
19
+ function set_anchor(position) {
20
+ selected_anchor = position;
21
+ }
22
+ </script>
23
+
24
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
25
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
26
+ <div class="wrap" on:click|stopPropagation>
27
+ <div class="size-wrap">
28
+ <div class="size-input">
29
+ <label for="width">Width</label><input
30
+ type="number"
31
+ id="width"
32
+ bind:value={new_width}
33
+ />
34
+ </div>
35
+ <div class="size-input">
36
+ <label for="height">Height </label><input
37
+ type="number"
38
+ id="height"
39
+ bind:value={new_height}
40
+ />
41
+ </div>
42
+ </div>
43
+
44
+ <div class="scale-wrap">
45
+ <h2 class="image-will-label">Image will:</h2>
46
+ <div class="toggle-container">
47
+ <label class="radio-label">
48
+ <input
49
+ type="radio"
50
+ name="resize_mode"
51
+ value={true}
52
+ bind:group={scale}
53
+ />
54
+ <span class="radio-button">rescale</span>
55
+ </label>
56
+ <label class="radio-label">
57
+ <input
58
+ type="radio"
59
+ name="resize_mode"
60
+ value={false}
61
+ bind:group={scale}
62
+ />
63
+ <span class="radio-button">anchor</span>
64
+ </label>
65
+ </div>
66
+ </div>
67
+ <div class="anchor-wrap">
68
+ <Anchor on:position={(e) => set_anchor(e.detail)} />
69
+ </div>
70
+ <button class="apply-button" on:click={() => handle_click()}
71
+ >Resize Canvas</button
72
+ >
73
+ </div>
74
+
75
+ <!-- </div> -->
76
+
77
+ <style>
78
+ .wrap {
79
+ padding: var(--spacing-xl) var(--spacing-lg);
80
+ color: var(--block-label-text-color);
81
+ }
82
+
83
+ .size-wrap {
84
+ display: flex;
85
+ flex-direction: row;
86
+ gap: 10px;
87
+ }
88
+
89
+ .size-input {
90
+ display: flex;
91
+ flex-direction: column;
92
+ gap: var(--spacing-xxs);
93
+ }
94
+
95
+ label,
96
+ h2 {
97
+ display: flex;
98
+ align-items: center;
99
+ gap: 15px;
100
+
101
+ cursor: pointer;
102
+ color: var(--checkbox-label-text-color);
103
+ font-weight: var(--checkbox-label-text-weight);
104
+ font-size: var(--text-sm);
105
+ line-height: var(--line-md);
106
+ }
107
+
108
+ .scale-wrap {
109
+ display: flex;
110
+ flex-direction: column;
111
+ gap: var(--spacing-sm);
112
+ margin-top: var(--spacing-md);
113
+ }
114
+
115
+ input[type="number"] {
116
+ border: 1px solid var(--border-color-primary);
117
+ width: 60px;
118
+ border-radius: var(--radius-sm);
119
+ background-color: var(--checkbox-background-color-focus);
120
+ color: var(--body-text-color);
121
+ font-size: var(--text-sm);
122
+ transition: border-color 0.15s ease;
123
+ padding: var(--spacing-xs);
124
+ line-height: 1rem;
125
+ }
126
+
127
+ input[type="number"]:hover {
128
+ border-color: var(--color-accent-soft);
129
+ }
130
+
131
+ input[type="number"]:focus {
132
+ border-color: var(--color-accent);
133
+ outline: none;
134
+ box-shadow: 0 0 0 1px var(--color-accent-soft);
135
+ }
136
+
137
+ .image-will-label {
138
+ grid-column: 1;
139
+ }
140
+
141
+ .toggle-container {
142
+ display: flex;
143
+ grid-column: 2;
144
+ border-radius: var(--radius-sm);
145
+ border: 1px solid var(--border-color-primary);
146
+ overflow: hidden;
147
+ }
148
+
149
+ .toggle-container {
150
+ display: flex;
151
+ grid-column: 2;
152
+ border-radius: var(--radius-sm);
153
+ border: 1px solid var(--border-color-primary);
154
+ overflow: hidden;
155
+ }
156
+
157
+ .radio-label {
158
+ flex: 1;
159
+ margin: 0;
160
+ padding: 0;
161
+ position: relative;
162
+ cursor: pointer;
163
+ }
164
+
165
+ .radio-button {
166
+ display: flex;
167
+ justify-content: center;
168
+ align-items: center;
169
+ padding: var(--spacing-sm);
170
+ background: var(--checkbox-background-color);
171
+ color: var(--body-text-color);
172
+ font-size: var(--text-sm);
173
+ transition: background-color 0.15s ease;
174
+ width: 100%;
175
+ height: 100%;
176
+ }
177
+
178
+ input[type="radio"] {
179
+ position: absolute;
180
+ opacity: 0;
181
+ width: 0;
182
+ height: 0;
183
+ }
184
+
185
+ input[type="radio"]:not(:checked) + .radio-button:hover {
186
+ background: var(--checkbox-background-color-hover);
187
+ }
188
+
189
+ input[type="radio"]:checked + .radio-button {
190
+ background: var(--color-accent);
191
+ color: white;
192
+ }
193
+
194
+ .apply-button {
195
+ width: 100%;
196
+ margin-top: var(--spacing-md);
197
+ padding: var(--spacing-sm) var(--spacing-md);
198
+ background: var(--color-accent);
199
+ color: white;
200
+ border: none;
201
+ border-radius: var(--radius-sm);
202
+ font-size: var(--text-sm);
203
+ font-weight: var(--weight-semibold);
204
+ transition: all 0.15s ease;
205
+ }
206
+
207
+ .apply-button:hover {
208
+ background: var(--button-primary-background-fill-hover);
209
+ }
210
+
211
+ .anchor-wrap {
212
+ display: flex;
213
+ justify-content: center;
214
+ align-items: center;
215
+ flex-direction: column;
216
+ gap: 10px;
217
+ }
218
+ </style>
@@ -0,0 +1,29 @@
1
+ import { SvelteComponent } from "svelte";
2
+ export type Position = "top-left" | "top" | "top-right" | "left" | "center" | "right" | "bottom-left" | "bottom" | "bottom-right";
3
+ import type { Spring } from "svelte/motion";
4
+ declare const __propDef: {
5
+ props: {
6
+ dimensions: Spring<{
7
+ width: number;
8
+ height: number;
9
+ }>;
10
+ };
11
+ events: {
12
+ click: MouseEvent;
13
+ change: CustomEvent<{
14
+ anchor: Position;
15
+ scale: boolean;
16
+ width: number;
17
+ height: number;
18
+ }>;
19
+ } & {
20
+ [evt: string]: CustomEvent<any>;
21
+ };
22
+ slots: {};
23
+ };
24
+ export type ResizeProps = typeof __propDef.props;
25
+ export type ResizeEvents = typeof __propDef.events;
26
+ export type ResizeSlots = typeof __propDef.slots;
27
+ export default class Resize extends SvelteComponent<ResizeProps, ResizeEvents, ResizeSlots> {
28
+ }
29
+ export {};