@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.
- package/CHANGELOG.md +36 -0
- package/Example.svelte +1 -1
- package/IMAGE_EDITOR_OVERVIEW.md +224 -0
- package/ImageEditor.stories.svelte +13 -5
- package/Index.svelte +46 -45
- package/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +65 -103
- package/README.md +2 -0
- package/dist/Example.svelte.d.ts +1 -1
- package/dist/Index.svelte +35 -33
- package/dist/Index.svelte.d.ts +25 -16
- package/dist/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +54 -88
- package/dist/{shared/InteractiveImageEditor.svelte.d.ts → InteractiveImageEditor.svelte.d.ts} +17 -15
- package/dist/shared/Anchor.svelte +311 -0
- package/dist/shared/Anchor.svelte.d.ts +18 -0
- package/dist/shared/Controls.svelte +169 -18
- package/dist/shared/Controls.svelte.d.ts +9 -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 +572 -289
- package/dist/shared/ImageEditor.svelte.d.ts +54 -56
- package/dist/shared/Layers.svelte +260 -0
- package/dist/shared/Layers.svelte.d.ts +37 -0
- package/dist/shared/Resize.svelte +218 -0
- package/dist/shared/Resize.svelte.d.ts +29 -0
- package/dist/shared/SecondaryToolbar.svelte +55 -0
- package/dist/shared/SecondaryToolbar.svelte.d.ts +37 -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 +65 -0
- package/dist/shared/brush/brush-textures.js +385 -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 +397 -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 +261 -0
- package/dist/shared/core/editor.js +1264 -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 +183 -0
- package/dist/shared/resize/resize.d.ts +270 -0
- package/dist/shared/resize/resize.js +1413 -0
- package/dist/shared/types.d.ts +16 -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 +8 -7
- package/shared/Anchor.svelte +384 -0
- package/shared/Controls.svelte +178 -37
- package/shared/{tools/IconButton.svelte → IconButton.svelte} +21 -4
- package/shared/ImageEditor.svelte +712 -350
- package/shared/Layers.svelte +282 -0
- package/shared/Resize.svelte +239 -0
- package/shared/SecondaryToolbar.svelte +67 -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 +485 -0
- package/shared/brush/brush-utils.ts +76 -0
- package/shared/brush/brush.ts +510 -0
- package/shared/brush/types.ts +41 -0
- package/shared/core/EDITOR.md +182 -0
- package/shared/core/editor.ts +1788 -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 +298 -0
- package/shared/resize/resize.ts +1894 -0
- package/shared/types.ts +19 -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
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
<script>import { tick, createEventDispatcher } from "svelte";
|
|
2
|
-
export let type = "corner";
|
|
3
|
-
export let location;
|
|
4
|
-
export let x1 = 0;
|
|
5
|
-
export let y1 = 0;
|
|
6
|
-
export let x2 = 0;
|
|
7
|
-
export let y2 = 0;
|
|
8
|
-
let box;
|
|
9
|
-
let y_offset = 0;
|
|
10
|
-
let x_offset = 0;
|
|
11
|
-
const min = 100;
|
|
12
|
-
let active = false;
|
|
13
|
-
const dispatch = createEventDispatcher();
|
|
14
|
-
export let dragging = false;
|
|
15
|
-
let el;
|
|
16
|
-
function handle_mousedown(e) {
|
|
17
|
-
box = el.getBoundingClientRect();
|
|
18
|
-
active = true;
|
|
19
|
-
dragging = true;
|
|
20
|
-
if (["tl", "bl", "l"].includes(location))
|
|
21
|
-
x_offset = e.clientX - box.right;
|
|
22
|
-
if (["tl", "tr", "t"].includes(location))
|
|
23
|
-
y_offset = e.clientY - box.bottom;
|
|
24
|
-
if (["tr", "r", "br"].includes(location))
|
|
25
|
-
x_offset = e.clientX - box.left;
|
|
26
|
-
if (["br", "b", "bl"].includes(location))
|
|
27
|
-
y_offset = e.clientY - box.top;
|
|
28
|
-
}
|
|
29
|
-
function handle_mousemove(e) {
|
|
30
|
-
if (!active)
|
|
31
|
-
return;
|
|
32
|
-
const top_pos = e.clientY - y_offset;
|
|
33
|
-
const bottom_pos = e.clientY - y_offset;
|
|
34
|
-
const left_pos = e.clientX - x_offset;
|
|
35
|
-
const right_pos = e.clientX - x_offset;
|
|
36
|
-
if (["tl", "bl", "l"].includes(location)) {
|
|
37
|
-
x1 = left_pos;
|
|
38
|
-
}
|
|
39
|
-
if (["tl", "tr", "t"].includes(location)) {
|
|
40
|
-
y1 = top_pos;
|
|
41
|
-
}
|
|
42
|
-
if (["tr", "r", "br"].includes(location)) {
|
|
43
|
-
x2 = right_pos;
|
|
44
|
-
}
|
|
45
|
-
if (["br", "b", "bl"].includes(location)) {
|
|
46
|
-
y2 = bottom_pos;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
async function handle_mouseup(e) {
|
|
50
|
-
await tick();
|
|
51
|
-
active = false;
|
|
52
|
-
dragging = false;
|
|
53
|
-
}
|
|
54
|
-
function make_transform(_location, x12, x22, y12, y22) {
|
|
55
|
-
let t = void 0;
|
|
56
|
-
let l = void 0;
|
|
57
|
-
let r = void 0;
|
|
58
|
-
let b = void 0;
|
|
59
|
-
if (box) {
|
|
60
|
-
if (["tl", "l", "bl"].includes(_location)) {
|
|
61
|
-
l = x12;
|
|
62
|
-
}
|
|
63
|
-
if (["tl", "t", "tr"].includes(_location)) {
|
|
64
|
-
t = y12;
|
|
65
|
-
}
|
|
66
|
-
if (["tr", "r", "br"].includes(_location)) {
|
|
67
|
-
r = x22;
|
|
68
|
-
}
|
|
69
|
-
if (["br", "b", "bl"].includes(_location)) {
|
|
70
|
-
b = y22;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
dispatch("change", { top: t, bottom: b, left: l, right: r });
|
|
74
|
-
return "";
|
|
75
|
-
}
|
|
76
|
-
$:
|
|
77
|
-
transform = make_transform(location, x1, x2, y1, y2);
|
|
78
|
-
</script>
|
|
79
|
-
|
|
80
|
-
<svelte:window on:mousemove={handle_mousemove} on:mouseup={handle_mouseup} />
|
|
81
|
-
|
|
82
|
-
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
83
|
-
<div class="hitbox {location}" on:mousedown={handle_mousedown} style:transform>
|
|
84
|
-
<div class="handle {type} {location}" bind:this={el}></div>
|
|
85
|
-
</div>
|
|
86
|
-
|
|
87
|
-
<style>
|
|
88
|
-
.hitbox {
|
|
89
|
-
position: absolute;
|
|
90
|
-
width: 50px;
|
|
91
|
-
height: 50px;
|
|
92
|
-
--hitbox-mid-offset: calc(50% - 25px);
|
|
93
|
-
--hitbox-corner-offset: -25px;
|
|
94
|
-
--handle-corner-offset: calc(50% - 5px);
|
|
95
|
-
--handle-mid-offset: calc(50% - 2px);
|
|
96
|
-
z-index: var(--layer-top);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/* hitbox positions */
|
|
100
|
-
.hitbox.tl,
|
|
101
|
-
.hitbox.bl,
|
|
102
|
-
.hitbox.l {
|
|
103
|
-
left: var(--hitbox-corner-offset);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
.hitbox.tr,
|
|
107
|
-
.hitbox.br,
|
|
108
|
-
.hitbox.r {
|
|
109
|
-
right: var(--hitbox-corner-offset);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
.hitbox.t,
|
|
113
|
-
.hitbox.tr,
|
|
114
|
-
.hitbox.tl {
|
|
115
|
-
top: var(--hitbox-corner-offset);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.hitbox.t,
|
|
119
|
-
.hitbox.b {
|
|
120
|
-
left: var(--hitbox-mid-offset);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.hitbox.l,
|
|
124
|
-
.hitbox.r {
|
|
125
|
-
top: var(--hitbox-mid-offset);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.hitbox.b,
|
|
129
|
-
.hitbox.br,
|
|
130
|
-
.hitbox.bl {
|
|
131
|
-
bottom: var(--hitbox-corner-offset);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/* hitbox cursors */
|
|
135
|
-
|
|
136
|
-
.hitbox.tl,
|
|
137
|
-
.hitbox.br {
|
|
138
|
-
cursor: nwse-resize;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
.hitbox.bl,
|
|
142
|
-
.hitbox.tr {
|
|
143
|
-
cursor: nesw-resize;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
.hitbox.l,
|
|
147
|
-
.hitbox.r {
|
|
148
|
-
cursor: ew-resize;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
.hitbox.t,
|
|
152
|
-
.hitbox.b {
|
|
153
|
-
cursor: ns-resize;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/* Visual handles */
|
|
157
|
-
.handle {
|
|
158
|
-
position: absolute;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/* square to fill in corners */
|
|
162
|
-
.corner {
|
|
163
|
-
width: 4px;
|
|
164
|
-
height: 4px;
|
|
165
|
-
background: black;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/* handle segment positions */
|
|
169
|
-
.handle.tl,
|
|
170
|
-
.handle.bl,
|
|
171
|
-
.handle.l {
|
|
172
|
-
left: var(--handle-corner-offset);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
.handle.tr,
|
|
176
|
-
.handle.r,
|
|
177
|
-
.handle.br {
|
|
178
|
-
right: var(--handle-corner-offset);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
.handle.tr,
|
|
182
|
-
.handle.t,
|
|
183
|
-
.handle.tl {
|
|
184
|
-
top: var(--handle-corner-offset);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
.handle.br,
|
|
188
|
-
.handle.b,
|
|
189
|
-
.handle.bl {
|
|
190
|
-
bottom: var(--handle-corner-offset);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
.handle.l,
|
|
194
|
-
.handle.r {
|
|
195
|
-
bottom: var(--handle-mid-offset);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
.handle.t,
|
|
199
|
-
.handle.b {
|
|
200
|
-
left: var(--handle-mid-offset);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
.handle::before {
|
|
204
|
-
position: absolute;
|
|
205
|
-
content: "";
|
|
206
|
-
width: 20px;
|
|
207
|
-
height: 4px;
|
|
208
|
-
background: black;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
.handle::after {
|
|
212
|
-
position: absolute;
|
|
213
|
-
content: "";
|
|
214
|
-
width: 4px;
|
|
215
|
-
height: 20px;
|
|
216
|
-
background: black;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
.handle.t::before,
|
|
220
|
-
.handle.b::before {
|
|
221
|
-
width: 30px;
|
|
222
|
-
left: -14px;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
.handle.r::after,
|
|
226
|
-
.handle.l::after {
|
|
227
|
-
height: 30px;
|
|
228
|
-
top: -13px;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
.handle.l::before,
|
|
232
|
-
.handle.r::before {
|
|
233
|
-
content: none;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
.handle.t::after,
|
|
237
|
-
.handle.b::after {
|
|
238
|
-
content: none;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
.handle.tr::before,
|
|
242
|
-
.handle.br::before {
|
|
243
|
-
right: 4px;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
.handle.tl::before,
|
|
247
|
-
.handle.bl::before {
|
|
248
|
-
left: 4px;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
.handle.tl::after,
|
|
252
|
-
.handle.tr::after {
|
|
253
|
-
top: 4px;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
.handle.bl::after,
|
|
257
|
-
.handle.br::after {
|
|
258
|
-
bottom: 4px;
|
|
259
|
-
}
|
|
260
|
-
</style>
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
|
2
|
-
declare const __propDef: {
|
|
3
|
-
props: {
|
|
4
|
-
type?: string | undefined;
|
|
5
|
-
location: "tl" | "tr" | "bl" | "br" | "t" | "b" | "l" | "r";
|
|
6
|
-
x1?: number | undefined;
|
|
7
|
-
y1?: number | undefined;
|
|
8
|
-
x2?: number | undefined;
|
|
9
|
-
y2?: number | undefined;
|
|
10
|
-
dragging?: boolean | undefined;
|
|
11
|
-
};
|
|
12
|
-
events: {
|
|
13
|
-
change: CustomEvent<{
|
|
14
|
-
top: number | undefined;
|
|
15
|
-
bottom: number | undefined;
|
|
16
|
-
left: number | undefined;
|
|
17
|
-
right: number | undefined;
|
|
18
|
-
}>;
|
|
19
|
-
} & {
|
|
20
|
-
[evt: string]: CustomEvent<any>;
|
|
21
|
-
};
|
|
22
|
-
slots: {};
|
|
23
|
-
};
|
|
24
|
-
export type HandleProps = typeof __propDef.props;
|
|
25
|
-
export type HandleEvents = typeof __propDef.events;
|
|
26
|
-
export type HandleSlots = typeof __propDef.slots;
|
|
27
|
-
export default class Handle extends SvelteComponent<HandleProps, HandleEvents, HandleSlots> {
|
|
28
|
-
}
|
|
29
|
-
export {};
|
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
<script>import { getContext, onMount, tick, createEventDispatcher } from "svelte";
|
|
2
|
-
import { TOOL_KEY } from "./Tools.svelte";
|
|
3
|
-
import { EDITOR_KEY } from "../ImageEditor.svelte";
|
|
4
|
-
import {
|
|
5
|
-
Image as ImageIcon,
|
|
6
|
-
Webcam as WebcamIcon,
|
|
7
|
-
ImagePaste
|
|
8
|
-
} from "@gradio/icons";
|
|
9
|
-
import { Upload } from "@gradio/upload";
|
|
10
|
-
import { Webcam } from "@gradio/image";
|
|
11
|
-
import {} from "@gradio/utils";
|
|
12
|
-
import { default as IconButton } from "./IconButton.svelte";
|
|
13
|
-
import {} from "@gradio/client";
|
|
14
|
-
import { add_bg_color, add_bg_image } from "./sources";
|
|
15
|
-
export let background_file;
|
|
16
|
-
export let root;
|
|
17
|
-
export let sources = [
|
|
18
|
-
"upload",
|
|
19
|
-
"webcam",
|
|
20
|
-
"clipboard"
|
|
21
|
-
];
|
|
22
|
-
export let mirror_webcam = true;
|
|
23
|
-
export let i18n;
|
|
24
|
-
export let upload;
|
|
25
|
-
export let stream_handler;
|
|
26
|
-
export let dragging;
|
|
27
|
-
export let canvas_size;
|
|
28
|
-
export let fixed_canvas = false;
|
|
29
|
-
const { active_tool } = getContext(TOOL_KEY);
|
|
30
|
-
const { pixi, dimensions, register_context, reset, editor_box } = getContext(EDITOR_KEY);
|
|
31
|
-
export let active_mode = null;
|
|
32
|
-
let background;
|
|
33
|
-
const dispatch = createEventDispatcher();
|
|
34
|
-
const sources_meta = {
|
|
35
|
-
upload: {
|
|
36
|
-
icon: ImageIcon,
|
|
37
|
-
label: "Upload",
|
|
38
|
-
order: 0,
|
|
39
|
-
id: "bg_upload",
|
|
40
|
-
cb() {
|
|
41
|
-
upload_component.open_file_upload();
|
|
42
|
-
$active_tool = "bg";
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
webcam: {
|
|
46
|
-
icon: WebcamIcon,
|
|
47
|
-
label: "Webcam",
|
|
48
|
-
order: 1,
|
|
49
|
-
id: "bg_webcam",
|
|
50
|
-
cb() {
|
|
51
|
-
active_mode = "webcam";
|
|
52
|
-
$active_tool = "bg";
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
clipboard: {
|
|
56
|
-
icon: ImagePaste,
|
|
57
|
-
label: "Paste",
|
|
58
|
-
order: 2,
|
|
59
|
-
id: "bg_clipboard",
|
|
60
|
-
cb() {
|
|
61
|
-
process_clipboard();
|
|
62
|
-
$active_tool = null;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
$:
|
|
67
|
-
sources_list = sources.map((src) => sources_meta[src]).sort((a, b) => a.order - b.order);
|
|
68
|
-
let upload_component;
|
|
69
|
-
async function process_clipboard() {
|
|
70
|
-
const items = await navigator.clipboard.read();
|
|
71
|
-
for (let i = 0; i < items.length; i++) {
|
|
72
|
-
const type = items[i].types.find((t) => t.startsWith("image/"));
|
|
73
|
-
if (type) {
|
|
74
|
-
const blob = await items[i].getType(type);
|
|
75
|
-
background = blob || null;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
function handle_upload(e) {
|
|
80
|
-
const file_data = e.detail;
|
|
81
|
-
background = file_data;
|
|
82
|
-
active_mode = null;
|
|
83
|
-
}
|
|
84
|
-
let should_reset = true;
|
|
85
|
-
async function set_background() {
|
|
86
|
-
if (!$pixi)
|
|
87
|
-
return;
|
|
88
|
-
if (background) {
|
|
89
|
-
const add_image = add_bg_image(
|
|
90
|
-
$pixi.background_container,
|
|
91
|
-
$pixi.renderer,
|
|
92
|
-
background,
|
|
93
|
-
$pixi.resize,
|
|
94
|
-
canvas_size,
|
|
95
|
-
fixed_canvas
|
|
96
|
-
);
|
|
97
|
-
$dimensions = await add_image.start();
|
|
98
|
-
if (should_reset) {
|
|
99
|
-
reset(false, $dimensions);
|
|
100
|
-
}
|
|
101
|
-
add_image.execute();
|
|
102
|
-
should_reset = true;
|
|
103
|
-
await tick();
|
|
104
|
-
bg = true;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
async function process_bg_file(file) {
|
|
108
|
-
if (!file || !file.url)
|
|
109
|
-
return;
|
|
110
|
-
should_reset = false;
|
|
111
|
-
const blob_res = await fetch(file.url);
|
|
112
|
-
const blob = await blob_res.blob();
|
|
113
|
-
background = blob;
|
|
114
|
-
}
|
|
115
|
-
function handle_key(e) {
|
|
116
|
-
if (e.key === "Escape") {
|
|
117
|
-
active_mode = null;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
$:
|
|
121
|
-
background && set_background();
|
|
122
|
-
$:
|
|
123
|
-
process_bg_file(background_file);
|
|
124
|
-
export let bg = false;
|
|
125
|
-
register_context("bg", {
|
|
126
|
-
init_fn: () => {
|
|
127
|
-
if (!$pixi)
|
|
128
|
-
return;
|
|
129
|
-
const add_image = add_bg_color(
|
|
130
|
-
$pixi.background_container,
|
|
131
|
-
$pixi.renderer,
|
|
132
|
-
"black",
|
|
133
|
-
...$dimensions,
|
|
134
|
-
$pixi.resize
|
|
135
|
-
);
|
|
136
|
-
$dimensions = add_image.start();
|
|
137
|
-
add_image.execute();
|
|
138
|
-
},
|
|
139
|
-
reset_fn: () => {
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
</script>
|
|
143
|
-
|
|
144
|
-
<svelte:window on:keydown={handle_key} />
|
|
145
|
-
|
|
146
|
-
{#if sources.length}
|
|
147
|
-
<div class="source-wrap">
|
|
148
|
-
{#each sources_list as { icon, label, id, cb } (id)}
|
|
149
|
-
<IconButton
|
|
150
|
-
Icon={icon}
|
|
151
|
-
size="medium"
|
|
152
|
-
padded={false}
|
|
153
|
-
label={label + " button"}
|
|
154
|
-
hasPopup={true}
|
|
155
|
-
transparent={true}
|
|
156
|
-
on:click={cb}
|
|
157
|
-
/>
|
|
158
|
-
{/each}
|
|
159
|
-
<span class="sep"></span>
|
|
160
|
-
</div>
|
|
161
|
-
<div
|
|
162
|
-
class="upload-container"
|
|
163
|
-
class:click-disabled={!!bg ||
|
|
164
|
-
active_mode === "webcam" ||
|
|
165
|
-
$active_tool !== "bg"}
|
|
166
|
-
style:height="{Math.max(
|
|
167
|
-
$editor_box.child_height +
|
|
168
|
-
($editor_box.child_top - $editor_box.parent_top),
|
|
169
|
-
100
|
|
170
|
-
)}px"
|
|
171
|
-
>
|
|
172
|
-
<Upload
|
|
173
|
-
hidden={bg || active_mode === "webcam" || $active_tool !== "bg"}
|
|
174
|
-
bind:this={upload_component}
|
|
175
|
-
filetype="image/*"
|
|
176
|
-
on:load={handle_upload}
|
|
177
|
-
on:error
|
|
178
|
-
bind:dragging
|
|
179
|
-
{root}
|
|
180
|
-
disable_click={!sources.includes("upload")}
|
|
181
|
-
format="blob"
|
|
182
|
-
{upload}
|
|
183
|
-
{stream_handler}
|
|
184
|
-
></Upload>
|
|
185
|
-
{#if active_mode === "webcam"}
|
|
186
|
-
<div
|
|
187
|
-
class="modal"
|
|
188
|
-
style:max-width="{$editor_box.child_width}px"
|
|
189
|
-
style:max-height="{$editor_box.child_height}px"
|
|
190
|
-
style:top="{$editor_box.child_top - $editor_box.parent_top}px"
|
|
191
|
-
>
|
|
192
|
-
<div class="modal-inner">
|
|
193
|
-
<Webcam
|
|
194
|
-
{upload}
|
|
195
|
-
{root}
|
|
196
|
-
on:capture={handle_upload}
|
|
197
|
-
on:error
|
|
198
|
-
on:drag
|
|
199
|
-
{mirror_webcam}
|
|
200
|
-
streaming={false}
|
|
201
|
-
mode="image"
|
|
202
|
-
include_audio={false}
|
|
203
|
-
{i18n}
|
|
204
|
-
/>
|
|
205
|
-
</div>
|
|
206
|
-
</div>
|
|
207
|
-
{/if}
|
|
208
|
-
</div>
|
|
209
|
-
{/if}
|
|
210
|
-
|
|
211
|
-
<style>
|
|
212
|
-
.modal {
|
|
213
|
-
position: absolute;
|
|
214
|
-
height: 100%;
|
|
215
|
-
width: 100%;
|
|
216
|
-
left: 0;
|
|
217
|
-
right: 0;
|
|
218
|
-
margin: auto;
|
|
219
|
-
z-index: var(--layer-top);
|
|
220
|
-
display: flex;
|
|
221
|
-
align-items: center;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
.modal-inner {
|
|
225
|
-
width: 100%;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
.sep {
|
|
229
|
-
height: 12px;
|
|
230
|
-
background-color: var(--block-border-color);
|
|
231
|
-
width: 1px;
|
|
232
|
-
display: block;
|
|
233
|
-
margin-left: var(--spacing-xl);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
.source-wrap {
|
|
237
|
-
display: flex;
|
|
238
|
-
justify-content: center;
|
|
239
|
-
align-items: center;
|
|
240
|
-
margin-left: var(--spacing-lg);
|
|
241
|
-
height: 100%;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
.upload-container {
|
|
245
|
-
position: absolute;
|
|
246
|
-
height: 100%;
|
|
247
|
-
flex-shrink: 1;
|
|
248
|
-
max-height: 100%;
|
|
249
|
-
width: 100%;
|
|
250
|
-
left: 0;
|
|
251
|
-
top: 0;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
.upload-container.click-disabled {
|
|
255
|
-
pointer-events: none;
|
|
256
|
-
}
|
|
257
|
-
</style>
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
|
2
|
-
import { type I18nFormatter } from "@gradio/utils";
|
|
3
|
-
import { type Client } from "@gradio/client";
|
|
4
|
-
import type { FileData } from "@gradio/client";
|
|
5
|
-
declare const __propDef: {
|
|
6
|
-
props: {
|
|
7
|
-
background_file: FileData | null;
|
|
8
|
-
root: string;
|
|
9
|
-
sources?: ("upload" | "webcam" | "clipboard")[] | undefined;
|
|
10
|
-
mirror_webcam?: boolean | undefined;
|
|
11
|
-
i18n: I18nFormatter;
|
|
12
|
-
upload: Client["upload"];
|
|
13
|
-
stream_handler: Client["stream"];
|
|
14
|
-
dragging: boolean;
|
|
15
|
-
canvas_size: [number, number];
|
|
16
|
-
fixed_canvas?: boolean | undefined;
|
|
17
|
-
active_mode?: ("webcam" | "color" | null) | undefined;
|
|
18
|
-
bg?: boolean | undefined;
|
|
19
|
-
};
|
|
20
|
-
events: {
|
|
21
|
-
error: CustomEvent<any> | CustomEvent<string>;
|
|
22
|
-
drag: CustomEvent<any>;
|
|
23
|
-
upload: CustomEvent<never>;
|
|
24
|
-
} & {
|
|
25
|
-
[evt: string]: CustomEvent<any>;
|
|
26
|
-
};
|
|
27
|
-
slots: {};
|
|
28
|
-
};
|
|
29
|
-
export type SourcesProps = typeof __propDef.props;
|
|
30
|
-
export type SourcesEvents = typeof __propDef.events;
|
|
31
|
-
export type SourcesSlots = typeof __propDef.slots;
|
|
32
|
-
export default class Sources extends SvelteComponent<SourcesProps, SourcesEvents, SourcesSlots> {
|
|
33
|
-
}
|
|
34
|
-
export {};
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
<script context="module">export const TOOL_KEY = Symbol("tool");
|
|
2
|
-
</script>
|
|
3
|
-
|
|
4
|
-
<script>import { Toolbar } from "@gradio/atoms";
|
|
5
|
-
import { default as IconButton } from "./IconButton.svelte";
|
|
6
|
-
import { getContext, setContext } from "svelte";
|
|
7
|
-
import { writable } from "svelte/store";
|
|
8
|
-
import { EDITOR_KEY } from "../ImageEditor.svelte";
|
|
9
|
-
import { Image, Crop, Brush, Erase } from "@gradio/icons";
|
|
10
|
-
import {} from "@gradio/utils";
|
|
11
|
-
const { active_tool, toolbar_box, editor_box } = getContext(EDITOR_KEY);
|
|
12
|
-
export let i18n;
|
|
13
|
-
let tools = [];
|
|
14
|
-
const cbs = {};
|
|
15
|
-
let current_color = writable("#000000");
|
|
16
|
-
const tool_context = {
|
|
17
|
-
current_color,
|
|
18
|
-
register_tool: (type, opts) => {
|
|
19
|
-
tools = [...tools, type];
|
|
20
|
-
if (opts?.cb) {
|
|
21
|
-
cbs[type] = opts.cb;
|
|
22
|
-
}
|
|
23
|
-
return () => {
|
|
24
|
-
tools = tools.filter((tool) => tool !== type);
|
|
25
|
-
};
|
|
26
|
-
},
|
|
27
|
-
active_tool: {
|
|
28
|
-
subscribe: active_tool.subscribe,
|
|
29
|
-
set: active_tool.set
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
setContext(TOOL_KEY, tool_context);
|
|
33
|
-
const tools_meta = {
|
|
34
|
-
crop: {
|
|
35
|
-
order: 1,
|
|
36
|
-
label: i18n("Transform"),
|
|
37
|
-
icon: Crop
|
|
38
|
-
},
|
|
39
|
-
draw: {
|
|
40
|
-
order: 2,
|
|
41
|
-
label: i18n("Draw"),
|
|
42
|
-
icon: Brush
|
|
43
|
-
},
|
|
44
|
-
erase: {
|
|
45
|
-
order: 2,
|
|
46
|
-
label: i18n("Erase"),
|
|
47
|
-
icon: Erase
|
|
48
|
-
},
|
|
49
|
-
bg: {
|
|
50
|
-
order: 0,
|
|
51
|
-
label: i18n("Background"),
|
|
52
|
-
icon: Image
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
let toolbar_width;
|
|
56
|
-
let toolbar_wrap;
|
|
57
|
-
$:
|
|
58
|
-
toolbar_width, $editor_box, get_dimensions();
|
|
59
|
-
function get_dimensions() {
|
|
60
|
-
if (!toolbar_wrap)
|
|
61
|
-
return;
|
|
62
|
-
$toolbar_box = toolbar_wrap.getBoundingClientRect();
|
|
63
|
-
}
|
|
64
|
-
function handle_click(e, tool) {
|
|
65
|
-
e.stopPropagation();
|
|
66
|
-
$active_tool = tool;
|
|
67
|
-
cbs[tool] && cbs[tool]();
|
|
68
|
-
}
|
|
69
|
-
</script>
|
|
70
|
-
|
|
71
|
-
<slot />
|
|
72
|
-
|
|
73
|
-
<div
|
|
74
|
-
class="toolbar-wrap"
|
|
75
|
-
bind:clientWidth={toolbar_width}
|
|
76
|
-
bind:this={toolbar_wrap}
|
|
77
|
-
>
|
|
78
|
-
<Toolbar show_border={false}>
|
|
79
|
-
{#each tools as tool (tool)}
|
|
80
|
-
<IconButton
|
|
81
|
-
highlight={$active_tool === tool}
|
|
82
|
-
on:click={(e) => handle_click(e, tool)}
|
|
83
|
-
Icon={tools_meta[tool].icon}
|
|
84
|
-
size="medium"
|
|
85
|
-
padded={false}
|
|
86
|
-
label={tools_meta[tool].label + " button"}
|
|
87
|
-
transparent={true}
|
|
88
|
-
offset={tool === "draw" ? -2 : tool === "erase" ? -6 : 0}
|
|
89
|
-
/>
|
|
90
|
-
{/each}
|
|
91
|
-
</Toolbar>
|
|
92
|
-
</div>
|
|
93
|
-
|
|
94
|
-
<style>
|
|
95
|
-
.toolbar-wrap {
|
|
96
|
-
display: flex;
|
|
97
|
-
justify-content: center;
|
|
98
|
-
align-items: center;
|
|
99
|
-
margin-left: var(--spacing-xl);
|
|
100
|
-
height: 100%;
|
|
101
|
-
}
|
|
102
|
-
</style>
|