@gradio/imageeditor 0.18.12 → 0.20.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 +42 -0
- package/Example.svelte +9 -3
- package/ImageEditor.stories.svelte +0 -74
- package/Index.svelte +34 -35
- package/InteractiveImageEditor.svelte +99 -57
- package/dist/Example.svelte +9 -3
- package/dist/Example.svelte.d.ts +4 -18
- package/dist/Index.svelte +34 -35
- package/dist/Index.svelte.d.ts +2 -19
- package/dist/InteractiveImageEditor.svelte +99 -57
- package/dist/InteractiveImageEditor.svelte.d.ts +20 -37
- package/dist/shared/Anchor.svelte +13 -11
- package/dist/shared/Anchor.svelte.d.ts +4 -19
- package/dist/shared/Controls.svelte +63 -39
- package/dist/shared/Controls.svelte.d.ts +13 -28
- package/dist/shared/IconButton.svelte +39 -18
- package/dist/shared/IconButton.svelte.d.ts +7 -21
- package/dist/shared/ImageEditor.svelte +246 -167
- package/dist/shared/ImageEditor.svelte.d.ts +55 -2
- package/dist/shared/Layers.svelte +43 -29
- package/dist/shared/Layers.svelte.d.ts +10 -25
- package/dist/shared/Resize.svelte +22 -16
- package/dist/shared/Resize.svelte.d.ts +6 -22
- package/dist/shared/SecondaryToolbar.svelte +34 -18
- package/dist/shared/SecondaryToolbar.svelte.d.ts +10 -25
- package/dist/shared/Toolbar.svelte +60 -76
- package/dist/shared/Toolbar.svelte.d.ts +10 -25
- package/dist/shared/brush/BrushOptions.svelte +49 -29
- package/dist/shared/brush/BrushOptions.svelte.d.ts +6 -21
- package/dist/shared/brush/BrushSize.svelte +12 -9
- package/dist/shared/brush/BrushSize.svelte.d.ts +5 -20
- package/dist/shared/brush/ColorField.svelte +21 -16
- package/dist/shared/brush/ColorField.svelte.d.ts +6 -22
- package/dist/shared/brush/ColorPicker.svelte +22 -16
- package/dist/shared/brush/ColorPicker.svelte.d.ts +4 -18
- package/dist/shared/brush/ColorSwatch.svelte +41 -21
- package/dist/shared/brush/ColorSwatch.svelte.d.ts +10 -24
- package/dist/shared/brush/brush.js +7 -8
- package/dist/shared/core/editor.d.ts +5 -0
- package/dist/shared/core/editor.js +43 -2
- package/dist/shared/resize/resize.d.ts +2 -0
- package/dist/shared/resize/resize.js +27 -18
- package/dist/types.d.ts +1 -1
- package/package.json +8 -8
- package/shared/Anchor.svelte +13 -11
- package/shared/Controls.svelte +63 -39
- package/shared/IconButton.svelte +39 -18
- package/shared/ImageEditor.svelte +246 -167
- package/shared/Layers.svelte +43 -29
- package/shared/Resize.svelte +22 -16
- package/shared/SecondaryToolbar.svelte +34 -18
- package/shared/Toolbar.svelte +60 -76
- package/shared/brush/BrushOptions.svelte +49 -29
- package/shared/brush/BrushSize.svelte +12 -9
- package/shared/brush/ColorField.svelte +21 -16
- package/shared/brush/ColorPicker.svelte +22 -16
- package/shared/brush/ColorSwatch.svelte +41 -21
- package/shared/brush/brush.ts +8 -10
- package/shared/core/editor.ts +49 -2
- package/shared/resize/resize.ts +28 -20
- package/types.ts +1 -1
|
@@ -2,45 +2,30 @@ export type Tool = "image" | "draw" | "erase" | "pan";
|
|
|
2
2
|
export type Subtool = "upload" | "paste" | "webcam" | "color" | "size" | "crop" | "remove_background" | null;
|
|
3
3
|
import type { Source, Transform } from "./types";
|
|
4
4
|
import { type Brush as BrushType, type Eraser as EraserType } from "./brush/types";
|
|
5
|
-
|
|
6
|
-
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
7
|
-
$$bindings?: Bindings;
|
|
8
|
-
} & Exports;
|
|
9
|
-
(internal: unknown, props: Props & {
|
|
10
|
-
$$events?: Events;
|
|
11
|
-
$$slots?: Slots;
|
|
12
|
-
}): Exports & {
|
|
13
|
-
$set?: any;
|
|
14
|
-
$on?: any;
|
|
15
|
-
};
|
|
16
|
-
z_$$bindings?: Bindings;
|
|
17
|
-
}
|
|
18
|
-
declare const Toolbar: $$__sveltets_2_IsomorphicComponent<{
|
|
5
|
+
type $$ComponentProps = {
|
|
19
6
|
tool?: Tool;
|
|
20
7
|
subtool?: Subtool;
|
|
21
8
|
background?: boolean;
|
|
22
9
|
brush_options: BrushType | false;
|
|
23
10
|
selected_size?: number;
|
|
24
|
-
eraser_options: EraserType;
|
|
11
|
+
eraser_options: EraserType | false;
|
|
25
12
|
selected_eraser_size?: number;
|
|
26
13
|
selected_color?: any;
|
|
27
|
-
selected_opacity?:
|
|
14
|
+
selected_opacity?: number;
|
|
28
15
|
preview?: boolean;
|
|
29
16
|
show_brush_color?: boolean;
|
|
30
17
|
show_brush_size?: boolean;
|
|
31
18
|
show_eraser_size?: boolean;
|
|
32
19
|
sources: Source[];
|
|
33
20
|
transforms: Transform[];
|
|
34
|
-
|
|
35
|
-
tool_change: CustomEvent<{
|
|
21
|
+
ontool_change?: (value: {
|
|
36
22
|
tool: Tool;
|
|
37
|
-
}
|
|
38
|
-
|
|
23
|
+
}) => void;
|
|
24
|
+
onsubtool_change?: (value: {
|
|
39
25
|
tool: Tool;
|
|
40
26
|
subtool: Subtool;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
type Toolbar = InstanceType<typeof Toolbar>;
|
|
27
|
+
}) => void;
|
|
28
|
+
};
|
|
29
|
+
declare const Toolbar: import("svelte").Component<$$ComponentProps, {}, "selected_color" | "selected_size" | "selected_opacity" | "preview" | "selected_eraser_size">;
|
|
30
|
+
type Toolbar = ReturnType<typeof Toolbar>;
|
|
46
31
|
export default Toolbar;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { createEventDispatcher, tick } from "svelte";
|
|
3
2
|
import { click_outside } from "../utils/events";
|
|
4
3
|
|
|
5
4
|
import { type Brush, type ColorTuple } from "./types";
|
|
@@ -9,23 +8,35 @@
|
|
|
9
8
|
import BrushSize from "./BrushSize.svelte";
|
|
10
9
|
import type { ColorInput } from "tinycolor2";
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
11
|
+
let {
|
|
12
|
+
colors,
|
|
13
|
+
selected_color = $bindable(),
|
|
14
|
+
color_mode = undefined,
|
|
15
|
+
recent_colors = [],
|
|
16
|
+
selected_size = $bindable(),
|
|
17
|
+
selected_opacity = $bindable(),
|
|
18
|
+
show_swatch,
|
|
19
|
+
show_size,
|
|
20
|
+
mode = "brush",
|
|
21
|
+
preview = $bindable(),
|
|
22
|
+
onclick_outside = () => {}
|
|
23
|
+
}: {
|
|
24
|
+
colors: (ColorInput | ColorTuple)[];
|
|
25
|
+
selected_color: any;
|
|
26
|
+
color_mode?: Brush["color_mode"];
|
|
27
|
+
recent_colors?: (ColorInput | ColorTuple)[];
|
|
28
|
+
selected_size: number;
|
|
29
|
+
selected_opacity: number;
|
|
30
|
+
show_swatch: boolean;
|
|
31
|
+
show_size: boolean;
|
|
32
|
+
mode?: "brush" | "eraser";
|
|
33
|
+
preview?: boolean;
|
|
34
|
+
onclick_outside?: (event: MouseEvent) => void;
|
|
35
|
+
} = $props();
|
|
36
|
+
|
|
37
|
+
let color_picker = $state(false);
|
|
38
|
+
let current_mode = $state<"hex" | "rgb" | "hsl">("hex");
|
|
39
|
+
let editing_index = $state<number | null>(null);
|
|
29
40
|
|
|
30
41
|
function handle_color_selection(
|
|
31
42
|
{
|
|
@@ -61,9 +72,11 @@
|
|
|
61
72
|
recent_colors[editing_index] = color;
|
|
62
73
|
}
|
|
63
74
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
75
|
+
$effect(() => {
|
|
76
|
+
handle_color_change(selected_color);
|
|
77
|
+
});
|
|
78
|
+
let width = $state(0);
|
|
79
|
+
let height = $state(0);
|
|
67
80
|
|
|
68
81
|
function debounce(
|
|
69
82
|
func: (...args: any[]) => void,
|
|
@@ -76,7 +89,6 @@
|
|
|
76
89
|
};
|
|
77
90
|
}
|
|
78
91
|
|
|
79
|
-
export let preview = false;
|
|
80
92
|
function handle_preview(): void {
|
|
81
93
|
if (!preview) {
|
|
82
94
|
preview = true;
|
|
@@ -92,7 +104,15 @@
|
|
|
92
104
|
|
|
93
105
|
const debounced_close_preview = debounce(handle_close_preview, 1000);
|
|
94
106
|
|
|
95
|
-
|
|
107
|
+
$effect(() => {
|
|
108
|
+
if (!show_size) {
|
|
109
|
+
preview = false;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
selected_size;
|
|
114
|
+
handle_preview();
|
|
115
|
+
});
|
|
96
116
|
|
|
97
117
|
function handle_select(color: string): void {
|
|
98
118
|
selected_color = color;
|
|
@@ -124,7 +144,7 @@
|
|
|
124
144
|
<div
|
|
125
145
|
class="wrap"
|
|
126
146
|
class:padded={!color_picker}
|
|
127
|
-
use:click_outside={
|
|
147
|
+
use:click_outside={onclick_outside}
|
|
128
148
|
class:color_picker
|
|
129
149
|
class:size_picker={show_size && mode === "brush"}
|
|
130
150
|
class:eraser_picker={mode === "eraser"}
|
|
@@ -138,8 +158,8 @@
|
|
|
138
158
|
<ColorField
|
|
139
159
|
bind:current_mode
|
|
140
160
|
color={selected_color}
|
|
141
|
-
|
|
142
|
-
|
|
161
|
+
onclose={() => (color_picker = false)}
|
|
162
|
+
onselected={(detail) => handle_select(detail)}
|
|
143
163
|
/>
|
|
144
164
|
{/if}
|
|
145
165
|
{/if}
|
|
@@ -147,12 +167,12 @@
|
|
|
147
167
|
<ColorSwatch
|
|
148
168
|
bind:color_picker
|
|
149
169
|
{colors}
|
|
150
|
-
|
|
151
|
-
|
|
170
|
+
onselect={(detail) => handle_color_selection(detail, "core")}
|
|
171
|
+
onedit={(detail) => handle_color_selection(detail, "user")}
|
|
152
172
|
user_colors={color_mode === "defaults" ? recent_colors : null}
|
|
153
173
|
{selected_color}
|
|
154
174
|
{current_mode}
|
|
155
|
-
|
|
175
|
+
onadd_color={handle_add_color}
|
|
156
176
|
/>
|
|
157
177
|
{/if}
|
|
158
178
|
|
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
import { type Brush, type ColorTuple } from "./types";
|
|
2
2
|
import type { ColorInput } from "tinycolor2";
|
|
3
|
-
|
|
4
|
-
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
5
|
-
$$bindings?: Bindings;
|
|
6
|
-
} & Exports;
|
|
7
|
-
(internal: unknown, props: Props & {
|
|
8
|
-
$$events?: Events;
|
|
9
|
-
$$slots?: Slots;
|
|
10
|
-
}): Exports & {
|
|
11
|
-
$set?: any;
|
|
12
|
-
$on?: any;
|
|
13
|
-
};
|
|
14
|
-
z_$$bindings?: Bindings;
|
|
15
|
-
}
|
|
16
|
-
declare const BrushOptions: $$__sveltets_2_IsomorphicComponent<{
|
|
3
|
+
type $$ComponentProps = {
|
|
17
4
|
colors: (ColorInput | ColorTuple)[];
|
|
18
5
|
selected_color: any;
|
|
19
|
-
color_mode?: Brush["color_mode"]
|
|
6
|
+
color_mode?: Brush["color_mode"];
|
|
20
7
|
recent_colors?: (ColorInput | ColorTuple)[];
|
|
21
8
|
selected_size: number;
|
|
22
9
|
selected_opacity: number;
|
|
@@ -24,10 +11,8 @@ declare const BrushOptions: $$__sveltets_2_IsomorphicComponent<{
|
|
|
24
11
|
show_size: boolean;
|
|
25
12
|
mode?: "brush" | "eraser";
|
|
26
13
|
preview?: boolean;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
}, {}, {}, string>;
|
|
32
|
-
type BrushOptions = InstanceType<typeof BrushOptions>;
|
|
14
|
+
onclick_outside?: (event: MouseEvent) => void;
|
|
15
|
+
};
|
|
16
|
+
declare const BrushOptions: import("svelte").Component<$$ComponentProps, {}, "selected_color" | "selected_size" | "selected_opacity" | "preview">;
|
|
17
|
+
type BrushOptions = ReturnType<typeof BrushOptions>;
|
|
33
18
|
export default BrushOptions;
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { click_outside } from "../utils/events";
|
|
3
|
-
import { createEventDispatcher } from "svelte";
|
|
4
3
|
import { BrushSize } from "@gradio/icons";
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
let {
|
|
6
|
+
selected_size = $bindable(),
|
|
7
|
+
min,
|
|
8
|
+
max,
|
|
9
|
+
onclick_outside = () => {}
|
|
10
|
+
}: {
|
|
11
|
+
selected_size: number;
|
|
12
|
+
min: number;
|
|
13
|
+
max: number;
|
|
14
|
+
onclick_outside?: (event: MouseEvent) => void;
|
|
15
|
+
} = $props();
|
|
13
16
|
</script>
|
|
14
17
|
|
|
15
|
-
<div class="wrap" use:click_outside={
|
|
18
|
+
<div class="wrap" use:click_outside={onclick_outside}>
|
|
16
19
|
<span>
|
|
17
20
|
<BrushSize />
|
|
18
21
|
</span>
|
|
@@ -1,25 +1,10 @@
|
|
|
1
1
|
import { BrushSize } from "@gradio/icons";
|
|
2
|
-
|
|
3
|
-
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
-
$$bindings?: Bindings;
|
|
5
|
-
} & Exports;
|
|
6
|
-
(internal: unknown, props: Props & {
|
|
7
|
-
$$events?: Events;
|
|
8
|
-
$$slots?: Slots;
|
|
9
|
-
}): Exports & {
|
|
10
|
-
$set?: any;
|
|
11
|
-
$on?: any;
|
|
12
|
-
};
|
|
13
|
-
z_$$bindings?: Bindings;
|
|
14
|
-
}
|
|
15
|
-
declare const BrushSize: $$__sveltets_2_IsomorphicComponent<{
|
|
2
|
+
type $$ComponentProps = {
|
|
16
3
|
selected_size: number;
|
|
17
4
|
min: number;
|
|
18
5
|
max: number;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}, {}, {}, string>;
|
|
24
|
-
type BrushSize = InstanceType<typeof BrushSize>;
|
|
6
|
+
onclick_outside?: (event: MouseEvent) => void;
|
|
7
|
+
};
|
|
8
|
+
declare const BrushSize: import("svelte").Component<$$ComponentProps, {}, "selected_size">;
|
|
9
|
+
type BrushSize = ReturnType<typeof BrushSize>;
|
|
25
10
|
export default BrushSize;
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { Eyedropper, Plus } from "@gradio/icons";
|
|
3
|
-
import { createEventDispatcher } from "svelte";
|
|
4
3
|
|
|
5
4
|
import tinycolor from "tinycolor2";
|
|
6
5
|
import IconButton from "../IconButton.svelte";
|
|
7
|
-
export let color: string;
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
let {
|
|
8
|
+
color,
|
|
9
|
+
current_mode = $bindable<"hex" | "rgb" | "hsl">("hex"),
|
|
10
|
+
onselected,
|
|
11
|
+
onclose
|
|
12
|
+
}: {
|
|
13
|
+
color: string;
|
|
14
|
+
current_mode?: "hex" | "rgb" | "hsl";
|
|
15
|
+
onselected?: (color: string) => void;
|
|
16
|
+
onclose?: () => void;
|
|
17
|
+
} = $props();
|
|
10
18
|
|
|
11
|
-
const dispatch = createEventDispatcher<{
|
|
12
|
-
selected: string;
|
|
13
|
-
close: void;
|
|
14
|
-
add_color: void;
|
|
15
|
-
}>();
|
|
16
19
|
const modes = [
|
|
17
20
|
["Hex", "hex"],
|
|
18
21
|
["RGB", "rgb"],
|
|
@@ -28,8 +31,10 @@
|
|
|
28
31
|
return tinycolor(color).toHslString();
|
|
29
32
|
}
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
let color_string = $derived(format_color(color, current_mode));
|
|
35
|
+
$effect(() => {
|
|
36
|
+
if (color_string) onselected?.(color_string);
|
|
37
|
+
});
|
|
33
38
|
|
|
34
39
|
function request_eyedropper(): void {
|
|
35
40
|
// @ts-ignore
|
|
@@ -44,23 +49,23 @@
|
|
|
44
49
|
const eyedropper_supported = !!window.EyeDropper;
|
|
45
50
|
|
|
46
51
|
function handle_click(): void {
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
onselected?.(color_string);
|
|
53
|
+
onclose?.();
|
|
49
54
|
}
|
|
50
55
|
</script>
|
|
51
56
|
|
|
52
57
|
<div class="input">
|
|
53
|
-
<button class="swatch" style:background={color}
|
|
58
|
+
<button class="swatch" style:background={color} onclick={handle_click}
|
|
54
59
|
></button>
|
|
55
60
|
<div>
|
|
56
61
|
<div class="input-wrap">
|
|
57
62
|
<input
|
|
58
63
|
type="text"
|
|
59
64
|
value={color_string}
|
|
60
|
-
|
|
65
|
+
onchange={(e) => (color = e.currentTarget.value)}
|
|
61
66
|
/>
|
|
62
67
|
|
|
63
|
-
<button class="eyedropper"
|
|
68
|
+
<button class="eyedropper" onclick={request_eyedropper}>
|
|
64
69
|
{#if eyedropper_supported}
|
|
65
70
|
<Eyedropper />
|
|
66
71
|
{/if}
|
|
@@ -71,7 +76,7 @@
|
|
|
71
76
|
<button
|
|
72
77
|
class="button"
|
|
73
78
|
class:active={current_mode === value}
|
|
74
|
-
|
|
79
|
+
onclick={() => (current_mode = value)}>{label}</button
|
|
75
80
|
>
|
|
76
81
|
{/each}
|
|
77
82
|
</div>
|
|
@@ -1,25 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
-
$$bindings?: Bindings;
|
|
4
|
-
} & Exports;
|
|
5
|
-
(internal: unknown, props: Props & {
|
|
6
|
-
$$events?: Events;
|
|
7
|
-
$$slots?: Slots;
|
|
8
|
-
}): Exports & {
|
|
9
|
-
$set?: any;
|
|
10
|
-
$on?: any;
|
|
11
|
-
};
|
|
12
|
-
z_$$bindings?: Bindings;
|
|
13
|
-
}
|
|
14
|
-
declare const ColorField: $$__sveltets_2_IsomorphicComponent<{
|
|
1
|
+
type $$ComponentProps = {
|
|
15
2
|
color: string;
|
|
16
3
|
current_mode?: "hex" | "rgb" | "hsl";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
[evt: string]: CustomEvent<any>;
|
|
23
|
-
}, {}, {}, string>;
|
|
24
|
-
type ColorField = InstanceType<typeof ColorField>;
|
|
4
|
+
onselected?: (color: string) => void;
|
|
5
|
+
onclose?: () => void;
|
|
6
|
+
};
|
|
7
|
+
declare const ColorField: import("svelte").Component<$$ComponentProps, {}, "current_mode">;
|
|
8
|
+
type ColorField = ReturnType<typeof ColorField>;
|
|
25
9
|
export default ColorField;
|
|
@@ -3,19 +3,25 @@
|
|
|
3
3
|
import tinycolor from "tinycolor2";
|
|
4
4
|
import { clamp } from "../utils/pixi";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
let {
|
|
7
|
+
color = $bindable("rgb(255, 255, 255)"),
|
|
8
|
+
opacity = $bindable(1)
|
|
9
|
+
}: {
|
|
10
|
+
color?: string;
|
|
11
|
+
opacity?: number;
|
|
12
|
+
} = $props();
|
|
13
|
+
|
|
14
|
+
let sl_marker_pos = $state([0, 0]);
|
|
9
15
|
let sl_rect: DOMRect | null = null;
|
|
10
|
-
let sl_moving = false;
|
|
11
|
-
let sl = [0, 0];
|
|
16
|
+
let sl_moving = $state(false);
|
|
17
|
+
let sl = $state([0, 0]);
|
|
12
18
|
|
|
13
|
-
let hue = 0;
|
|
14
|
-
let hue_marker_pos = 0;
|
|
19
|
+
let hue = $state(0);
|
|
20
|
+
let hue_marker_pos = $state(0);
|
|
15
21
|
let hue_rect: DOMRect | null = null;
|
|
16
|
-
let hue_moving = false;
|
|
22
|
+
let hue_moving = $state(false);
|
|
17
23
|
|
|
18
|
-
let opacity_moving = false;
|
|
24
|
+
let opacity_moving = $state(false);
|
|
19
25
|
|
|
20
26
|
function handle_hue_down(
|
|
21
27
|
event: MouseEvent & { currentTarget: HTMLDivElement }
|
|
@@ -121,13 +127,13 @@
|
|
|
121
127
|
hue_marker_pos = (hsva.h / 360) * hue_rect!.width;
|
|
122
128
|
}
|
|
123
129
|
|
|
124
|
-
|
|
130
|
+
$effect(() => {
|
|
131
|
+
update_mouse_from_color(color);
|
|
132
|
+
});
|
|
125
133
|
|
|
126
134
|
let sl_wrap: HTMLDivElement;
|
|
127
135
|
let hue_wrap: HTMLDivElement;
|
|
128
136
|
|
|
129
|
-
export let opacity = 1;
|
|
130
|
-
|
|
131
137
|
let opacity_wrap: HTMLDivElement;
|
|
132
138
|
|
|
133
139
|
function handle_opacity_down(
|
|
@@ -150,12 +156,12 @@
|
|
|
150
156
|
});
|
|
151
157
|
</script>
|
|
152
158
|
|
|
153
|
-
<svelte:window
|
|
159
|
+
<svelte:window onmousemove={handle_move} onmouseup={handle_end} />
|
|
154
160
|
|
|
155
161
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
156
162
|
<div
|
|
157
163
|
class="color-gradient"
|
|
158
|
-
|
|
164
|
+
onmousedown={handle_sl_down}
|
|
159
165
|
style="--hue:{hue}"
|
|
160
166
|
bind:this={sl_wrap}
|
|
161
167
|
>
|
|
@@ -168,7 +174,7 @@
|
|
|
168
174
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
169
175
|
<div
|
|
170
176
|
class="opacity-slider"
|
|
171
|
-
|
|
177
|
+
onmousedown={handle_opacity_down}
|
|
172
178
|
style="--color:{color === 'auto' ? 'transparent' : color}"
|
|
173
179
|
bind:this={opacity_wrap}
|
|
174
180
|
>
|
|
@@ -179,7 +185,7 @@
|
|
|
179
185
|
/>
|
|
180
186
|
</div>
|
|
181
187
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
182
|
-
<div class="hue-slider"
|
|
188
|
+
<div class="hue-slider" onmousedown={handle_hue_down} bind:this={hue_wrap}>
|
|
183
189
|
<div
|
|
184
190
|
class="marker"
|
|
185
191
|
style:background={"hsl(" + hue + ", 100%, 50%)"}
|
|
@@ -1,21 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
-
$$bindings?: Bindings;
|
|
4
|
-
} & Exports;
|
|
5
|
-
(internal: unknown, props: Props & {
|
|
6
|
-
$$events?: Events;
|
|
7
|
-
$$slots?: Slots;
|
|
8
|
-
}): Exports & {
|
|
9
|
-
$set?: any;
|
|
10
|
-
$on?: any;
|
|
11
|
-
};
|
|
12
|
-
z_$$bindings?: Bindings;
|
|
13
|
-
}
|
|
14
|
-
declare const ColorPicker: $$__sveltets_2_IsomorphicComponent<{
|
|
1
|
+
type $$ComponentProps = {
|
|
15
2
|
color?: string;
|
|
16
3
|
opacity?: number;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
type ColorPicker = InstanceType<typeof ColorPicker>;
|
|
4
|
+
};
|
|
5
|
+
declare const ColorPicker: import("svelte").Component<$$ComponentProps, {}, "color" | "opacity">;
|
|
6
|
+
type ColorPicker = ReturnType<typeof ColorPicker>;
|
|
21
7
|
export default ColorPicker;
|
|
@@ -1,25 +1,41 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import tinycolor from "tinycolor2";
|
|
3
|
-
import { createEventDispatcher } from "svelte";
|
|
4
3
|
import type { ColorTuple } from "./types";
|
|
5
4
|
import type { ColorInput } from "tinycolor2";
|
|
6
5
|
import IconButton from "../IconButton.svelte";
|
|
7
6
|
import { Plus } from "@gradio/icons";
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
8
|
+
let {
|
|
9
|
+
selected_color,
|
|
10
|
+
colors,
|
|
11
|
+
user_colors = [],
|
|
12
|
+
show_empty = false,
|
|
13
|
+
current_mode = "hex",
|
|
14
|
+
color_picker = $bindable(false),
|
|
15
|
+
onselect,
|
|
16
|
+
onedit,
|
|
17
|
+
onadd_color
|
|
18
|
+
}: {
|
|
19
|
+
selected_color: string;
|
|
20
|
+
colors: (ColorInput | ColorTuple)[];
|
|
21
|
+
user_colors?: (ColorInput | ColorTuple)[] | null;
|
|
22
|
+
show_empty?: boolean;
|
|
23
|
+
current_mode?: "hex" | "rgb" | "hsl";
|
|
24
|
+
color_picker?: boolean;
|
|
25
|
+
onselect?: (value: {
|
|
26
|
+
index: number | null;
|
|
27
|
+
color: string | null;
|
|
28
|
+
opacity?: number;
|
|
29
|
+
}) => void;
|
|
30
|
+
onedit?: (value: {
|
|
31
|
+
index: number;
|
|
32
|
+
color: string | null;
|
|
33
|
+
opacity?: number;
|
|
34
|
+
}) => void;
|
|
35
|
+
onadd_color?: () => void;
|
|
36
|
+
} = $props();
|
|
21
37
|
|
|
22
|
-
|
|
38
|
+
let _colors = $derived(show_empty ? colors : colors.filter((c) => c));
|
|
23
39
|
|
|
24
40
|
function get_color(color_input: ColorInput | ColorTuple): string {
|
|
25
41
|
if (Array.isArray(color_input)) {
|
|
@@ -58,7 +74,7 @@
|
|
|
58
74
|
get_formatted_color(selected_color, current_mode)
|
|
59
75
|
)}`;
|
|
60
76
|
|
|
61
|
-
|
|
77
|
+
let selected_opacity = $derived(get_opacity(selected_color));
|
|
62
78
|
|
|
63
79
|
function handle_select(
|
|
64
80
|
type: "edit" | "select",
|
|
@@ -69,11 +85,15 @@
|
|
|
69
85
|
}
|
|
70
86
|
): void {
|
|
71
87
|
current_index = `${type}-${detail.index}`;
|
|
72
|
-
|
|
88
|
+
if (type === "edit") {
|
|
89
|
+
onedit?.(detail);
|
|
90
|
+
} else {
|
|
91
|
+
onselect?.(detail);
|
|
92
|
+
}
|
|
73
93
|
}
|
|
74
94
|
|
|
75
95
|
function handle_picker_click(): void {
|
|
76
|
-
|
|
96
|
+
onselect?.({ index: null, color: selected_color });
|
|
77
97
|
color_picker = !color_picker;
|
|
78
98
|
}
|
|
79
99
|
</script>
|
|
@@ -89,7 +109,7 @@
|
|
|
89
109
|
{#if color_picker}
|
|
90
110
|
<IconButton
|
|
91
111
|
Icon={Plus}
|
|
92
|
-
onclick={() =>
|
|
112
|
+
onclick={() => onadd_color?.()}
|
|
93
113
|
roundedness="very"
|
|
94
114
|
background={get_color(selected_color)}
|
|
95
115
|
color="white"
|
|
@@ -99,7 +119,7 @@
|
|
|
99
119
|
{@const color_string = get_color(color)}
|
|
100
120
|
{@const opacity = get_opacity(color)}
|
|
101
121
|
<button
|
|
102
|
-
|
|
122
|
+
onclick={() =>
|
|
103
123
|
handle_select("edit", {
|
|
104
124
|
index: i,
|
|
105
125
|
color: color_string,
|
|
@@ -115,7 +135,7 @@
|
|
|
115
135
|
{/each}
|
|
116
136
|
|
|
117
137
|
<button
|
|
118
|
-
|
|
138
|
+
onclick={handle_picker_click}
|
|
119
139
|
class="color colorpicker"
|
|
120
140
|
class:hidden={!color_picker}
|
|
121
141
|
></button>
|
|
@@ -126,7 +146,7 @@
|
|
|
126
146
|
{@const color_string = get_color(color_item)}
|
|
127
147
|
{@const opacity = get_opacity(color_item)}
|
|
128
148
|
<button
|
|
129
|
-
|
|
149
|
+
onclick={() =>
|
|
130
150
|
handle_select("select", {
|
|
131
151
|
index: i,
|
|
132
152
|
color: color_string,
|