@gradio/imageeditor 0.18.2-dev.0 → 0.18.2

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 (42) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/Index.svelte +122 -159
  3. package/InteractiveImageEditor.svelte +1 -0
  4. package/dist/Example.svelte +7 -4
  5. package/dist/Example.svelte.d.ts +20 -18
  6. package/dist/Index.svelte +152 -136
  7. package/dist/Index.svelte.d.ts +18 -202
  8. package/dist/InteractiveImageEditor.svelte +205 -148
  9. package/dist/InteractiveImageEditor.svelte.d.ts +55 -51
  10. package/dist/shared/Anchor.svelte +210 -136
  11. package/dist/shared/Anchor.svelte.d.ts +18 -16
  12. package/dist/shared/Controls.svelte +55 -36
  13. package/dist/shared/Controls.svelte.d.ts +35 -33
  14. package/dist/shared/IconButton.svelte +19 -17
  15. package/dist/shared/IconButton.svelte.d.ts +34 -32
  16. package/dist/shared/ImageEditor.svelte +673 -466
  17. package/dist/shared/ImageEditor.svelte.d.ts +4 -79
  18. package/dist/shared/Layers.svelte +52 -30
  19. package/dist/shared/Layers.svelte.d.ts +39 -36
  20. package/dist/shared/Resize.svelte +42 -21
  21. package/dist/shared/Resize.svelte.d.ts +29 -27
  22. package/dist/shared/SecondaryToolbar.svelte +17 -5
  23. package/dist/shared/SecondaryToolbar.svelte.d.ts +38 -36
  24. package/dist/shared/Toolbar.svelte +123 -69
  25. package/dist/shared/Toolbar.svelte.d.ts +40 -38
  26. package/dist/shared/brush/BrushOptions.svelte +119 -84
  27. package/dist/shared/brush/BrushOptions.svelte.d.ts +29 -27
  28. package/dist/shared/brush/BrushSize.svelte +12 -7
  29. package/dist/shared/brush/BrushSize.svelte.d.ts +23 -20
  30. package/dist/shared/brush/ColorField.svelte +49 -33
  31. package/dist/shared/brush/ColorField.svelte.d.ts +23 -21
  32. package/dist/shared/brush/ColorPicker.svelte +152 -108
  33. package/dist/shared/brush/ColorPicker.svelte.d.ts +19 -17
  34. package/dist/shared/brush/ColorSwatch.svelte +78 -46
  35. package/dist/shared/brush/ColorSwatch.svelte.d.ts +34 -32
  36. package/dist/types.d.ts +40 -0
  37. package/dist/types.js +25 -0
  38. package/package.json +12 -12
  39. package/shared/ImageEditor.svelte +1 -3
  40. package/shared/brush/BrushOptions.svelte +1 -1
  41. package/shared/brush/ColorPicker.svelte +2 -1
  42. package/types.ts +74 -0
