@gradio/imageeditor 0.9.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/ImageEditor.stories.svelte +1 -0
  3. package/Index.svelte +7 -2
  4. package/dist/Example.svelte +41 -0
  5. package/dist/Example.svelte.d.ts +19 -0
  6. package/dist/Index.svelte +184 -0
  7. package/dist/Index.svelte.d.ts +192 -0
  8. package/dist/shared/Controls.svelte +73 -0
  9. package/dist/shared/Controls.svelte.d.ts +24 -0
  10. package/dist/shared/ImageEditor.svelte +329 -0
  11. package/dist/shared/ImageEditor.svelte.d.ts +79 -0
  12. package/dist/shared/InteractiveImageEditor.svelte +273 -0
  13. package/dist/shared/InteractiveImageEditor.svelte.d.ts +58 -0
  14. package/dist/shared/layers/Layers.svelte +216 -0
  15. package/dist/shared/layers/Layers.svelte.d.ts +18 -0
  16. package/dist/shared/layers/utils.d.ts +69 -0
  17. package/dist/shared/layers/utils.js +131 -0
  18. package/dist/shared/tools/Brush.svelte +208 -0
  19. package/dist/shared/tools/Brush.svelte.d.ts +29 -0
  20. package/dist/shared/tools/BrushOptions.svelte +162 -0
  21. package/dist/shared/tools/BrushOptions.svelte.d.ts +29 -0
  22. package/dist/shared/tools/BrushSize.svelte +60 -0
  23. package/dist/shared/tools/BrushSize.svelte.d.ts +20 -0
  24. package/dist/shared/tools/ColorField.svelte +159 -0
  25. package/dist/shared/tools/ColorField.svelte.d.ts +20 -0
  26. package/dist/shared/tools/ColorPicker.svelte +179 -0
  27. package/dist/shared/tools/ColorPicker.svelte.d.ts +16 -0
  28. package/dist/shared/tools/ColorSwatch.svelte +183 -0
  29. package/dist/shared/tools/ColorSwatch.svelte.d.ts +30 -0
  30. package/dist/shared/tools/Crop.svelte +155 -0
  31. package/dist/shared/tools/Crop.svelte.d.ts +16 -0
  32. package/dist/shared/tools/Cropper.svelte +271 -0
  33. package/dist/shared/tools/Cropper.svelte.d.ts +41 -0
  34. package/dist/shared/tools/Handle.svelte +260 -0
  35. package/dist/shared/tools/Handle.svelte.d.ts +29 -0
  36. package/dist/shared/tools/Sources.svelte +250 -0
  37. package/dist/shared/tools/Sources.svelte.d.ts +32 -0
  38. package/dist/shared/tools/Tools.svelte +101 -0
  39. package/dist/shared/tools/Tools.svelte.d.ts +48 -0
  40. package/dist/shared/tools/brush.d.ts +62 -0
  41. package/dist/shared/tools/brush.js +133 -0
  42. package/dist/shared/tools/crop.d.ts +15 -0
  43. package/dist/shared/tools/crop.js +154 -0
  44. package/dist/shared/tools/index.d.ts +5 -0
  45. package/dist/shared/tools/index.js +5 -0
  46. package/dist/shared/tools/sources.d.ts +40 -0
  47. package/dist/shared/tools/sources.js +69 -0
  48. package/dist/shared/tools/types.d.ts +1 -0
  49. package/dist/shared/tools/types.js +1 -0
  50. package/dist/shared/utils/commands.d.ts +96 -0
  51. package/dist/shared/utils/commands.js +65 -0
  52. package/dist/shared/utils/events.d.ts +7 -0
  53. package/dist/shared/utils/events.js +22 -0
  54. package/dist/shared/utils/parse_placeholder.d.ts +1 -0
  55. package/dist/shared/utils/parse_placeholder.js +19 -0
  56. package/dist/shared/utils/pixi.d.ts +76 -0
  57. package/dist/shared/utils/pixi.js +152 -0
  58. package/package.json +28 -12
  59. package/shared/ImageEditor.svelte +8 -4
  60. package/shared/InteractiveImageEditor.svelte +29 -5
  61. package/shared/tools/Brush.svelte +4 -6
  62. package/shared/tools/BrushOptions.svelte +1 -1
  63. package/shared/tools/Crop.svelte +2 -1
  64. package/shared/utils/parse_placeholder.ts +27 -0
  65. package/shared/utils/pixi.ts +0 -1
