@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.
Files changed (131) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/Example.svelte +1 -1
  3. package/IMAGE_EDITOR_OVERVIEW.md +224 -0
  4. package/ImageEditor.stories.svelte +13 -5
  5. package/Index.svelte +46 -45
  6. package/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +65 -103
  7. package/README.md +2 -0
  8. package/dist/Example.svelte.d.ts +1 -1
  9. package/dist/Index.svelte +35 -33
  10. package/dist/Index.svelte.d.ts +25 -16
  11. package/dist/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +54 -88
  12. package/dist/{shared/InteractiveImageEditor.svelte.d.ts → InteractiveImageEditor.svelte.d.ts} +17 -15
  13. package/dist/shared/Anchor.svelte +311 -0
  14. package/dist/shared/Anchor.svelte.d.ts +18 -0
  15. package/dist/shared/Controls.svelte +169 -18
  16. package/dist/shared/Controls.svelte.d.ts +9 -2
  17. package/dist/shared/{tools/IconButton.svelte → IconButton.svelte} +19 -3
  18. package/dist/shared/{tools/IconButton.svelte.d.ts → IconButton.svelte.d.ts} +4 -1
  19. package/dist/shared/ImageEditor.svelte +572 -289
  20. package/dist/shared/ImageEditor.svelte.d.ts +54 -56
  21. package/dist/shared/Layers.svelte +260 -0
  22. package/dist/shared/Layers.svelte.d.ts +37 -0
  23. package/dist/shared/Resize.svelte +218 -0
  24. package/dist/shared/Resize.svelte.d.ts +29 -0
  25. package/dist/shared/SecondaryToolbar.svelte +55 -0
  26. package/dist/shared/SecondaryToolbar.svelte.d.ts +37 -0
  27. package/dist/shared/Toolbar.svelte +337 -0
  28. package/dist/shared/Toolbar.svelte.d.ts +42 -0
  29. package/dist/shared/{tools → brush}/BrushOptions.svelte +68 -64
  30. package/dist/shared/{tools → brush}/BrushOptions.svelte.d.ts +9 -9
  31. package/dist/shared/{tools → brush}/BrushSize.svelte +2 -27
  32. package/dist/shared/{tools → brush}/ColorField.svelte +2 -1
  33. package/dist/shared/{tools → brush}/ColorField.svelte.d.ts +1 -0
  34. package/dist/shared/{tools → brush}/ColorPicker.svelte +81 -9
  35. package/dist/shared/{tools → brush}/ColorPicker.svelte.d.ts +1 -0
  36. package/dist/shared/{tools → brush}/ColorSwatch.svelte +78 -38
  37. package/dist/shared/{tools → brush}/ColorSwatch.svelte.d.ts +6 -2
  38. package/dist/shared/brush/brush-cursor.d.ts +101 -0
  39. package/dist/shared/brush/brush-cursor.js +327 -0
  40. package/dist/shared/brush/brush-textures.d.ts +65 -0
  41. package/dist/shared/brush/brush-textures.js +385 -0
  42. package/dist/shared/brush/brush-utils.d.ts +32 -0
  43. package/dist/shared/brush/brush-utils.js +59 -0
  44. package/dist/shared/brush/brush.d.ts +152 -0
  45. package/dist/shared/brush/brush.js +397 -0
  46. package/dist/shared/brush/types.d.ts +37 -0
  47. package/dist/shared/brush/types.js +1 -0
  48. package/dist/shared/core/editor.d.ts +261 -0
  49. package/dist/shared/core/editor.js +1264 -0
  50. package/dist/shared/crop/crop.d.ts +201 -0
  51. package/dist/shared/crop/crop.js +727 -0
  52. package/dist/shared/image/image.d.ts +89 -0
  53. package/dist/shared/image/image.js +183 -0
  54. package/dist/shared/resize/resize.d.ts +270 -0
  55. package/dist/shared/resize/resize.js +1413 -0
  56. package/dist/shared/types.d.ts +16 -0
  57. package/dist/shared/utils/pixi.d.ts +16 -57
  58. package/dist/shared/utils/pixi.js +15 -113
  59. package/dist/shared/zoom/zoom.d.ts +136 -0
  60. package/dist/shared/zoom/zoom.js +548 -0
  61. package/package.json +8 -7
  62. package/shared/Anchor.svelte +384 -0
  63. package/shared/Controls.svelte +178 -37
  64. package/shared/{tools/IconButton.svelte → IconButton.svelte} +21 -4
  65. package/shared/ImageEditor.svelte +712 -350
  66. package/shared/Layers.svelte +282 -0
  67. package/shared/Resize.svelte +239 -0
  68. package/shared/SecondaryToolbar.svelte +67 -0
  69. package/shared/Toolbar.svelte +386 -0
  70. package/shared/brush/BRUSH_TOOL.md +134 -0
  71. package/shared/brush/BrushOptions.svelte +200 -0
  72. package/shared/{tools → brush}/BrushSize.svelte +2 -30
  73. package/shared/{tools → brush}/ColorField.svelte +3 -1
  74. package/shared/{tools → brush}/ColorPicker.svelte +86 -9
  75. package/shared/{tools → brush}/ColorSwatch.svelte +95 -42
  76. package/shared/brush/brush-cursor.ts +408 -0
  77. package/shared/brush/brush-textures.ts +485 -0
  78. package/shared/brush/brush-utils.ts +76 -0
  79. package/shared/brush/brush.ts +510 -0
  80. package/shared/brush/types.ts +41 -0
  81. package/shared/core/EDITOR.md +182 -0
  82. package/shared/core/editor.ts +1788 -0
  83. package/shared/crop/CROP.md +139 -0
  84. package/shared/crop/crop.ts +1027 -0
  85. package/shared/image/IMAGE.md +135 -0
  86. package/shared/image/image.ts +298 -0
  87. package/shared/resize/resize.ts +1894 -0
  88. package/shared/types.ts +19 -0
  89. package/shared/utils/pixi.ts +19 -246
  90. package/shared/zoom/zoom.ts +729 -0
  91. package/dist/shared/layers/Layers.svelte +0 -231
  92. package/dist/shared/layers/Layers.svelte.d.ts +0 -18
  93. package/dist/shared/layers/utils.d.ts +0 -73
  94. package/dist/shared/layers/utils.js +0 -156
  95. package/dist/shared/tools/Brush.svelte +0 -215
  96. package/dist/shared/tools/Brush.svelte.d.ts +0 -29
  97. package/dist/shared/tools/Crop.svelte +0 -155
  98. package/dist/shared/tools/Crop.svelte.d.ts +0 -16
  99. package/dist/shared/tools/Cropper.svelte +0 -271
  100. package/dist/shared/tools/Cropper.svelte.d.ts +0 -41
  101. package/dist/shared/tools/Handle.svelte +0 -260
  102. package/dist/shared/tools/Handle.svelte.d.ts +0 -29
  103. package/dist/shared/tools/Sources.svelte +0 -257
  104. package/dist/shared/tools/Sources.svelte.d.ts +0 -34
  105. package/dist/shared/tools/Tools.svelte +0 -102
  106. package/dist/shared/tools/Tools.svelte.d.ts +0 -48
  107. package/dist/shared/tools/brush.d.ts +0 -62
  108. package/dist/shared/tools/brush.js +0 -133
  109. package/dist/shared/tools/crop.d.ts +0 -15
  110. package/dist/shared/tools/crop.js +0 -154
  111. package/dist/shared/tools/index.d.ts +0 -5
  112. package/dist/shared/tools/index.js +0 -5
  113. package/dist/shared/tools/sources.d.ts +0 -46
  114. package/dist/shared/tools/sources.js +0 -121
  115. package/dist/shared/tools/types.d.ts +0 -1
  116. package/shared/layers/Layers.svelte +0 -250
  117. package/shared/layers/utils.ts +0 -294
  118. package/shared/tools/Brush.svelte +0 -280
  119. package/shared/tools/BrushOptions.svelte +0 -180
  120. package/shared/tools/Crop.svelte +0 -189
  121. package/shared/tools/Cropper.svelte +0 -346
  122. package/shared/tools/Handle.svelte +0 -289
  123. package/shared/tools/Sources.svelte +0 -283
  124. package/shared/tools/Tools.svelte +0 -162
  125. package/shared/tools/brush.ts +0 -247
  126. package/shared/tools/crop.ts +0 -213
  127. package/shared/tools/index.ts +0 -5
  128. package/shared/tools/sources.ts +0 -195
  129. package/shared/tools/types.ts +0 -1
  130. /package/dist/shared/{tools → brush}/BrushSize.svelte.d.ts +0 -0
  131. /package/dist/shared/{tools/types.js → types.js} +0 -0