@@ -1,151 +1,207 @@
1
- <script context="module"></script>
2
-
3
- <script>import { createEventDispatcher } from "svelte";
4
- import {} from "@gradio/utils";
5
- import { prepare_files } from "@gradio/client";
6
- import {} from "./shared/core/commands";
7
- import ImageEditor from "./shared/ImageEditor.svelte";
8
- import {} from "./shared/brush/types";
9
- import {} from "./shared/Toolbar.svelte";
10
- import { BlockLabel } from "@gradio/atoms";
11
- import { Image as ImageIcon } from "@gradio/icons";
12
- import { inject } from "./shared/utils/parse_placeholder";
13
- import {
14
- } from "./shared/types";
15
- export let brush;
16
- export let eraser;
17
- export let sources;
18
- export let i18n;
19
- export let root;
20
- export let label = void 0;
21
- export let show_label;
22
- export let changeable = false;
23
- export let theme_mode;
24
- export let layers;
25
- export let composite;
26
- export let background;
27
- export let layer_options;
28
- export let transforms;
29
- export let accept_blobs;
30
- export let canvas_size;
31
- export let fixed_canvas = false;
32
- export let realtime;
33
- export let upload;
34
- export let is_dragging;
35
- export let placeholder = void 0;
36
- export let border_region;
37
- export let full_history = null;
38
- export let webcam_options;
39
- export let show_download_button = false;
40
- const dispatch = createEventDispatcher();
41
- let editor;
42
- let has_drawn = false;
43
- function is_not_null(o) {
44
- return !!o;
45
- }
46
- function is_file_data(o) {
47
- return !!o;
48
- }
49
- $: if (background_image) dispatch("upload");
50
- export async function get_data() {
51
- let blobs;
52
- try {
53
- blobs = await editor.get_blobs();
54
- } catch (e) {
55
- return { background: null, layers: [], composite: null };
56
- }
57
- const bg = blobs.background ? upload(
58
- await prepare_files([new File([blobs.background], "background.png")]),
59
- root
60
- ) : Promise.resolve(null);
61
- const layers2 = blobs.layers.filter(is_not_null).map(
62
- async (blob, i) => upload(await prepare_files([new File([blob], `layer_${i}.png`)]), root)
63
- );
64
- const composite2 = blobs.composite ? upload(
65
- await prepare_files([new File([blobs.composite], "composite.png")]),
66
- root
67
- ) : Promise.resolve(null);
68
- const [background2, composite_, ...layers_] = await Promise.all([
69
- bg,
70
- composite2,
71
- ...layers2
72
- ]);
73
- return {
74
- background: Array.isArray(background2) ? background2[0] : background2,
75
- layers: layers_.flatMap((layer) => Array.isArray(layer) ? layer : [layer]).filter(is_file_data),
76
- composite: Array.isArray(composite_) ? composite_[0] : composite_
77
- };
78
- }
79
- function handle_value(value) {
80
- if (!editor) return;
81
- if (value == null) {
82
- editor.handle_remove();
83
- dispatch("receive_null");
84
- }
85
- }
86
- $: handle_value({ layers, composite, background });
87
- let background_image = false;
88
- let can_undo;
89
- export let image_id = null;
90
- function nextframe() {
91
- return new Promise((resolve) => setTimeout(() => resolve(), 30));
92
- }
93
- let uploading = false;
94
- let pending = false;
95
- async function handle_change(e) {
96
- if (!realtime) return;
97
- if (uploading) {
98
- pending = true;
99
- return;
100
- }
101
- uploading = true;
102
- await nextframe();
103
- const blobs = await editor.get_blobs();
104
- const images = [];
105
- let id = Math.random().toString(36).substring(2);
106
- if (blobs.background)
107
- images.push([
108
- id,
109
- "background",
110
- new File([blobs.background], "background.png"),
111
- null
112
- ]);
113
- if (blobs.composite)
114
- images.push([
115
- id,
116
- "composite",
117
- new File([blobs.composite], "composite.png"),
118
- null
119
- ]);
120
- blobs.layers.forEach((layer, i) => {
121
- if (layer)
122
- images.push([
123
- id,
124
- `layer`,
125
- new File([layer], `layer_${i}.png`),
126
- i
127
- ]);
128
- });
129
- await Promise.all(
130
- images.map(async ([image_id2, type, data, index]) => {
131
- return accept_blobs({
132
- binary: true,
133
- data: { file: data, id: image_id2, type, index }
134
- });
135
- })
136
- );
137
- image_id = id;
138
- dispatch("change");
139
- await nextframe();
140
- uploading = false;
141
- if (pending) {
142
- pending = false;
143
- uploading = false;
144
- handle_change(e);
145
- }
146
- }
147
- $: [heading, paragraph] = placeholder ? inject(placeholder) : [false, false];
148
- let current_tool;
1
+ <script lang="ts" context="module">
2
+ export interface EditorData {
3
+ background: FileData | null;
4
+ layers: FileData[] | null;
5
+ composite: FileData | null;
6
+ }
7
+
8
+ export interface ImageBlobs {
9
+ background: FileData | null;
10
+ layers: FileData[];
11
+ composite: FileData | null;
12
+ }
13
+ </script>
14
+
15
+ <script lang="ts">
16
+ import { createEventDispatcher } from "svelte";
17
+ import { type I18nFormatter } from "@gradio/utils";
18
+ import { prepare_files, type FileData, type Client } from "@gradio/client";
19
+ import { type CommandNode } from "./shared/core/commands";
20
+ import ImageEditor from "./shared/ImageEditor.svelte";
21
+ import { type Brush as IBrush, type Eraser } from "./shared/brush/types";
22
+ import { type Tool as ToolbarTool } from "./shared/Toolbar.svelte";
23
+
24
+ import { BlockLabel } from "@gradio/atoms";
25
+ import { Image as ImageIcon } from "@gradio/icons";
26
+ import { inject } from "./shared/utils/parse_placeholder";
27
+ import {
28
+ type LayerOptions,
29
+ type Transform,
30
+ type Source,
31
+ type WebcamOptions
32
+ } from "./shared/types";
33
+
34
+ export let brush: IBrush;
35
+ export let eraser: Eraser;
36
+ export let sources: Source[];
37
+ export let i18n: I18nFormatter;
38
+ export let root: string;
39
+ export let label: string | undefined = undefined;
40
+ export let show_label: boolean;
41
+ export let changeable = false;
42
+ export let theme_mode: "dark" | "light";
43
+
44
+ export let layers: FileData[];
45
+ export let composite: FileData | null;
46
+ export let background: FileData | null;
47
+
48
+ export let layer_options: LayerOptions;
49
+ export let transforms: Transform[];
50
+ export let accept_blobs: (a: any) => void;
51
+
52
+ export let canvas_size: [number, number];
53
+ export let fixed_canvas = false;
54
+ export let realtime: boolean;
55
+ export let upload: Client["upload"];
56
+ export let is_dragging: boolean;
57
+ export let placeholder: string | undefined = undefined;
58
+ export let border_region: number;
59
+ export let full_history: CommandNode | null = null;
60
+ export let webcam_options: WebcamOptions;
61
+ export let show_download_button = false;
62
+
63
+ const dispatch = createEventDispatcher<{
64
+ clear?: never;
65
+ upload?: never;
66
+ change?: never;
67
+ receive_null?: never;
68
+ }>();
69
+
70
+ let editor: ImageEditor;
71
+ let has_drawn = false;
72
+
73
+ function is_not_null(o: Blob | null): o is Blob {
74
+ return !!o;
75
+ }
76
+
77
+ function is_file_data(o: null | FileData): o is FileData {
78
+ return !!o;
79
+ }
80
+
81
+ $: if (background_image) dispatch("upload");
82
+
83
+ export async function get_data(): Promise<ImageBlobs> {
84
+ let blobs;
85
+ try {
86
+ blobs = await editor.get_blobs();
87
+ } catch (e) {
88
+ return { background: null, layers: [], composite: null };
89
+ }
90
+
91
+ const bg = blobs.background
92
+ ? upload(
93
+ await prepare_files([new File([blobs.background], "background.png")]),
94
+ root
95
+ )
96
+ : Promise.resolve(null);
97
+
98
+ const layers = blobs.layers
99
+ .filter(is_not_null)
100
+ .map(async (blob, i) =>
101
+ upload(await prepare_files([new File([blob], `layer_${i}.png`)]), root)
102
+ );
103
+
104
+ const composite = blobs.composite
105
+ ? upload(
106
+ await prepare_files([new File([blobs.composite], "composite.png")]),
107
+ root
108
+ )
109
+ : Promise.resolve(null);
110
+
111
+ const [background, composite_, ...layers_] = await Promise.all([
112
+ bg,
113
+ composite,
114
+ ...layers
115
+ ]);
116
+
117
+ return {
118
+ background: Array.isArray(background) ? background[0] : background,
119
+ layers: layers_
120
+ .flatMap((layer) => (Array.isArray(layer) ? layer : [layer]))
121
+ .filter(is_file_data),
122
+ composite: Array.isArray(composite_) ? composite_[0] : composite_
123
+ };
124
+ }
125
+
126
+ function handle_value(value: EditorData | null): void {
127
+ if (!editor) return;
128
+ if (value == null) {
129
+ editor.handle_remove();
130
+ dispatch("receive_null");
131
+ }
132
+ }
133
+
134
+ $: handle_value({ layers, composite, background });
135
+
136
+ let background_image = false;
137
+ let can_undo: boolean;
138
+
139
+ export let image_id: null | string = null;
140
+
141
+ type BinaryImages = [string, string, File, number | null][];
142
+
143
+ function nextframe(): Promise<void> {
144
+ return new Promise((resolve) => setTimeout(() => resolve(), 30));
145
+ }
146
+
147
+ let uploading = false;
148
+ let pending = false;
149
+ async function handle_change(e: CustomEvent<Blob | any>): Promise<void> {
150
+ if (!realtime) return;
151
+ if (uploading) {
152
+ pending = true;
153
+ return;
154
+ }
155
+ uploading = true;
156
+ await nextframe();
157
+ const blobs = await editor.get_blobs();
158
+ const images: BinaryImages = [];
159
+ let id = Math.random().toString(36).substring(2);
160
+ if (blobs.background)
161
+ images.push([
162
+ id,
163
+ "background",
164
+ new File([blobs.background], "background.png"),
165
+ null
166
+ ]);
167
+ if (blobs.composite)
168
+ images.push([
169
+ id,
170
+ "composite",
171
+ new File([blobs.composite], "composite.png"),
172
+ null
173
+ ]);
174
+ blobs.layers.forEach((layer, i) => {
175
+ if (layer)
176
+ images.push([
177
+ id as string,
178
+ `layer`,
179
+ new File([layer], `layer_${i}.png`),
180
+ i
181
+ ]);
182
+ });
183
+ await Promise.all(
184
+ images.map(async ([image_id, type, data, index]) => {
185
+ return accept_blobs({
186
+ binary: true,
187
+ data: { file: data, id: image_id, type, index }
188
+ });
189
+ })
190
+ );
191
+ image_id = id;
192
+ dispatch("change");
193
+ await nextframe();
194
+ uploading = false;
195
+ if (pending) {
196
+ pending = false;
197
+ uploading = false;
198
+ handle_change(e);
199
+ }
200
+ }
201
+
202
+ $: [heading, paragraph] = placeholder ? inject(placeholder) : [false, false];
203
+
204
+ let current_tool: ToolbarTool;
149
205
  </script>