@@ -0,0 +1,29 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import { type ColorInput } from "tinycolor2";
3
+ export interface Eraser {
4
+ /**
5
+ * The default size of the eraser.
6
+ */
7
+ default_size: number | "auto";
8
+ }
9
+ export interface Brush extends Eraser {
10
+ /**
11
+ * The default color of the brush.
12
+ */
13
+ default_color: ColorInput;
14
+ /**
15
+ * The colors to show in the color swatch
16
+ */
17
+ colors: ColorInput[];
18
+ /**
19
+ * Whether to show _only_ the color swatches specified in `colors`, or to show the color swatches specified in `colors` along with the colorpicker.
20
+ */
21
+ color_mode: "fixed" | "defaults";
22
+ }
23
+ declare const __propDef: any;
24
+ export type BrushProps = typeof __propDef.props;
25
+ export type BrushEvents = typeof __propDef.events;
26
+ export type BrushSlots = typeof __propDef.slots;
27
+ export default class Brush extends SvelteComponent<BrushProps, BrushEvents, BrushSlots> {
28
+ }
29
+ export {};
@@ -0,0 +1,162 @@
1
+ <script>import { createEventDispatcher } from "svelte";
2
+ import { click_outside } from "../utils/events";
3
+ import {} from "./Brush.svelte";
4
+ import ColorPicker from "./ColorPicker.svelte";
5
+ import ColorSwatch from "./ColorSwatch.svelte";
6
+ import ColorField from "./ColorField.svelte";
7
+ import BrushSize from "./BrushSize.svelte";
8
+ export let colors;
9
+ export let selected_color;
10
+ export let color_mode = void 0;
11
+ export let recent_colors = [];
12
+ export let selected_size;
13
+ export let dimensions;
14
+ export let parent_width;
15
+ export let parent_height;
16
+ export let parent_left;
17
+ export let toolbar_box;
18
+ export let show_swatch;
19
+ let color_picker = false;
20
+ let current_mode = "hex";
21
+ let editing_index = null;
22
+ const dispatch = createEventDispatcher();
23
+ function handle_color_selection({
24
+ index,
25
+ color
26
+ }, type) {
27
+ if (type === "user" && !color) {
28
+ editing_index = index;
29
+ color_picker = true;
30
+ }
31
+ if (!color)
32
+ return;
33
+ selected_color = color;
34
+ if (type === "core") {
35
+ color_picker = false;
36
+ }
37
+ }
38
+ function handle_color_change(color) {
39
+ if (editing_index === null)
40
+ return;
41
+ recent_colors[editing_index] = color;
42
+ }
43
+ $:
44
+ handle_color_change(selected_color);
45
+ let width = 0;
46
+ let height = 0;
47
+ let c_width = 0;
48
+ let c_height = 0;
49
+ let wrap_el;
50
+ let full_screen = false;
51
+ let anchor = "default";
52
+ let left_anchor = 0;
53
+ let top_anchor = null;
54
+ $: {
55
+ if (wrap_el && (width || height || c_height || c_width)) {
56
+ const box = wrap_el.getBoundingClientRect();
57
+ color_picker;
58
+ if (box.width > parent_width) {
59
+ full_screen = true;
60
+ } else if (parent_width > box.width + 230 * 2 + 25) {
61
+ anchor = "default";
62
+ left_anchor = toolbar_box.right - parent_left + 24;
63
+ } else {
64
+ anchor = "center";
65
+ }
66
+ if (box.height + 50 > parent_height) {
67
+ anchor = "top";
68
+ top_anchor = true;
69
+ }
70
+ }
71
+ }
72
+ </script>
73
+
74
+ <svelte:window bind:innerHeight={height} bind:innerWidth={width} />
75
+
76
+ <div
77
+ class="wrap"
78
+ class:padded={!color_picker}
79
+ use:click_outside={() => dispatch("click_outside")}
80
+ class:anchor_default={anchor === "default"}
81
+ class:anchor_center={anchor === "center"}
82
+ class:anchor_top={anchor === "top"}
83
+ bind:this={wrap_el}
84
+ bind:clientWidth={c_width}
85
+ bind:clientHeight={c_height}
86
+ class:anchor={`${left_anchor}px`}
87
+ >
88
+ {#if color_mode === "defaults"}
89
+ {#if color_picker}
90
+ <ColorPicker bind:color={selected_color} />
91
+ <ColorField
92
+ bind:current_mode
93
+ color={selected_color}
94
+ on:close={() => (color_picker = false)}
95
+ on:selected={({ detail }) => (selected_color = detail)}
96
+ />
97
+ {/if}
98
+ {/if}
99
+ {#if show_swatch}
100
+ <ColorSwatch
101
+ bind:color_picker
102
+ {colors}
103
+ on:select={({ detail }) => handle_color_selection(detail, "core")}
104
+ on:edit={({ detail }) => handle_color_selection(detail, "user")}
105
+ user_colors={color_mode === "defaults" ? recent_colors : null}
106
+ {selected_color}
107
+ {current_mode}
108
+ />
109
+ {/if}
110
+
111
+ {#if color_picker || show_swatch}
112
+ <div class="sep"></div>
113
+ {/if}
114
+
115
+ <BrushSize max={dimensions[0] / 10} min={1} bind:selected_size />
116
+ </div>
117
+
118
+ <style>
119
+ .wrap {
120
+ max-width: 230px;
121
+ width: 90%;
122
+ position: absolute;
123
+ display: flex;
124
+ flex-direction: column;
125
+ gap: 5px;
126
+ background: var(--background-fill-secondary);
127
+ border: 1px solid var(--block-border-color);
128
+ border-radius: var(--radius-md);
129
+ box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.1);
130
+ padding-bottom: var(--size-2);
131
+ pointer-events: all;
132
+ cursor: default;
133
+ z-index: var(--layer-top);
134
+ overflow: hidden;
135
+ }
136
+
137
+ .anchor_default {
138
+ position: absolute;
139
+ left: var(--left-anchor);
140
+ bottom: 8px;
141
+ }
142
+ .anchor_center {
143
+ position: absolute;
144
+ bottom: 50px;
145
+ left: 50%;
146
+ transform: translateX(-50%);
147
+ }
148
+
149
+ .anchor_top {
150
+ position: absolute;
151
+ top: 1px;
152
+ left: 50%;
153
+ transform: translateX(-50%);
154
+ }
155
+
156
+ .sep {
157
+ height: 1px;
158
+ background-color: var(--block-border-color);
159
+ margin: 0 var(--size-3);
160
+ margin-top: var(--size-1);
161
+ }
162
+ </style>
@@ -0,0 +1,29 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import { type Brush } from "./Brush.svelte";
3
+ declare const __propDef: {
4
+ props: {
5
+ colors: string[];
6
+ selected_color: string;
7
+ color_mode?: Brush["color_mode"] | undefined;
8
+ recent_colors?: (string | null)[] | undefined;
9
+ selected_size: number;
10
+ dimensions: [number, number];
11
+ parent_width: number;
12
+ parent_height: number;
13
+ parent_left: number;
14
+ toolbar_box: DOMRect | Record<string, never>;
15
+ show_swatch: boolean;
16
+ };
17
+ events: {
18
+ click_outside: CustomEvent<void>;
19
+ } & {
20
+ [evt: string]: CustomEvent<any>;
21
+ };
22
+ slots: {};
23
+ };
24
+ export type BrushOptionsProps = typeof __propDef.props;
25
+ export type BrushOptionsEvents = typeof __propDef.events;
26
+ export type BrushOptionsSlots = typeof __propDef.slots;
27
+ export default class BrushOptions extends SvelteComponent<BrushOptionsProps, BrushOptionsEvents, BrushOptionsSlots> {
28
+ }
29
+ export {};
@@ -0,0 +1,60 @@
1
+ <script>import { click_outside } from "../utils/events";
2
+ import { createEventDispatcher } from "svelte";
3
+ import { BrushSize } from "@gradio/icons";
4
+ export let selected_size;
5
+ export let min;
6
+ export let max;
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
+ </script>
23
+
24
+ <svelte:window bind:innerHeight={height} bind:innerWidth={width} />
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
+ >
36
+ <span>
37
+ <BrushSize />
38
+ </span>
39
+ <input type="range" bind:value={selected_size} {min} {max} step={1} />
40
+ </div>
41
+
42
+ <style>
43
+ .wrap {
44
+ width: 100%;
45
+ display: flex;
46
+ gap: var(--size-4);
47
+ background: var(--background-fill-secondary);
48
+ padding: 0 var(--size-4);
49
+ cursor: default;
50
+ padding-top: var(--size-2-5);
51
+ }
52
+
53
+ input {
54
+ width: 100%;
55
+ }
56
+ span {
57
+ width: 26px;
58
+ color: var(--body-text-color);
59
+ }
60
+ </style>
@@ -0,0 +1,20 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ selected_size: number;
5
+ min: number;
6
+ max: number;
7
+ };
8
+ events: {
9
+ click_outside: CustomEvent<void>;
10
+ } & {
11
+ [evt: string]: CustomEvent<any>;
12
+ };
13
+ slots: {};
14
+ };
15
+ export type BrushSizeProps = typeof __propDef.props;
16
+ export type BrushSizeEvents = typeof __propDef.events;
17
+ export type BrushSizeSlots = typeof __propDef.slots;
18
+ export default class BrushSize extends SvelteComponent<BrushSizeProps, BrushSizeEvents, BrushSizeSlots> {
19
+ }
20
+ export {};
@@ -0,0 +1,159 @@
1
+ <script>import { Eyedropper } from "@gradio/icons";
2
+ import { createEventDispatcher } from "svelte";
3
+ import tinycolor from "tinycolor2";
4
+ export let color;
5
+ export let current_mode = "hex";
6
+ const dispatch = createEventDispatcher();
7
+ const modes = [
8
+ ["Hex", "hex"],
9
+ ["RGB", "rgb"],
10
+ ["HSL", "hsl"]
11
+ ];
12
+ function format_color(color2, mode) {
13
+ if (mode === "hex") {
14
+ return tinycolor(color2).toHexString();
15
+ } else if (mode === "rgb") {
16
+ return tinycolor(color2).toRgbString();
17
+ }
18
+ return tinycolor(color2).toHslString();
19
+ }
20
+ $:
21
+ color_string = format_color(color, current_mode);
22
+ $:
23
+ color_string && dispatch("selected", color_string);
24
+ function request_eyedropper() {
25
+ const eyeDropper = new EyeDropper();
26
+ eyeDropper.open().then((result) => {
27
+ color = result.sRGBHex;
28
+ });
29
+ }
30
+ const eyedropper_supported = !!window.EyeDropper;
31
+ function handle_click() {
32
+ dispatch("selected", color_string);
33
+ dispatch("close");
34
+ }
35
+ </script>
36
+
37
+ <div class="input">
38
+ <button class="swatch" style:background={color} on:click={handle_click}
39
+ ></button>
40
+ <div>
41
+ <div class="input-wrap">
42
+ <input
43
+ type="text"
44
+ value={color_string}
45
+ on:change={(e) => (color = e.currentTarget.value)}
46
+ />
47
+
48
+ <button class="eyedropper" on:click={request_eyedropper}>
49
+ {#if eyedropper_supported}
50
+ <Eyedropper />
51
+ {/if}
52
+ </button>
53
+ </div>
54
+ <div class="buttons">
55
+ {#each modes as [label, value]}
56
+ <button
57
+ class="button"
58
+ class:active={current_mode === value}
59
+ on:click={() => (current_mode = value)}>{label}</button
60
+ >
61
+ {/each}
62
+ </div>
63
+ </div>
64
+ </div>
65
+
66
+ <style>
67
+ .input {
68
+ display: flex;
69
+ align-items: center;
70
+ padding: 0 10px 15px;
71
+ }
72
+
73
+ .input input {
74
+ height: 30px;
75
+ width: 100%;
76
+ flex-shrink: 1;
77
+ border-bottom-left-radius: 0;
78
+ border: 1px solid var(--block-border-color);
79
+ letter-spacing: -0.05rem;
80
+ border-left: none;
81
+ border-right: none;
82
+ font-family: var(--font-mono);
83
+ font-size: var(--scale-000);
84
+ padding-left: 15px;
85
+ padding-right: 0;
86
+ background-color: var(--background-fill-secondary);
87
+ color: var(--block-label-text-color);
88
+ }
89
+
90
+ .swatch {
91
+ width: 50px;
92
+ height: 50px;
93
+ border-top-left-radius: 15px;
94
+ border-bottom-left-radius: 15px;
95
+ flex-shrink: 0;
96
+ border: 1px solid var(--block-border-color);
97
+ }
98
+
99
+ .buttons button {
100
+ display: flex;
101
+ align-items: center;
102
+ justify-content: center;
103
+ border: 1px solid var(--block-border-color);
104
+ background: var(--background-fill-secondary);
105
+ padding: 3px 6px;
106
+ font-size: var(--scale-000);
107
+ cursor: pointer;
108
+ border-right: none;
109
+ width: 100%;
110
+ border-top: none;
111
+ }
112
+
113
+ .buttons button:first-child {
114
+ border-left: none;
115
+ }
116
+
117
+ .buttons button:last-child {
118
+ border-bottom-right-radius: 15px;
119
+ border-right: 1px solid var(--block-border-color);
120
+ }
121
+
122
+ .buttons button:hover {
123
+ background: var(--background-fill-secondary-hover);
124
+ font-weight: var(--weight-bold);
125
+ }
126
+
127
+ .buttons button.active {
128
+ background: var(--background-fill-secondary);
129
+ font-weight: var(--weight-bold);
130
+ }
131
+
132
+ .buttons {
133
+ height: 20px;
134
+
135
+ display: flex;
136
+ justify-content: stretch;
137
+ gap: 0px;
138
+ /* padding: 0 10px; */
139
+ }
140
+
141
+ .input-wrap {
142
+ display: flex;
143
+ }
144
+
145
+ .eyedropper {
146
+ display: flex;
147
+ align-items: center;
148
+ justify-content: center;
149
+ width: 25px;
150
+ height: 30px;
151
+ border-top-right-radius: 15px;
152
+ border: 1px solid var(--block-border-color);
153
+ border-left: none;
154
+ background: var(--background-fill-secondary);
155
+ height: 30px;
156
+ padding: 7px 7px 5px 0px;
157
+ cursor: pointer;
158
+ }
159
+ </style>
@@ -0,0 +1,20 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ color: string;
5
+ current_mode?: ("hex" | "rgb" | "hsl") | undefined;
6
+ };
7
+ events: {
8
+ selected: CustomEvent<string>;
9
+ close: CustomEvent<void>;
10
+ } & {
11
+ [evt: string]: CustomEvent<any>;
12
+ };
13
+ slots: {};
14
+ };
15
+ export type ColorFieldProps = typeof __propDef.props;
16
+ export type ColorFieldEvents = typeof __propDef.events;
17
+ export type ColorFieldSlots = typeof __propDef.slots;
18
+ export default class ColorField extends SvelteComponent<ColorFieldProps, ColorFieldEvents, ColorFieldSlots> {
19
+ }
20
+ export {};
@@ -0,0 +1,179 @@
1
+ <script>import { tick } from "svelte";
2
+ import tinycolor from "tinycolor2";
3
+ import { clamp } from "../utils/pixi";
4
+ export let color = "rgb(255, 255, 255)";
5
+ let name = "world";
6
+ let sl_marker_pos = [0, 0];
7
+ let sl_rect = null;
8
+ let sl_moving = false;
9
+ let sl = [0, 0];
10
+ let hue = 0;
11
+ let hue_marker_pos = 0;
12
+ let hue_rect = null;
13
+ let hue_moving = false;
14
+ function handle_hue_down(event) {
15
+ hue_rect = event.currentTarget.getBoundingClientRect();
16
+ hue_moving = true;
17
+ update_hue_from_mouse(event.clientX);
18
+ }
19
+ function update_hue_from_mouse(x) {
20
+ if (!hue_rect)
21
+ return;
22
+ const _x = clamp(x - hue_rect.left, 0, hue_rect.width);
23
+ hue_marker_pos = _x;
24
+ const _hue = _x / hue_rect.width * 360;
25
+ hue = _hue;
26
+ color = hsva_to_rgba({ h: _hue, s: sl[0], v: sl[1], a: 1 });
27
+ }
28
+ function hsva_to_rgba(hsva) {
29
+ const saturation = hsva.s;
30
+ const value = hsva.v;
31
+ let chroma = saturation * value;
32
+ const hue_by_60 = hsva.h / 60;
33
+ let x = chroma * (1 - Math.abs(hue_by_60 % 2 - 1));
34
+ const m = value - chroma;
35
+ chroma = chroma + m;
36
+ x = x + m;
37
+ const index = Math.floor(hue_by_60) % 6;
38
+ const red = [chroma, x, m, m, x, chroma][index];
39
+ const green = [x, chroma, chroma, x, m, m][index];
40
+ const blue = [m, m, x, chroma, chroma, x][index];
41
+ return `rgba(${red * 255}, ${green * 255}, ${blue * 255}, ${hsva.a})`;
42
+ }
43
+ function update_color_from_mouse(x, y) {
44
+ if (!sl_rect)
45
+ return;
46
+ const _x = clamp(x - sl_rect.left, 0, sl_rect.width);
47
+ const _y = clamp(y - sl_rect.top, 0, sl_rect.height);
48
+ sl_marker_pos = [_x, _y];
49
+ const _hsva = {
50
+ h: hue * 1,
51
+ s: _x / sl_rect.width,
52
+ v: 1 - _y / sl_rect.height,
53
+ a: 1
54
+ };
55
+ sl = [_hsva.s, _hsva.v];
56
+ color = hsva_to_rgba(_hsva);
57
+ }
58
+ function handle_sl_down(event) {
59
+ sl_moving = true;
60
+ sl_rect = event.currentTarget.getBoundingClientRect();
61
+ update_color_from_mouse(event.clientX, event.clientY);
62
+ }
63
+ function handle_move(event) {
64
+ if (sl_moving)
65
+ update_color_from_mouse(event.clientX, event.clientY);
66
+ if (hue_moving)
67
+ update_hue_from_mouse(event.clientX);
68
+ }
69
+ function handle_end() {
70
+ if (sl_moving)
71
+ sl_moving = false;
72
+ if (hue_moving)
73
+ hue_moving = false;
74
+ }
75
+ async function update_mouse_from_color(color2) {
76
+ if (sl_moving || hue_moving)
77
+ return;
78
+ await tick();
79
+ if (!color2)
80
+ return;
81
+ if (!sl_rect) {
82
+ sl_rect = sl_wrap.getBoundingClientRect();
83
+ }
84
+ if (!hue_rect) {
85
+ hue_rect = hue_wrap.getBoundingClientRect();
86
+ }
87
+ const hsva = tinycolor(color2).toHsv();
88
+ const _x = hsva.s * sl_rect.width;
89
+ const _y = (1 - hsva.v) * sl_rect.height;
90
+ sl_marker_pos = [_x, _y];
91
+ sl = [hsva.s, hsva.v];
92
+ hue = hsva.h;
93
+ hue_marker_pos = hsva.h / 360 * hue_rect.width;
94
+ }
95
+ $:
96
+ update_mouse_from_color(color);
97
+ let sl_wrap;
98
+ let hue_wrap;
99
+ </script>
100
+
101
+ <svelte:window on:mousemove={handle_move} on:mouseup={handle_end} />
102
+
103
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
104
+ <div
105
+ class="color-gradient"
106
+ on:mousedown={handle_sl_down}
107
+ style="--hue:{hue}"
108
+ bind:this={sl_wrap}
109
+ >
110
+ <div
111
+ class="marker"
112
+ style:transform="translate({sl_marker_pos[0]}px,{sl_marker_pos[1]}px)"
113
+ style:background={color}
114
+ />
115
+ </div>
116
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
117
+ <div class="hue-slider" on:mousedown={handle_hue_down} bind:this={hue_wrap}>
118
+ <div
119
+ class="marker"
120
+ style:background={"hsl(" + hue + ", 100%, 50%)"}
121
+ style:transform="translateX({hue_marker_pos}px)"
122
+ />
123
+ </div>
124
+
125
+ <style>
126
+ .hue-slider {
127
+ position: relative;
128
+ width: 90%;
129
+ margin: 10px auto;
130
+ height: 10px;
131
+ border-radius: 5px;
132
+ background: linear-gradient(
133
+ to right,
134
+ hsl(0, 100%, 50%) 0%,
135
+ #ff0 17%,
136
+ lime 33%,
137
+ cyan 50%,
138
+ blue 67%,
139
+ magenta 83%,
140
+ red 100%
141
+ );
142
+ border-top: none;
143
+ }
144
+
145
+ .color-gradient {
146
+ position: relative;
147
+ --hue: white;
148
+
149
+ background: linear-gradient(rgba(0, 0, 0, 0), #000),
150
+ linear-gradient(90deg, #fff, hsl(var(--hue), 100%, 50%));
151
+ width: 100%;
152
+ height: 150px;
153
+ border-top-left-radius: 4px;
154
+ border-top-right-radius: 4px;
155
+ }
156
+
157
+ .marker {
158
+ position: absolute;
159
+ width: 14px;
160
+ height: 14px;
161
+ border-radius: 50%;
162
+ border: 2px solid white;
163
+
164
+ top: -7px;
165
+ left: -7px;
166
+ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.1);
167
+ pointer-events: none;
168
+ }
169
+
170
+ .hue-slider > .marker {
171
+ box-shadow: 0 0 1px #888;
172
+ top: -3px;
173
+ margin: auto;
174
+ height: 16px;
175
+ width: 16px;
176
+ left: -8px;
177
+ border: 2px solid white;
178
+ }
179
+ </style>
@@ -0,0 +1,16 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ color?: string | undefined;
5
+ };
6
+ events: {
7
+ [evt: string]: CustomEvent<any>;
8
+ };
9
+ slots: {};
10
+ };
11
+ export type ColorPickerProps = typeof __propDef.props;
12
+ export type ColorPickerEvents = typeof __propDef.events;
13
+ export type ColorPickerSlots = typeof __propDef.slots;
14
+ export default class ColorPicker extends SvelteComponent<ColorPickerProps, ColorPickerEvents, ColorPickerSlots> {
15
+ }
16
+ export {};