@@ -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
- <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
- >
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: 100%;
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();
@@ -7,6 +7,7 @@ declare const __propDef: {
7
7
  events: {
8
8
  selected: CustomEvent<string>;
9
9
  close: CustomEvent<void>;
10
+ add_color: CustomEvent<void>;
10
11
  } & {
11
12
  [evt: string]: CustomEvent<any>;
12
13
  };
@@ -1,8 +1,7 @@
1
- <script>import { tick } from "svelte";
1
+ <script>import { onMount, tick } from "svelte";
2
2
  import tinycolor from "tinycolor2";
3
3
  import { clamp } from "../utils/pixi";
4
4
  export let color = "rgb(255, 255, 255)";
5
- let name = "world";
6
5
  let sl_marker_pos = [0, 0];
7
6
  let sl_rect = null;
8
7
  let sl_moving = false;
@@ -11,6 +10,7 @@ let hue = 0;
11
10
  let hue_marker_pos = 0;
12
11
  let hue_rect = null;
13
12
  let hue_moving = false;
13
+ let opacity_moving = false;
14
14
  function handle_hue_down(event) {
15
15
  hue_rect = event.currentTarget.getBoundingClientRect();
16
16
  hue_moving = true;
@@ -65,12 +65,16 @@ function handle_move(event) {
65
65
  update_color_from_mouse(event.clientX, event.clientY);
66
66
  if (hue_moving)
67
67
  update_hue_from_mouse(event.clientX);
68
+ if (opacity_moving)
69
+ update_opacity_from_mouse(event.clientX);
68
70
  }
69
71
  function handle_end() {
70
72
  if (sl_moving)
71
73
  sl_moving = false;
72
74
  if (hue_moving)
73
75
  hue_moving = false;
76
+ if (opacity_moving)
77
+ opacity_moving = false;
74
78
  }
75
79
  async function update_mouse_from_color(color2) {
76
80
  if (sl_moving || hue_moving)
@@ -96,6 +100,23 @@ $:
96
100
  update_mouse_from_color(color);
97
101
  let sl_wrap;
98
102
  let hue_wrap;
103
+ export let opacity = 1;
104
+ let opacity_wrap;
105
+ function handle_opacity_down(event) {
106
+ opacity_rect = event.currentTarget.getBoundingClientRect();
107
+ opacity_moving = true;
108
+ update_opacity_from_mouse(event.clientX);
109
+ }
110
+ let opacity_rect = null;
111
+ function update_opacity_from_mouse(x) {
112
+ if (!opacity_rect)
113
+ return;
114
+ const _x = clamp(x - opacity_rect.left, 0, opacity_rect.width);
115
+ opacity = _x / opacity_rect.width;
116
+ }
117
+ onMount(() => {
118
+ opacity_rect = opacity_wrap.getBoundingClientRect();
119
+ });
99
120
  </script>
100
121
 
101
122
  <svelte:window on:mousemove={handle_move} on:mouseup={handle_end} />
@@ -114,6 +135,19 @@ let hue_wrap;
114
135
  />
115
136
  </div>
116
137
  <!-- svelte-ignore a11y-no-static-element-interactions -->
138
+ <div
139
+ class="opacity-slider"
140
+ on:mousedown={handle_opacity_down}
141
+ style="--color:{color === 'auto' ? 'transparent' : color}"
142
+ bind:this={opacity_wrap}
143
+ >
144
+ <div
145
+ class="opacity-marker"
146
+ style:background="white"
147
+ style:transform="translateX({opacity * (opacity_rect?.width ?? 1)}px)"
148
+ />
149
+ </div>
150
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
117
151
  <div class="hue-slider" on:mousedown={handle_hue_down} bind:this={hue_wrap}>
118
152
  <div
119
153
  class="marker"
@@ -126,9 +160,10 @@ let hue_wrap;
126
160
  .hue-slider {
127
161
  position: relative;
128
162
  width: 90%;
129
- margin: 10px auto;
130
- height: 10px;
131
- border-radius: 5px;
163
+ margin: 0px auto 10px auto;
164
+ height: 12px;
165
+ border-radius: 2px;
166
+ border: 1px solid var(--block-border-color);
132
167
  background: linear-gradient(
133
168
  to right,
134
169
  hsl(0, 100%, 50%) 0%,
@@ -142,6 +177,41 @@ let hue_wrap;
142
177
  border-top: none;
143
178
  }
144
179
 
180
+ .opacity-slider {
181
+ position: relative;
182
+ width: 90%;
183
+ margin: 10px auto 5px auto;
184
+ height: 12px;
185
+ border-radius: 2px;
186
+ border: 1px solid var(--block-border-color);
187
+ /* background: linear-gradient(45deg, #808080 25%, transparent 25%),
188
+ linear-gradient(-45deg, #808080 25%, transparent 25%),
189
+ linear-gradient(45deg, transparent 75%, #808080 75%),
190
+ linear-gradient(-45deg, transparent 75%, #808080 75%); */
191
+ background:
192
+ linear-gradient(to right, transparent, var(--color)),
193
+ repeating-conic-gradient(#808080 0% 25%, transparent 0% 50%) 0 0 / 10px
194
+ 10px;
195
+ }
196
+
197
+ .opacity-marker {
198
+ position: absolute;
199
+ width: 16px;
200
+ height: 16px;
201
+ border-radius: 50%;
202
+ }
203
+
204
+ .opacity-slider > .opacity-marker {
205
+ box-shadow: 0 0 1px #888;
206
+ top: -4px;
207
+ margin: auto;
208
+ height: 18px;
209
+ width: 18px;
210
+ left: -9px;
211
+ margin: auto;
212
+ border: 1px solid var(--block-border-color);
213
+ }
214
+
145
215
  .color-gradient {
146
216
  position: relative;
147
217
  --hue: white;
@@ -165,15 +235,17 @@ let hue_wrap;
165
235
  left: -7px;
166
236
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.1);
167
237
  pointer-events: none;
238
+ border: 1px solid var(--block-border-color);
168
239
  }
169
240
 
170
241
  .hue-slider > .marker {
171
242
  box-shadow: 0 0 1px #888;
172
243
  top: -3px;
173
244
  margin: auto;
174
- height: 16px;
175
- width: 16px;
176
- left: -8px;
177
- border: 2px solid white;
245
+ height: 18px;
246
+ width: 18px;
247
+ left: -9px;
248
+
249
+ border: 1px solid var(--block-border-color);
178
250
  }
179
251
  </style>
@@ -2,6 +2,7 @@ import { SvelteComponent } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
4
  color?: string | undefined;
5
+ opacity?: number | undefined;
5
6
  };
6
7
  events: {
7
8
  [evt: string]: CustomEvent<any>;
@@ -1,26 +1,43 @@
1
1
  <script>import tinycolor from "tinycolor2";
2
2
  import { createEventDispatcher } from "svelte";
3
+ import IconButton from "../IconButton.svelte";
4
+ import { Plus } from "@gradio/icons";
3
5
  export let selected_color;
4
6
  export let colors;
5
7
  export let user_colors = [];
6
- import { Palette } from "@gradio/icons";
7
8
  export let show_empty = false;
8
9
  export let current_mode = "hex";
9
10
  export let color_picker = false;
10
11
  const dispatch = createEventDispatcher();
11
12
  $:
12
13
  _colors = show_empty ? colors : colors.filter((c) => c);
14
+ function get_color(color_input) {
15
+ if (Array.isArray(color_input)) {
16
+ return color_input[0];
17
+ }
18
+ return color_input;
19
+ }
20
+ function get_opacity(color_input) {
21
+ if (Array.isArray(color_input)) {
22
+ return color_input[1];
23
+ }
24
+ const color = tinycolor(color_input);
25
+ return color.getAlpha();
26
+ }
13
27
  function get_formatted_color(color, mode) {
28
+ const color_value = get_color(color);
14
29
  if (mode === "hex") {
15
- return tinycolor(color).toHexString();
30
+ return tinycolor(color_value).toHexString();
16
31
  } else if (mode === "rgb") {
17
- return tinycolor(color).toRgbString();
32
+ return tinycolor(color_value).toRgbString();
18
33
  }
19
- return tinycolor(color).toHslString();
34
+ return tinycolor(color_value).toHslString();
20
35
  }
21
36
  let current_index = `select-${colors.findIndex(
22
37
  (c) => get_formatted_color(c, current_mode) === get_formatted_color(selected_color, current_mode)
23
38
  )}`;
39
+ $:
40
+ selected_opacity = get_opacity(selected_color);
24
41
  function handle_select(type, detail) {
25
42
  current_index = `${type}-${detail.index}`;
26
43
  dispatch(type, detail);
@@ -36,19 +53,34 @@ function handle_picker_click() {
36
53
  {/if}
37
54
 
38
55
  <div class="swatch-wrap">
39
- <span class="icon-wrap">
40
- <Palette />
41
- </span>
42
- <div>
56
+ <div class="swatch-container">
43
57
  {#if user_colors}
44
58
  <div class="swatch">
59
+ {#if color_picker}
60
+ <IconButton
61
+ Icon={Plus}
62
+ on:click={() => dispatch("add_color")}
63
+ roundedness="very"
64
+ background={get_color(selected_color)}
65
+ color="white"
66
+ />
67
+ {/if}
45
68
  {#each user_colors as color, i}
69
+ {@const color_string = get_color(color)}
70
+ {@const opacity = get_opacity(color)}
46
71
  <button
47
- on:click={() => handle_select("edit", { index: i, color })}
72
+ on:click={() =>
73
+ handle_select("edit", {
74
+ index: i,
75
+ color: color_string,
76
+ opacity: opacity
77
+ })}
48
78
  class="color"
49
79
  class:empty={color === null}
50
- style="background-color: {color}"
51
- class:selected={`edit-${i}` === current_index}
80
+ style="background-color: {color_string}"
81
+ style:opacity
82
+ class:selected={`${color_string}-${opacity}` ===
83
+ `${selected_color}-${selected_opacity}`}
52
84
  ></button>
53
85
  {/each}
54
86
 
@@ -60,13 +92,22 @@ function handle_picker_click() {
60
92
  </div>
61
93
  {/if}
62
94
  <menu class="swatch">
63
- {#each _colors as color, i}
95
+ {#each _colors as color_item, i}
96
+ {@const color_string = get_color(color_item)}
97
+ {@const opacity = get_opacity(color_item)}
64
98
  <button
65
- on:click={() => handle_select("select", { index: i, color })}
99
+ on:click={() =>
100
+ handle_select("select", {
101
+ index: i,
102
+ color: color_string,
103
+ opacity: opacity
104
+ })}
66
105
  class="color"
67
- class:empty={color === null}
68
- style="background-color: {color}"
69
- class:selected={`select-${i}` === current_index}
106
+ class:empty={color_item === null}
107
+ style="background-color: {color_string}"
108
+ style:opacity
109
+ class:selected={`${color_string}-${opacity}` ===
110
+ `${selected_color}-${selected_opacity}`}
70
111
  ></button>
71
112
  {/each}
72
113
  </menu>
@@ -74,32 +115,31 @@ function handle_picker_click() {
74
115
  </div>
75
116
 
76
117
  <style>
77
- .icon-wrap {
78
- width: 18px;
79
- margin-top: 6px;
80
-
81
- margin-left: var(--size-4);
82
- }
83
-
84
118
  .swatch-wrap {
85
119
  display: flex;
86
120
  justify-content: space-between;
87
121
  align-items: flex-start;
88
- }
89
- span {
90
- margin-top: 0px;
122
+ /* max-width: 200px; */
123
+ width: 205px;
91
124
  }
92
125
 
93
126
  span.lg {
94
- margin-top: var(--spacing-xl);
127
+ margin-top: var(--spacing-sm);
95
128
  }
96
- .swatch {
129
+ .swatch-container {
97
130
  display: flex;
98
- gap: var(--size-2-5);
99
- justify-content: space-around;
100
- margin-bottom: var(--size-2);
101
- margin-right: var(--size-6);
102
- padding-left: var(--size-2);
131
+ flex-direction: column;
132
+ gap: 10px;
133
+ width: 100%;
134
+ }
135
+ .swatch {
136
+ display: grid;
137
+ grid-template-columns: repeat(auto-fill, 25px);
138
+ gap: 8px;
139
+ justify-content: flex-start;
140
+
141
+ overflow: hidden;
142
+ justify-content: center;
103
143
  }
104
144
 
105
145
  .empty {
@@ -120,9 +160,9 @@ function handle_picker_click() {
120
160
  }
121
161
 
122
162
  .color {
123
- width: 30px;
124
- height: 30px;
125
- border-radius: 50%;
163
+ width: 25px;
164
+ height: 25px;
165
+ border-radius: var(--radius-md);
126
166
  }
127
167
 
128
168
  .empty.selected,
@@ -163,14 +203,14 @@ function handle_picker_click() {
163
203
  .colorpicker::after {
164
204
  display: flex;
165
205
  justify-content: center;
166
- align-content: center;
206
+ align-items: center;
167
207
  content: "⨯";
168
208
  color: white;
169
209
  font-size: var(--scale-5);
170
210
  position: absolute;
171
211
  width: 100%;
172
212
  height: 100%;
173
- transform: translateY(-17px);
213
+ transform: translateY(-7px);
174
214
  opacity: 1;
175
215
  transition: 0.1s;
176
216
  top: 0;
@@ -1,9 +1,11 @@
1
1
  import { SvelteComponent } from "svelte";
2
+ import type { ColorTuple } from "./types";
3
+ import type { ColorInput } from "tinycolor2";
2
4
  declare const __propDef: {
3
5
  props: {
4
6
  selected_color: string;
5
- colors: string[];
6
- user_colors?: ((string | null)[] | null) | undefined;
7
+ colors: (ColorInput | ColorTuple)[];
8
+ user_colors?: ((ColorInput | ColorTuple)[] | null) | undefined;
7
9
  show_empty?: boolean | undefined;
8
10
  current_mode?: ("hex" | "rgb" | "hsl") | undefined;
9
11
  color_picker?: boolean | undefined;
@@ -12,11 +14,13 @@ declare const __propDef: {
12
14
  select: CustomEvent<{
13
15
  index: number | null;
14
16
  color: string | null;
17
+ opacity?: number;
15
18
  }>;
16
19
  edit: CustomEvent<{
17
20
  index: number;
18
21
  color: string | null;
19
22
  }>;
23
+ add_color: CustomEvent<void>;
20
24
  } & {
21
25
  [evt: string]: CustomEvent<any>;
22
26
  };
@@ -0,0 +1,101 @@
1
+ import { type FederatedPointerEvent } from "pixi.js";
2
+ import { type ImageEditorContext } from "../core/editor";
3
+ import { type BrushState } from "./types";
4
+ /**
5
+ * Class to handle all cursor preview-related functionality for the brush tool.
6
+ */
7
+ export declare class BrushCursor {
8
+ private image_editor_context;
9
+ private state;
10
+ private scale;
11
+ private cursor_graphics;
12
+ private cursor_container;
13
+ private brush_preview_container;
14
+ private brush_preview_graphics;
15
+ private is_preview_visible;
16
+ private is_cursor_over_image;
17
+ private cursor_position_check_timeout;
18
+ private is_brush_or_erase_active;
19
+ private _bound_update_cursor;
20
+ private _bound_check_cursor_over_image;
21
+ constructor(image_editor_context: ImageEditorContext, state: BrushState, scale: number);
22
+ /**
23
+ * Returns whether the cursor is currently over the image.
24
+ */
25
+ is_over_image(): boolean;
26
+ /**
27
+ * Sets up cursor-related event listeners.
28
+ */
29
+ setup_event_listeners(): void;
30
+ /**
31
+ * Removes all cursor-related event listeners.
32
+ */
33
+ cleanup_event_listeners(): void;
34
+ /**
35
+ * initializes the cursor for the brush tool.
36
+ */
37
+ initialize_cursor(): void;
38
+ /**
39
+ * updates the appearance of the cursor.
40
+ */
41
+ update_cursor_appearance(): void;
42
+ /**
43
+ * updates the position of the cursor.
44
+ * @param {FederatedPointerEvent} event - The pointer event.
45
+ */
46
+ update_cursor_position(event: FederatedPointerEvent): void;
47
+ /**
48
+ * checks if the cursor is over the image container.
49
+ * @param {FederatedPointerEvent} event - The pointer event.
50
+ */
51
+ check_cursor_over_image(event: FederatedPointerEvent): void;
52
+ /**
53
+ * updates the size of the cursor.
54
+ */
55
+ update_cursor_size(): void;
56
+ /**
57
+ * Updates whether brush or erase tool is active
58
+ */
59
+ set_active(is_active: boolean): void;
60
+ /**
61
+ * updates the visibility of the cursor.
62
+ */
63
+ update_cursor_visibility(): void;
64
+ /**
65
+ * Shows or hides the brush preview.
66
+ * @param {boolean} show - Whether to show the preview.
67
+ */
68
+ preview_brush(show: boolean): void;
69
+ /**
70
+ * initializes the brush preview.
71
+ */
72
+ initialize_brush_preview(): void;
73
+ /**
74
+ * updates the brush preview appearance.
75
+ */
76
+ update_brush_preview(): void;
77
+ /**
78
+ * updates the position of the brush preview to center of canvas.
79
+ */
80
+ update_brush_preview_position(): void;
81
+ /**
82
+ * Called when the pointer enters the image container.
83
+ */
84
+ on_image_container_pointer_enter(): void;
85
+ /**
86
+ * Called when the pointer leaves the image container.
87
+ */
88
+ on_image_container_pointer_leave(): void;
89
+ /**
90
+ * Updates both cursor and preview visibility based on cursor position.
91
+ */
92
+ update_cursor_and_preview_visibility(): void;
93
+ /**
94
+ * Cleans up all cursor resources.
95
+ */
96
+ cleanup(): void;
97
+ /**
98
+ * Updates the brush state.
99
+ */
100
+ update_state(state: BrushState, scale: number): void;
101
+ }