@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
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script>import Layers from "./Layers.svelte";
|
|
2
|
+
export let layers;
|
|
3
|
+
export let enable_additional_layers = true;
|
|
4
|
+
export let enable_layers = true;
|
|
5
|
+
export let show_layers = false;
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<div class="toolbar-wrap-wrap">
|
|
9
|
+
<div class="toolbar-wrap">
|
|
10
|
+
{#if enable_layers}
|
|
11
|
+
<Layers
|
|
12
|
+
{layers}
|
|
13
|
+
{enable_additional_layers}
|
|
14
|
+
{enable_layers}
|
|
15
|
+
{show_layers}
|
|
16
|
+
on:new_layer
|
|
17
|
+
on:change_layer
|
|
18
|
+
on:move_layer
|
|
19
|
+
on:delete_layer
|
|
20
|
+
on:toggle_layer_visibility
|
|
21
|
+
/>
|
|
22
|
+
{/if}
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<style>
|
|
27
|
+
.toolbar-wrap-wrap {
|
|
28
|
+
position: absolute;
|
|
29
|
+
right: 0;
|
|
30
|
+
bottom: 0;
|
|
31
|
+
width: fit-content;
|
|
32
|
+
max-height: 100%;
|
|
33
|
+
overflow-y: auto;
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-direction: column-reverse;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.toolbar-wrap {
|
|
39
|
+
min-width: 110px;
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
justify-content: center;
|
|
43
|
+
align-items: center;
|
|
44
|
+
position: relative;
|
|
45
|
+
right: 0;
|
|
46
|
+
bottom: 0;
|
|
47
|
+
border: 1px solid var(--block-border-color);
|
|
48
|
+
border-radius: 0;
|
|
49
|
+
border-top-left-radius: var(--radius-md);
|
|
50
|
+
border-right: none;
|
|
51
|
+
border-bottom: none;
|
|
52
|
+
z-index: 1000;
|
|
53
|
+
background-color: var(--block-background-fill);
|
|
54
|
+
}
|
|
55
|
+
</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 SecondaryToolbarProps = typeof __propDef.props;
|
|
33
|
+
export type SecondaryToolbarEvents = typeof __propDef.events;
|
|
34
|
+
export type SecondaryToolbarSlots = typeof __propDef.slots;
|
|
35
|
+
export default class SecondaryToolbar extends SvelteComponent<SecondaryToolbarProps, SecondaryToolbarEvents, SecondaryToolbarSlots> {
|
|
36
|
+
}
|
|
37
|
+
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>;
|