150
206
 
151
207
  <BlockLabel
@@ -163,6 +219,7 @@ let current_tool;
163
219
  bind:this={editor}
164
220
  {changeable}
165
221
  on:save
222
+ on:input
166
223
  on:change={handle_change}
167
224
  on:clear={() => dispatch("clear")}
168
225
  on:download_error
@@ -1,4 +1,3 @@
1
- import { SvelteComponent } from "svelte";
2
1
  export interface EditorData {
3
2
  background: FileData | null;
4
3
  layers: FileData[] | null;
@@ -14,55 +13,60 @@ import { type FileData, type Client } from "@gradio/client";
14
13
  import { type CommandNode } from "./shared/core/commands";
15
14
  import { type Brush as IBrush, type Eraser } from "./shared/brush/types";
16
15
  import { type LayerOptions, type Transform, type Source, type WebcamOptions } from "./shared/types";
17
- declare const __propDef: {
18
- props: {
19
- brush: IBrush;
20
- eraser: Eraser;
21
- sources: Source[];
22
- i18n: I18nFormatter;
23
- root: string;
24
- label?: string | undefined;
25
- show_label: boolean;
26
- changeable?: boolean;
27
- theme_mode: "dark" | "light";
28
- layers: FileData[];
29
- composite: FileData | null;
30
- background: FileData | null;
31
- layer_options: LayerOptions;
32
- transforms: Transform[];
33
- accept_blobs: (a: any) => void;
34
- canvas_size: [number, number];
35
- fixed_canvas?: boolean;
36
- realtime: boolean;
37
- upload: Client["upload"];
38
- is_dragging: boolean;
39
- placeholder?: string | undefined;
40
- border_region: number;
41
- full_history?: CommandNode | null;
42
- webcam_options: WebcamOptions;
43
- show_download_button?: boolean;
44
- get_data?: () => Promise<ImageBlobs>;
45
- image_id?: null | string;
16
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
17
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
18
+ $$bindings?: Bindings;
19
+ } & Exports;
20
+ (internal: unknown, props: Props & {
21
+ $$events?: Events;
22
+ $$slots?: Slots;
23
+ }): Exports & {
24
+ $set?: any;
25
+ $on?: any;
46
26
  };
47
- events: {
48
- history: CustomEvent<any>;
49
- save: CustomEvent<void>;
50
- download_error: CustomEvent<string>;
51
- clear?: CustomEvent<undefined> | undefined;
52
- upload?: CustomEvent<undefined> | undefined;
53
- change?: CustomEvent<undefined> | undefined;
54
- receive_null?: CustomEvent<undefined> | undefined;
55
- } & {
56
- [evt: string]: CustomEvent<any>;
57
- };
58
- slots: {};
59
- exports?: {} | undefined;
60
- bindings?: string | undefined;
61
- };
62
- export type InteractiveImageEditorProps = typeof __propDef.props;
63
- export type InteractiveImageEditorEvents = typeof __propDef.events;
64
- export type InteractiveImageEditorSlots = typeof __propDef.slots;
65
- export default class InteractiveImageEditor extends SvelteComponent<InteractiveImageEditorProps, InteractiveImageEditorEvents, InteractiveImageEditorSlots> {
66
- get get_data(): () => Promise<ImageBlobs>;
27
+ z_$$bindings?: Bindings;
67
28
  }
68
- export {};
29
+ declare const InteractiveImageEditor: $$__sveltets_2_IsomorphicComponent<{
30
+ brush: IBrush;
31
+ eraser: Eraser;
32
+ sources: Source[];
33
+ i18n: I18nFormatter;
34
+ root: string;
35
+ label?: string | undefined;
36
+ show_label: boolean;
37
+ changeable?: boolean;
38
+ theme_mode: "dark" | "light";
39
+ layers: FileData[];
40
+ composite: FileData | null;
41
+ background: FileData | null;
42
+ layer_options: LayerOptions;
43
+ transforms: Transform[];
44
+ accept_blobs: (a: any) => void;
45
+ canvas_size: [number, number];
46
+ fixed_canvas?: boolean;
47
+ realtime: boolean;
48
+ upload: Client["upload"];
49
+ is_dragging: boolean;
50
+ placeholder?: string | undefined;
51
+ border_region: number;
52
+ full_history?: CommandNode | null;
53
+ webcam_options: WebcamOptions;
54
+ show_download_button?: boolean;
55
+ get_data?: () => Promise<ImageBlobs>;
56
+ image_id?: null | string;
57
+ }, {
58
+ history: any;
59
+ save: any;
60
+ input: any;
61
+ download_error: any;
62
+ clear?: CustomEvent<undefined> | undefined;
63
+ upload?: CustomEvent<undefined> | undefined;
64
+ change?: CustomEvent<undefined> | undefined;
65
+ receive_null?: CustomEvent<undefined> | undefined;
66
+ } & {
67
+ [evt: string]: CustomEvent<any>;
68
+ }, {}, {
69
+ get_data: () => Promise<ImageBlobs>;
70
+ }, string>;
71
+ type InteractiveImageEditor = InstanceType<typeof InteractiveImageEditor>;
72
+ export default InteractiveImageEditor;