@gradio/imageeditor 0.12.13 → 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 +23 -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 +11 -10
- 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,35 @@
|
|
|
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
|
+
}[];
|
|
12
|
+
}>;
|
|
13
|
+
enable_additional_layers?: boolean | undefined;
|
|
14
|
+
enable_layers?: boolean | undefined;
|
|
15
|
+
show_layers?: boolean | undefined;
|
|
16
|
+
};
|
|
17
|
+
events: {
|
|
18
|
+
new_layer: CustomEvent<void>;
|
|
19
|
+
change_layer: CustomEvent<string>;
|
|
20
|
+
move_layer: CustomEvent<{
|
|
21
|
+
id: string;
|
|
22
|
+
direction: "up" | "down";
|
|
23
|
+
}>;
|
|
24
|
+
delete_layer: CustomEvent<string>;
|
|
25
|
+
} & {
|
|
26
|
+
[evt: string]: CustomEvent<any>;
|
|
27
|
+
};
|
|
28
|
+
slots: {};
|
|
29
|
+
};
|
|
30
|
+
export type SecondaryToolbarProps = typeof __propDef.props;
|
|
31
|
+
export type SecondaryToolbarEvents = typeof __propDef.events;
|
|
32
|
+
export type SecondaryToolbarSlots = typeof __propDef.slots;
|
|
33
|
+
export default class SecondaryToolbar extends SvelteComponent<SecondaryToolbarProps, SecondaryToolbarEvents, SecondaryToolbarSlots> {
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
<script context="module"></script>
|
|
2
|
+
|
|
3
|
+
<script>import { createEventDispatcher } from "svelte";
|
|
4
|
+
import IconButton from "./IconButton.svelte";
|
|
5
|
+
import {
|
|
6
|
+
Image,
|
|
7
|
+
Brush,
|
|
8
|
+
Erase,
|
|
9
|
+
Crop,
|
|
10
|
+
Upload,
|
|
11
|
+
ImagePaste,
|
|
12
|
+
Webcam,
|
|
13
|
+
Circle,
|
|
14
|
+
Resize,
|
|
15
|
+
ColorPickerSolid
|
|
16
|
+
} from "@gradio/icons";
|
|
17
|
+
import BrushOptions from "./brush/BrushOptions.svelte";
|
|
18
|
+
import {
|
|
19
|
+
} from "./brush/types";
|
|
20
|
+
import tinycolor from "tinycolor2";
|
|
21
|
+
export let tool = "image";
|
|
22
|
+
export let subtool = null;
|
|
23
|
+
export let background = false;
|
|
24
|
+
export let brush_options;
|
|
25
|
+
export let selected_size = brush_options && typeof brush_options.default_size === "number" ? brush_options.default_size : 25;
|
|
26
|
+
export let eraser_options;
|
|
27
|
+
export let selected_eraser_size = eraser_options && typeof eraser_options.default_size === "number" ? eraser_options.default_size : 25;
|
|
28
|
+
export let selected_color = brush_options && (() => {
|
|
29
|
+
const default_color = brush_options.default_color;
|
|
30
|
+
if (Array.isArray(default_color)) {
|
|
31
|
+
return default_color[0];
|
|
32
|
+
}
|
|
33
|
+
return default_color;
|
|
34
|
+
})();
|
|
35
|
+
export let selected_opacity = brush_options && (() => {
|
|
36
|
+
const default_color = brush_options.default_color;
|
|
37
|
+
if (Array.isArray(default_color)) {
|
|
38
|
+
return default_color[1];
|
|
39
|
+
}
|
|
40
|
+
const color = tinycolor(default_color);
|
|
41
|
+
if (color.getAlpha() < 1) {
|
|
42
|
+
return color.getAlpha();
|
|
43
|
+
}
|
|
44
|
+
return 1;
|
|
45
|
+
})();
|
|
46
|
+
export let preview = false;
|
|
47
|
+
export let show_brush_color = false;
|
|
48
|
+
export let show_brush_size = false;
|
|
49
|
+
export let show_eraser_size = false;
|
|
50
|
+
export let sources;
|
|
51
|
+
export let transforms;
|
|
52
|
+
let recent_colors = [];
|
|
53
|
+
let enable_layers = true;
|
|
54
|
+
const dispatch = createEventDispatcher();
|
|
55
|
+
function handle_tool_click(e, _tool) {
|
|
56
|
+
e.stopPropagation();
|
|
57
|
+
dispatch("tool_change", { tool: _tool });
|
|
58
|
+
}
|
|
59
|
+
function handle_subtool_click(e, _subtool) {
|
|
60
|
+
e.stopPropagation();
|
|
61
|
+
dispatch("subtool_change", { tool, subtool: _subtool });
|
|
62
|
+
}
|
|
63
|
+
$:
|
|
64
|
+
show_brush_size = tool === "draw" && subtool === "size";
|
|
65
|
+
$:
|
|
66
|
+
show_brush_color = tool === "draw" && subtool === "color";
|
|
67
|
+
$:
|
|
68
|
+
show_eraser_size = tool === "erase" && subtool === "size";
|
|
69
|
+
$:
|
|
70
|
+
can_crop = transforms.includes("crop");
|
|
71
|
+
$:
|
|
72
|
+
can_resize = transforms.includes("resize");
|
|
73
|
+
$:
|
|
74
|
+
can_upload = sources.includes("upload");
|
|
75
|
+
$:
|
|
76
|
+
can_webcam = sources.includes("webcam");
|
|
77
|
+
$:
|
|
78
|
+
can_paste = sources.includes("clipboard");
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<div class="toolbar-wrap">
|
|
82
|
+
<div class="half-container">
|
|
83
|
+
{#if sources.length > 0}
|
|
84
|
+
<IconButton
|
|
85
|
+
Icon={Image}
|
|
86
|
+
label="Image"
|
|
87
|
+
highlight={tool === "image"}
|
|
88
|
+
on:click={(e) => handle_tool_click(e, "image")}
|
|
89
|
+
size="medium"
|
|
90
|
+
padded={false}
|
|
91
|
+
transparent={true}
|
|
92
|
+
/>
|
|
93
|
+
{/if}
|
|
94
|
+
{#if brush_options}
|
|
95
|
+
<IconButton
|
|
96
|
+
Icon={Brush}
|
|
97
|
+
label="Brush"
|
|
98
|
+
on:click={(e) => handle_tool_click(e, "draw")}
|
|
99
|
+
highlight={tool === "draw"}
|
|
100
|
+
size="medium"
|
|
101
|
+
padded={false}
|
|
102
|
+
transparent={true}
|
|
103
|
+
/>
|
|
104
|
+
{/if}
|
|
105
|
+
{#if eraser_options}
|
|
106
|
+
<IconButton
|
|
107
|
+
Icon={Erase}
|
|
108
|
+
label="Erase"
|
|
109
|
+
on:click={(e) => handle_tool_click(e, "erase")}
|
|
110
|
+
highlight={tool === "erase"}
|
|
111
|
+
size="medium"
|
|
112
|
+
padded={false}
|
|
113
|
+
transparent={true}
|
|
114
|
+
/>
|
|
115
|
+
{/if}
|
|
116
|
+
</div>
|
|
117
|
+
<div
|
|
118
|
+
class="half-container right"
|
|
119
|
+
class:hide={tool === "pan" ||
|
|
120
|
+
(tool === "image" && !background && sources.length === 0) ||
|
|
121
|
+
(tool === "image" && background && transforms.length === 0)}
|
|
122
|
+
>
|
|
123
|
+
{#if tool === "image"}
|
|
124
|
+
{#if background}
|
|
125
|
+
{#if can_crop}
|
|
126
|
+
<IconButton
|
|
127
|
+
Icon={Crop}
|
|
128
|
+
label="Crop"
|
|
129
|
+
on:click={(e) => handle_subtool_click(e, "crop")}
|
|
130
|
+
highlight={subtool === "crop"}
|
|
131
|
+
size="medium"
|
|
132
|
+
padded={false}
|
|
133
|
+
transparent={true}
|
|
134
|
+
offset={0}
|
|
135
|
+
/>
|
|
136
|
+
{/if}
|
|
137
|
+
{#if can_resize}
|
|
138
|
+
<IconButton
|
|
139
|
+
Icon={Resize}
|
|
140
|
+
label="Resize"
|
|
141
|
+
on:click={(e) => handle_subtool_click(e, "size")}
|
|
142
|
+
highlight={subtool === "size"}
|
|
143
|
+
size="medium"
|
|
144
|
+
padded={false}
|
|
145
|
+
transparent={true}
|
|
146
|
+
offset={0}
|
|
147
|
+
/>
|
|
148
|
+
{/if}
|
|
149
|
+
{:else}
|
|
150
|
+
{#if can_upload}
|
|
151
|
+
<IconButton
|
|
152
|
+
Icon={Upload}
|
|
153
|
+
label="Upload"
|
|
154
|
+
on:click={(e) => handle_subtool_click(e, "upload")}
|
|
155
|
+
highlight={subtool === "upload"}
|
|
156
|
+
size="medium"
|
|
157
|
+
padded={false}
|
|
158
|
+
transparent={true}
|
|
159
|
+
offset={0}
|
|
160
|
+
/>
|
|
161
|
+
{/if}
|
|
162
|
+
{#if can_paste}
|
|
163
|
+
<IconButton
|
|
164
|
+
Icon={ImagePaste}
|
|
165
|
+
label="Paste"
|
|
166
|
+
on:click={(e) => handle_subtool_click(e, "paste")}
|
|
167
|
+
highlight={subtool === "paste"}
|
|
168
|
+
size="large"
|
|
169
|
+
padded={false}
|
|
170
|
+
transparent={true}
|
|
171
|
+
offset={0}
|
|
172
|
+
/>
|
|
173
|
+
{/if}
|
|
174
|
+
{#if can_webcam}
|
|
175
|
+
<IconButton
|
|
176
|
+
Icon={Webcam}
|
|
177
|
+
label="Webcam"
|
|
178
|
+
on:click={(e) => handle_subtool_click(e, "webcam")}
|
|
179
|
+
highlight={subtool === "webcam"}
|
|
180
|
+
size="medium"
|
|
181
|
+
padded={false}
|
|
182
|
+
transparent={true}
|
|
183
|
+
offset={0}
|
|
184
|
+
/>
|
|
185
|
+
{/if}
|
|
186
|
+
{/if}
|
|
187
|
+
{/if}
|
|
188
|
+
|
|
189
|
+
{#if tool === "draw" && brush_options}
|
|
190
|
+
<IconButton
|
|
191
|
+
Icon={ColorPickerSolid}
|
|
192
|
+
label="Color"
|
|
193
|
+
color={selected_color}
|
|
194
|
+
on:click={(e) => handle_subtool_click(e, "color")}
|
|
195
|
+
size="medium"
|
|
196
|
+
padded={false}
|
|
197
|
+
transparent={true}
|
|
198
|
+
offset={0}
|
|
199
|
+
/>
|
|
200
|
+
<IconButton
|
|
201
|
+
Icon={Circle}
|
|
202
|
+
label="Brush Size"
|
|
203
|
+
on:click={(e) => handle_subtool_click(e, "size")}
|
|
204
|
+
highlight={subtool === "size"}
|
|
205
|
+
size="medium"
|
|
206
|
+
padded={false}
|
|
207
|
+
transparent={true}
|
|
208
|
+
offset={0}
|
|
209
|
+
/>
|
|
210
|
+
|
|
211
|
+
{#if show_brush_color || show_brush_size}
|
|
212
|
+
<BrushOptions
|
|
213
|
+
colors={brush_options.colors}
|
|
214
|
+
color_mode={brush_options.color_mode}
|
|
215
|
+
{recent_colors}
|
|
216
|
+
show_swatch={show_brush_color}
|
|
217
|
+
show_size={show_brush_size}
|
|
218
|
+
bind:selected_size
|
|
219
|
+
bind:selected_color
|
|
220
|
+
bind:selected_opacity
|
|
221
|
+
bind:preview
|
|
222
|
+
on:click_outside={(e) => {
|
|
223
|
+
e.stopPropagation();
|
|
224
|
+
preview = false;
|
|
225
|
+
show_brush_color = false;
|
|
226
|
+
show_brush_size = false;
|
|
227
|
+
handle_subtool_click(e, null);
|
|
228
|
+
}}
|
|
229
|
+
mode="brush"
|
|
230
|
+
/>
|
|
231
|
+
{/if}
|
|
232
|
+
{/if}
|
|
233
|
+
|
|
234
|
+
{#if tool === "erase" && eraser_options}
|
|
235
|
+
<IconButton
|
|
236
|
+
Icon={Circle}
|
|
237
|
+
label="Eraser Size"
|
|
238
|
+
on:click={(e) => handle_subtool_click(e, "size")}
|
|
239
|
+
highlight={subtool === "size"}
|
|
240
|
+
size="medium"
|
|
241
|
+
padded={false}
|
|
242
|
+
transparent={true}
|
|
243
|
+
offset={0}
|
|
244
|
+
/>
|
|
245
|
+
{/if}
|
|
246
|
+
{#if show_eraser_size}
|
|
247
|
+
<BrushOptions
|
|
248
|
+
colors={[]}
|
|
249
|
+
show_swatch={false}
|
|
250
|
+
show_size={true}
|
|
251
|
+
bind:selected_size={selected_eraser_size}
|
|
252
|
+
bind:selected_color
|
|
253
|
+
bind:selected_opacity
|
|
254
|
+
bind:preview
|
|
255
|
+
on:click_outside={(e) => {
|
|
256
|
+
e.stopPropagation();
|
|
257
|
+
preview = false;
|
|
258
|
+
show_eraser_size = false;
|
|
259
|
+
handle_subtool_click(e, null);
|
|
260
|
+
}}
|
|
261
|
+
mode="eraser"
|
|
262
|
+
/>
|
|
263
|
+
{/if}
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
|
|
267
|
+
<style>
|
|
268
|
+
.toolbar-wrap {
|
|
269
|
+
display: inline-flex;
|
|
270
|
+
flex-direction: column;
|
|
271
|
+
justify-content: center;
|
|
272
|
+
align-items: center;
|
|
273
|
+
position: absolute;
|
|
274
|
+
left: 15px;
|
|
275
|
+
right: 0;
|
|
276
|
+
top: 30%;
|
|
277
|
+
/* transform: translateY(-50%); */
|
|
278
|
+
width: 30px;
|
|
279
|
+
border: 1px solid var(--block-border-color);
|
|
280
|
+
border-radius: var(--radius-md);
|
|
281
|
+
|
|
282
|
+
gap: var(--spacing-sm);
|
|
283
|
+
z-index: 1000;
|
|
284
|
+
background-color: var(--block-background-fill);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.half-container {
|
|
288
|
+
flex: 1;
|
|
289
|
+
display: flex;
|
|
290
|
+
flex-direction: column;
|
|
291
|
+
gap: var(--spacing-sm);
|
|
292
|
+
position: relative;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.half-container {
|
|
296
|
+
width: 100%;
|
|
297
|
+
padding: var(--spacing-sm) 0;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.half-container:last-child {
|
|
301
|
+
border-top: 1px solid var(--block-border-color);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.hide {
|
|
305
|
+
display: none;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/* .toolbar-left,
|
|
309
|
+
.toolbar-right {
|
|
310
|
+
display: flex;
|
|
311
|
+
flex-direction: row;
|
|
312
|
+
align-items: center;
|
|
313
|
+
gap: var(--spacing-sm);
|
|
314
|
+
display: flex;
|
|
315
|
+
z-index: 1000;
|
|
316
|
+
border-radius: var(--radius-sm);
|
|
317
|
+
background-color: #fff;
|
|
318
|
+
padding: var(--spacing-sm) 0.3rem;
|
|
319
|
+
width: auto;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.toolbar-right {
|
|
323
|
+
border-left: 0;
|
|
324
|
+
border-top-left-radius: 0;
|
|
325
|
+
border-bottom-left-radius: 0;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.toolbar-left {
|
|
329
|
+
border-top-right-radius: 0;
|
|
330
|
+
border-bottom-right-radius: 0;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.toolbar-layers {
|
|
334
|
+
border-top-left-radius: 0;
|
|
335
|
+
border-bottom-left-radius: 0;
|
|
336
|
+
} */
|
|
337
|
+
</style>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
export type Tool = "image" | "draw" | "erase" | "pan";
|
|
3
|
+
export type Subtool = "upload" | "paste" | "webcam" | "color" | "size" | "crop" | "remove_background" | null;
|
|
4
|
+
import type { Source, Transform } from "./types";
|
|
5
|
+
import { type Brush as BrushType, type Eraser as EraserType } from "./brush/types";
|
|
6
|
+
declare const __propDef: {
|
|
7
|
+
props: {
|
|
8
|
+
tool?: Tool | undefined;
|
|
9
|
+
subtool?: Subtool | undefined;
|
|
10
|
+
background?: boolean | undefined;
|
|
11
|
+
brush_options: BrushType | false;
|
|
12
|
+
selected_size?: number | undefined;
|
|
13
|
+
eraser_options: EraserType;
|
|
14
|
+
selected_eraser_size?: number | undefined;
|
|
15
|
+
selected_color?: any;
|
|
16
|
+
selected_opacity?: any;
|
|
17
|
+
preview?: boolean | undefined;
|
|
18
|
+
show_brush_color?: boolean | undefined;
|
|
19
|
+
show_brush_size?: boolean | undefined;
|
|
20
|
+
show_eraser_size?: boolean | undefined;
|
|
21
|
+
sources: Source[];
|
|
22
|
+
transforms: Transform[];
|
|
23
|
+
};
|
|
24
|
+
events: {
|
|
25
|
+
tool_change: CustomEvent<{
|
|
26
|
+
tool: Tool;
|
|
27
|
+
}>;
|
|
28
|
+
subtool_change: CustomEvent<{
|
|
29
|
+
tool: Tool;
|
|
30
|
+
subtool: Subtool;
|
|
31
|
+
}>;
|
|
32
|
+
} & {
|
|
33
|
+
[evt: string]: CustomEvent<any>;
|
|
34
|
+
};
|
|
35
|
+
slots: {};
|
|
36
|
+
};
|
|
37
|
+
export type ToolbarProps = typeof __propDef.props;
|
|
38
|
+
export type ToolbarEvents = typeof __propDef.events;
|
|
39
|
+
export type ToolbarSlots = typeof __propDef.slots;
|
|
40
|
+
export default class Toolbar extends SvelteComponent<ToolbarProps, ToolbarEvents, ToolbarSlots> {
|
|
41
|
+
}
|
|
42
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<script>import { createEventDispatcher } from "svelte";
|
|
1
|
+
<script>import { createEventDispatcher, tick } from "svelte";
|
|
2
2
|
import { click_outside } from "../utils/events";
|
|
3
|
-
import {} from "./
|
|
3
|
+
import {} from "./types";
|
|
4
4
|
import ColorPicker from "./ColorPicker.svelte";
|
|
5
5
|
import ColorSwatch from "./ColorSwatch.svelte";
|
|
6
6
|
import ColorField from "./ColorField.svelte";
|
|
@@ -10,19 +10,18 @@ export let selected_color;
|
|
|
10
10
|
export let color_mode = void 0;
|
|
11
11
|
export let recent_colors = [];
|
|
12
12
|
export let selected_size;
|
|
13
|
-
export let
|
|
14
|
-
export let parent_width;
|
|
15
|
-
export let parent_height;
|
|
16
|
-
export let parent_left;
|
|
17
|
-
export let toolbar_box;
|
|
13
|
+
export let selected_opacity;
|
|
18
14
|
export let show_swatch;
|
|
15
|
+
export let show_size;
|
|
16
|
+
export let mode = "brush";
|
|
19
17
|
let color_picker = false;
|
|
20
18
|
let current_mode = "hex";
|
|
21
19
|
let editing_index = null;
|
|
22
20
|
const dispatch = createEventDispatcher();
|
|
23
21
|
function handle_color_selection({
|
|
24
22
|
index,
|
|
25
|
-
color
|
|
23
|
+
color,
|
|
24
|
+
opacity
|
|
26
25
|
}, type) {
|
|
27
26
|
if (type === "user" && !color) {
|
|
28
27
|
editing_index = index;
|
|
@@ -31,6 +30,9 @@ function handle_color_selection({
|
|
|
31
30
|
if (!color)
|
|
32
31
|
return;
|
|
33
32
|
selected_color = color;
|
|
33
|
+
if (opacity !== void 0) {
|
|
34
|
+
selected_opacity = opacity;
|
|
35
|
+
}
|
|
34
36
|
if (type === "core") {
|
|
35
37
|
color_picker = false;
|
|
36
38
|
}
|
|
@@ -44,30 +46,45 @@ $:
|
|
|
44
46
|
handle_color_change(selected_color);
|
|
45
47
|
let width = 0;
|
|
46
48
|
let height = 0;
|
|
47
|
-
|
|
48
|
-
let
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
49
|
+
function debounce(func, delay) {
|
|
50
|
+
let timeout;
|
|
51
|
+
return function(...args) {
|
|
52
|
+
clearTimeout(timeout);
|
|
53
|
+
timeout = setTimeout(() => func(...args), delay);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export let preview = false;
|
|
57
|
+
function handle_preview() {
|
|
58
|
+
if (!preview) {
|
|
59
|
+
preview = true;
|
|
60
|
+
debounced_close_preview();
|
|
61
|
+
} else {
|
|
62
|
+
debounced_close_preview();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function handle_close_preview() {
|
|
66
|
+
preview = false;
|
|
67
|
+
}
|
|
68
|
+
const debounced_close_preview = debounce(handle_close_preview, 1e3);
|
|
69
|
+
$:
|
|
70
|
+
selected_size, selected_color, handle_preview();
|
|
71
|
+
function handle_select(color) {
|
|
72
|
+
selected_color = color;
|
|
73
|
+
}
|
|
74
|
+
function handle_add_color() {
|
|
75
|
+
if (recent_colors.length >= 5) {
|
|
76
|
+
recent_colors.pop();
|
|
77
|
+
}
|
|
78
|
+
if (recent_colors.some((color) => {
|
|
79
|
+
if (Array.isArray(color)) {
|
|
80
|
+
return color[0] === selected_color && color[1] === selected_opacity;
|
|
69
81
|
}
|
|
82
|
+
return color === selected_color;
|
|
83
|
+
})) {
|
|
84
|
+
return;
|
|
70
85
|
}
|
|
86
|
+
recent_colors.push([selected_color, selected_opacity]);
|
|
87
|
+
recent_colors = recent_colors;
|
|
71
88
|
}
|
|
72
89
|
</script>
|
|
73
90
|
|
|
@@ -77,22 +94,21 @@ $: {
|
|
|
77
94
|
class="wrap"
|
|
78
95
|
class:padded={!color_picker}
|
|
79
96
|
use:click_outside={() => dispatch("click_outside")}
|
|
80
|
-
class:
|
|
81
|
-
class:
|
|
82
|
-
class:
|
|
83
|
-
bind:this={wrap_el}
|
|
84
|
-
bind:clientWidth={c_width}
|
|
85
|
-
bind:clientHeight={c_height}
|
|
86
|
-
class:anchor={`${left_anchor}px`}
|
|
97
|
+
class:color_picker
|
|
98
|
+
class:size_picker={show_size && mode === "brush"}
|
|
99
|
+
class:eraser_picker={mode === "eraser"}
|
|
87
100
|
>
|
|
88
101
|
{#if color_mode === "defaults"}
|
|
89
102
|
{#if color_picker}
|
|
90
|
-
<ColorPicker
|
|
103
|
+
<ColorPicker
|
|
104
|
+
bind:color={selected_color}
|
|
105
|
+
bind:opacity={selected_opacity}
|
|
106
|
+
/>
|
|
91
107
|
<ColorField
|
|
92
108
|
bind:current_mode
|
|
93
109
|
color={selected_color}
|
|
94
110
|
on:close={() => (color_picker = false)}
|
|
95
|
-
on:selected={({ detail }) => (
|
|
111
|
+
on:selected={({ detail }) => handle_select(detail)}
|
|
96
112
|
/>
|
|
97
113
|
{/if}
|
|
98
114
|
{/if}
|
|
@@ -105,20 +121,19 @@ $: {
|
|
|
105
121
|
user_colors={color_mode === "defaults" ? recent_colors : null}
|
|
106
122
|
{selected_color}
|
|
107
123
|
{current_mode}
|
|
124
|
+
on:add_color={handle_add_color}
|
|
108
125
|
/>
|
|
109
126
|
{/if}
|
|
110
127
|
|
|
111
|
-
{#if
|
|
112
|
-
<
|
|
128
|
+
{#if show_size}
|
|
129
|
+
<BrushSize max={100} min={1} bind:selected_size />
|
|
113
130
|
{/if}
|
|
114
|
-
|
|
115
|
-
<BrushSize max={dimensions[0] / 10} min={1} bind:selected_size />
|
|
116
131
|
</div>
|
|
117
132
|
|
|
118
133
|
<style>
|
|
119
134
|
.wrap {
|
|
120
135
|
max-width: 230px;
|
|
121
|
-
width: 90%;
|
|
136
|
+
/* width: 90%; */
|
|
122
137
|
position: absolute;
|
|
123
138
|
display: flex;
|
|
124
139
|
flex-direction: column;
|
|
@@ -132,31 +147,20 @@ $: {
|
|
|
132
147
|
cursor: default;
|
|
133
148
|
z-index: var(--layer-top);
|
|
134
149
|
overflow: hidden;
|
|
135
|
-
|
|
150
|
+
top: 0;
|
|
136
151
|
|
|
137
|
-
|
|
138
|
-
position: absolute;
|
|
139
|
-
left: var(--left-anchor);
|
|
140
|
-
bottom: 8px;
|
|
152
|
+
transform: translate(35px, -12px);
|
|
141
153
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
left: 50%;
|
|
146
|
-
transform: translateX(-50%);
|
|
154
|
+
|
|
155
|
+
.color_picker {
|
|
156
|
+
transform: translate(35px, -50%);
|
|
147
157
|
}
|
|
148
158
|
|
|
149
|
-
.
|
|
150
|
-
|
|
151
|
-
top: 1px;
|
|
152
|
-
left: 50%;
|
|
153
|
-
transform: translateX(-50%);
|
|
159
|
+
.size_picker {
|
|
160
|
+
transform: translate(35px, 18px);
|
|
154
161
|
}
|
|
155
162
|
|
|
156
|
-
.
|
|
157
|
-
|
|
158
|
-
background-color: var(--block-border-color);
|
|
159
|
-
margin: 0 var(--size-3);
|
|
160
|
-
margin-top: var(--size-1);
|
|
163
|
+
.eraser_picker {
|
|
164
|
+
transform: translate(35px, -7px);
|
|
161
165
|
}
|
|
162
166
|
</style>
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
-
import { type Brush } from "./
|
|
2
|
+
import { type Brush, type ColorTuple } from "./types";
|
|
3
|
+
import type { ColorInput } from "tinycolor2";
|
|
3
4
|
declare const __propDef: {
|
|
4
5
|
props: {
|
|
5
|
-
colors:
|
|
6
|
-
selected_color:
|
|
6
|
+
colors: (ColorInput | ColorTuple)[];
|
|
7
|
+
selected_color: any;
|
|
7
8
|
color_mode?: Brush["color_mode"] | undefined;
|
|
8
|
-
recent_colors?: (
|
|
9
|
+
recent_colors?: (ColorInput | ColorTuple)[] | undefined;
|
|
9
10
|
selected_size: number;
|
|
10
|
-
|
|
11
|
-
parent_width: number;
|
|
12
|
-
parent_height: number;
|
|
13
|
-
parent_left: number;
|
|
14
|
-
toolbar_box: DOMRect | Record<string, never>;
|
|
11
|
+
selected_opacity: number;
|
|
15
12
|
show_swatch: boolean;
|
|
13
|
+
show_size: boolean;
|
|
14
|
+
mode?: ("brush" | "eraser") | undefined;
|
|
15
|
+
preview?: boolean | undefined;
|
|
16
16
|
};
|
|
17
17
|
events: {
|
|
18
18
|
click_outside: CustomEvent<void>;
|
|
@@ -5,34 +5,9 @@ export let selected_size;
|
|
|
5
5
|
export let min;
|
|
6
6
|
export let max;
|
|
7
7
|
const dispatch = createEventDispatcher();
|
|
8
|
-
let width = 0;
|
|
9
|
-
let height = 0;
|
|
10
|
-
let c_width = 0;
|
|
11
|
-
let c_height = 0;
|
|
12
|
-
let wrap_el;
|
|
13
|
-
let anchor_right = false;
|
|
14
|
-
let anchor_top = false;
|
|
15
|
-
$: {
|
|
16
|
-
if (wrap_el && (width || height || c_height || c_width)) {
|
|
17
|
-
const box = wrap_el.getBoundingClientRect();
|
|
18
|
-
anchor_right = box.width + 30 > width / 2;
|
|
19
|
-
anchor_top = box.y < 80;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
8
|
</script>
|
|
23
9
|
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
<div
|
|
27
|
-
class="wrap"
|
|
28
|
-
use:click_outside={() => dispatch("click_outside")}
|
|
29
|
-
bind:this={wrap_el}
|
|
30
|
-
bind:clientWidth={c_width}
|
|
31
|
-
bind:clientHeight={c_height}
|
|
32
|
-
class:right={anchor_right}
|
|
33
|
-
class:top={anchor_top}
|
|
34
|
-
class:bottom={!anchor_top}
|
|
35
|
-
>
|
|
10
|
+
<div class="wrap" use:click_outside={() => dispatch("click_outside")}>
|
|
36
11
|
<span>
|
|
37
12
|
<BrushSize />
|
|
38
13
|
</span>
|
|
@@ -41,7 +16,7 @@ $: {
|
|
|
41
16
|
|
|
42
17
|
<style>
|
|
43
18
|
.wrap {
|
|
44
|
-
width:
|
|
19
|
+
width: 230px;
|
|
45
20
|
display: flex;
|
|
46
21
|
gap: var(--size-4);
|
|
47
22
|
background: var(--background-fill-secondary);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
<script>import { Eyedropper } from "@gradio/icons";
|
|
1
|
+
<script>import { Eyedropper, Plus } from "@gradio/icons";
|
|
2
2
|
import { createEventDispatcher } from "svelte";
|
|
3
3
|
import tinycolor from "tinycolor2";
|
|
4
|
+
import IconButton from "../IconButton.svelte";
|
|
4
5
|
export let color;
|
|
5
6
|
export let current_mode = "hex";
|
|
6
7
|
const dispatch = createEventDispatcher();
|