@gradio/imageeditor 0.10.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 (63) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/Index.svelte +5 -2
  3. package/dist/Example.svelte +41 -0
  4. package/dist/Example.svelte.d.ts +19 -0
  5. package/dist/Index.svelte +184 -0
  6. package/dist/Index.svelte.d.ts +192 -0
  7. package/dist/shared/Controls.svelte +73 -0
  8. package/dist/shared/Controls.svelte.d.ts +24 -0
  9. package/dist/shared/ImageEditor.svelte +329 -0
  10. package/dist/shared/ImageEditor.svelte.d.ts +79 -0
  11. package/dist/shared/InteractiveImageEditor.svelte +273 -0
  12. package/dist/shared/InteractiveImageEditor.svelte.d.ts +58 -0
  13. package/dist/shared/layers/Layers.svelte +216 -0
  14. package/dist/shared/layers/Layers.svelte.d.ts +18 -0
  15. package/dist/shared/layers/utils.d.ts +69 -0
  16. package/dist/shared/layers/utils.js +131 -0
  17. package/dist/shared/tools/Brush.svelte +208 -0
  18. package/dist/shared/tools/Brush.svelte.d.ts +29 -0
  19. package/dist/shared/tools/BrushOptions.svelte +162 -0
  20. package/dist/shared/tools/BrushOptions.svelte.d.ts +29 -0
  21. package/dist/shared/tools/BrushSize.svelte +60 -0
  22. package/dist/shared/tools/BrushSize.svelte.d.ts +20 -0
  23. package/dist/shared/tools/ColorField.svelte +159 -0
  24. package/dist/shared/tools/ColorField.svelte.d.ts +20 -0
  25. package/dist/shared/tools/ColorPicker.svelte +179 -0
  26. package/dist/shared/tools/ColorPicker.svelte.d.ts +16 -0
  27. package/dist/shared/tools/ColorSwatch.svelte +183 -0
  28. package/dist/shared/tools/ColorSwatch.svelte.d.ts +30 -0
  29. package/dist/shared/tools/Crop.svelte +155 -0
  30. package/dist/shared/tools/Crop.svelte.d.ts +16 -0
  31. package/dist/shared/tools/Cropper.svelte +271 -0
  32. package/dist/shared/tools/Cropper.svelte.d.ts +41 -0
  33. package/dist/shared/tools/Handle.svelte +260 -0
  34. package/dist/shared/tools/Handle.svelte.d.ts +29 -0
  35. package/dist/shared/tools/Sources.svelte +250 -0
  36. package/dist/shared/tools/Sources.svelte.d.ts +32 -0
  37. package/dist/shared/tools/Tools.svelte +101 -0
  38. package/dist/shared/tools/Tools.svelte.d.ts +48 -0
  39. package/dist/shared/tools/brush.d.ts +62 -0
  40. package/dist/shared/tools/brush.js +133 -0
  41. package/dist/shared/tools/crop.d.ts +15 -0
  42. package/dist/shared/tools/crop.js +154 -0
  43. package/dist/shared/tools/index.d.ts +5 -0
  44. package/dist/shared/tools/index.js +5 -0
  45. package/dist/shared/tools/sources.d.ts +40 -0
  46. package/dist/shared/tools/sources.js +69 -0
  47. package/dist/shared/tools/types.d.ts +1 -0
  48. package/dist/shared/tools/types.js +1 -0
  49. package/dist/shared/utils/commands.d.ts +96 -0
  50. package/dist/shared/utils/commands.js +65 -0
  51. package/dist/shared/utils/events.d.ts +7 -0
  52. package/dist/shared/utils/events.js +22 -0
  53. package/dist/shared/utils/parse_placeholder.d.ts +1 -0
  54. package/dist/shared/utils/parse_placeholder.js +19 -0
  55. package/dist/shared/utils/pixi.d.ts +76 -0
  56. package/dist/shared/utils/pixi.js +152 -0
  57. package/package.json +23 -12
  58. package/shared/ImageEditor.svelte +8 -4
  59. package/shared/InteractiveImageEditor.svelte +3 -1
  60. package/shared/tools/Brush.svelte +4 -6
  61. package/shared/tools/BrushOptions.svelte +1 -1
  62. package/shared/tools/Crop.svelte +2 -1
  63. package/shared/utils/pixi.ts +0 -1
@@ -0,0 +1,183 @@
1
+ <script>import tinycolor from "tinycolor2";
2
+ import { createEventDispatcher } from "svelte";
3
+ export let selected_color;
4
+ export let colors;
5
+ export let user_colors = [];
6
+ import { Palette } from "@gradio/icons";
7
+ export let show_empty = false;
8
+ export let current_mode = "hex";
9
+ export let color_picker = false;
10
+ const dispatch = createEventDispatcher();
11
+ $:
12
+ _colors = show_empty ? colors : colors.filter((c) => c);
13
+ function get_formatted_color(color, mode) {
14
+ if (mode === "hex") {
15
+ return tinycolor(color).toHexString();
16
+ } else if (mode === "rgb") {
17
+ return tinycolor(color).toRgbString();
18
+ }
19
+ return tinycolor(color).toHslString();
20
+ }
21
+ let current_index = `select-${colors.findIndex(
22
+ (c) => get_formatted_color(c, current_mode) === get_formatted_color(selected_color, current_mode)
23
+ )}`;
24
+ function handle_select(type, detail) {
25
+ current_index = `${type}-${detail.index}`;
26
+ dispatch(type, detail);
27
+ }
28
+ function handle_picker_click() {
29
+ dispatch("select", { index: null, color: selected_color });
30
+ color_picker = !color_picker;
31
+ }
32
+ </script>
33
+
34
+ {#if !color_picker}
35
+ <span class:lg={user_colors}></span>
36
+ {/if}
37
+
38
+ <div class="swatch-wrap">
39
+ <span class="icon-wrap">
40
+ <Palette />
41
+ </span>
42
+ <div>
43
+ {#if user_colors}
44
+ <div class="swatch">
45
+ {#each user_colors as color, i}
46
+ <button
47
+ on:click={() => handle_select("edit", { index: i, color })}
48
+ class="color"
49
+ class:empty={color === null}
50
+ style="background-color: {color}"
51
+ class:selected={`edit-${i}` === current_index}
52
+ ></button>
53
+ {/each}
54
+
55
+ <button
56
+ on:click={handle_picker_click}
57
+ class="color colorpicker"
58
+ class:hidden={!color_picker}
59
+ ></button>
60
+ </div>
61
+ {/if}
62
+ <menu class="swatch">
63
+ {#each _colors as color, i}
64
+ <button
65
+ on:click={() => handle_select("select", { index: i, color })}
66
+ class="color"
67
+ class:empty={color === null}
68
+ style="background-color: {color}"
69
+ class:selected={`select-${i}` === current_index}
70
+ ></button>
71
+ {/each}
72
+ </menu>
73
+ </div>
74
+ </div>
75
+
76
+ <style>
77
+ .icon-wrap {
78
+ width: 18px;
79
+ margin-top: 6px;
80
+
81
+ margin-left: var(--size-4);
82
+ }
83
+
84
+ .swatch-wrap {
85
+ display: flex;
86
+ justify-content: space-between;
87
+ align-items: flex-start;
88
+ }
89
+ span {
90
+ margin-top: 0px;
91
+ }
92
+
93
+ span.lg {
94
+ margin-top: var(--spacing-xl);
95
+ }
96
+ .swatch {
97
+ 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);
103
+ }
104
+
105
+ .empty {
106
+ border: 1px solid var(--block-border-color);
107
+ font-weight: var(--weight-bold);
108
+ display: flex;
109
+ justify-content: center;
110
+ align-items: center;
111
+ padding-top: 4px;
112
+ text-align: center;
113
+ font-size: var(--scale-0);
114
+ cursor: pointer;
115
+ }
116
+
117
+ .empty::after {
118
+ content: "+";
119
+ margin-bottom: var(--size-1);
120
+ }
121
+
122
+ .color {
123
+ width: 30px;
124
+ height: 30px;
125
+ border-radius: 50%;
126
+ }
127
+
128
+ .empty.selected,
129
+ .color.selected {
130
+ border: 2px solid var(--color-accent);
131
+ }
132
+
133
+ .colorpicker {
134
+ border: 1px solid var(--block-border-color);
135
+
136
+ background: conic-gradient(
137
+ red,
138
+ #ff0 60deg,
139
+ lime 120deg,
140
+ cyan 180deg,
141
+ blue 240deg,
142
+ magenta 300deg,
143
+ red 360deg
144
+ );
145
+ overflow: hidden;
146
+ position: relative;
147
+ color: white;
148
+ cursor: pointer;
149
+ }
150
+
151
+ .colorpicker::before {
152
+ content: "";
153
+ position: absolute;
154
+ width: 100%;
155
+ height: 100%;
156
+ background: rgba(0, 0, 0, 0.6);
157
+ opacity: 1;
158
+ transition: 0.1s;
159
+ top: 0;
160
+ left: 0;
161
+ }
162
+
163
+ .colorpicker::after {
164
+ display: flex;
165
+ justify-content: center;
166
+ align-content: center;
167
+ content: "⨯";
168
+ color: white;
169
+ font-size: var(--scale-5);
170
+ position: absolute;
171
+ width: 100%;
172
+ height: 100%;
173
+ transform: translateY(-17px);
174
+ opacity: 1;
175
+ transition: 0.1s;
176
+ top: 0;
177
+ }
178
+
179
+ .colorpicker.hidden::after,
180
+ .colorpicker.hidden::before {
181
+ opacity: 0;
182
+ }
183
+ </style>
@@ -0,0 +1,30 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ selected_color: string;
5
+ colors: string[];
6
+ user_colors?: ((string | null)[] | null) | undefined;
7
+ show_empty?: boolean | undefined;
8
+ current_mode?: ("hex" | "rgb" | "hsl") | undefined;
9
+ color_picker?: boolean | undefined;
10
+ };
11
+ events: {
12
+ select: CustomEvent<{
13
+ index: number | null;
14
+ color: string | null;
15
+ }>;
16
+ edit: CustomEvent<{
17
+ index: number;
18
+ color: string | null;
19
+ }>;
20
+ } & {
21
+ [evt: string]: CustomEvent<any>;
22
+ };
23
+ slots: {};
24
+ };
25
+ export type ColorSwatchProps = typeof __propDef.props;
26
+ export type ColorSwatchEvents = typeof __propDef.events;
27
+ export type ColorSwatchSlots = typeof __propDef.slots;
28
+ export default class ColorSwatch extends SvelteComponent<ColorSwatchProps, ColorSwatchEvents, ColorSwatchSlots> {
29
+ }
30
+ export {};
@@ -0,0 +1,155 @@
1
+ <script>import { getContext, onDestroy, onMount, tick } from "svelte";
2
+ import { TOOL_KEY } from "./Tools.svelte";
3
+ import { EDITOR_KEY } from "../ImageEditor.svelte";
4
+ import { crop_canvas, resize_and_reposition } from "./crop";
5
+ import Cropper from "./Cropper.svelte";
6
+ const { active_tool, register_tool } = getContext(TOOL_KEY);
7
+ const {
8
+ dimensions,
9
+ editor_box,
10
+ pixi,
11
+ crop,
12
+ command_manager,
13
+ current_history
14
+ } = getContext(EDITOR_KEY);
15
+ let cropper;
16
+ export let crop_constraint;
17
+ let _crop_constraint = null;
18
+ $: {
19
+ if (typeof crop_constraint === "string") {
20
+ const [w, h] = crop_constraint.split(":");
21
+ _crop_constraint = parseInt(w) / parseInt(h);
22
+ } else if (Array.isArray(crop_constraint)) {
23
+ _crop_constraint = crop_constraint[0] / crop_constraint[1];
24
+ }
25
+ }
26
+ let w_p = 1;
27
+ let h_p = 1;
28
+ let l_p = 0;
29
+ let t_p = 0;
30
+ let current_opacity = 0;
31
+ let manually_cropped = false;
32
+ $: {
33
+ if (!manually_cropped && _crop_constraint && $pixi && $active_tool) {
34
+ requestAnimationFrame(() => {
35
+ initial_crop();
36
+ });
37
+ }
38
+ }
39
+ let c = null;
40
+ async function initial_crop() {
41
+ if (c || $current_history.previous)
42
+ return;
43
+ const { new_height, new_width, x_offset, y_offset } = resize_and_reposition(
44
+ $editor_box.child_width,
45
+ $editor_box.child_height,
46
+ "c",
47
+ _crop_constraint,
48
+ $editor_box.child_width,
49
+ $editor_box.child_height
50
+ );
51
+ w_p = new_width / $editor_box.child_width;
52
+ h_p = new_height / $editor_box.child_height;
53
+ l_p = x_offset / $editor_box.child_width;
54
+ t_p = y_offset / $editor_box.child_height;
55
+ c = crop_canvas($pixi.renderer, $pixi.mask_container, crop, 0.2);
56
+ c.start(...$dimensions, current_crop, false);
57
+ c.continue(
58
+ [
59
+ l_p * $dimensions[0],
60
+ t_p * $dimensions[1],
61
+ w_p * $dimensions[0],
62
+ h_p * $dimensions[1]
63
+ ],
64
+ false
65
+ );
66
+ c.stop();
67
+ c.execute();
68
+ c = null;
69
+ current_opacity = 0;
70
+ }
71
+ function handle_crop(type, {
72
+ x,
73
+ y,
74
+ width,
75
+ height
76
+ }) {
77
+ if (!$pixi)
78
+ return;
79
+ if (type === "start") {
80
+ if (cropper) {
81
+ current_opacity = cropper.stop();
82
+ cropper = null;
83
+ }
84
+ cropper = crop_canvas(
85
+ $pixi?.renderer,
86
+ $pixi.mask_container,
87
+ crop,
88
+ current_opacity
89
+ );
90
+ cropper.start(...$dimensions, current_crop);
91
+ } else if (type === "continue") {
92
+ if (!cropper)
93
+ return;
94
+ cropper.continue([
95
+ x * $dimensions[0],
96
+ y * $dimensions[1],
97
+ width * $dimensions[0],
98
+ height * $dimensions[1]
99
+ ]);
100
+ } else if (type === "stop") {
101
+ if (!cropper)
102
+ return;
103
+ command_manager.execute(cropper);
104
+ }
105
+ manually_cropped = true;
106
+ }
107
+ let measured = false;
108
+ function get_measurements() {
109
+ if (measured)
110
+ return;
111
+ if (!$editor_box.child_height)
112
+ return;
113
+ const _height = $editor_box.child_height;
114
+ const _width = $editor_box.child_width;
115
+ const _top = $editor_box.child_top - $editor_box.parent_top;
116
+ const _left = $editor_box.child_left - $editor_box.parent_left;
117
+ w_p = _width / $editor_box.child_width;
118
+ h_p = _height / $editor_box.child_height;
119
+ l_p = (_left - $editor_box.child_left + $editor_box.parent_left) / $editor_box.child_width;
120
+ t_p = (_top - $editor_box.child_top + $editor_box.parent_top) / $editor_box.child_height;
121
+ measured = true;
122
+ }
123
+ let current_crop;
124
+ $:
125
+ current_crop = [
126
+ l_p * $dimensions[0],
127
+ t_p * $dimensions[1],
128
+ w_p * $dimensions[0],
129
+ h_p * $dimensions[1]
130
+ ];
131
+ $: {
132
+ l_p = $crop[0];
133
+ t_p = $crop[1];
134
+ w_p = $crop[2];
135
+ h_p = $crop[3];
136
+ }
137
+ $:
138
+ $editor_box && get_measurements();
139
+ const unregister = register_tool("crop");
140
+ onDestroy(unregister);
141
+ </script>
142
+
143
+ {#if $active_tool === "crop" && measured}
144
+ <Cropper
145
+ crop_constraint={_crop_constraint}
146
+ {w_p}
147
+ {h_p}
148
+ {l_p}
149
+ {t_p}
150
+ {editor_box}
151
+ on:crop_start={({ detail }) => handle_crop("start", detail)}
152
+ on:crop_continue={({ detail }) => handle_crop("continue", detail)}
153
+ on:crop_end={({ detail }) => handle_crop("stop", detail)}
154
+ />
155
+ {/if}
@@ -0,0 +1,16 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ crop_constraint: [number, number] | `${string}:${string}` | null;
5
+ };
6
+ events: {
7
+ [evt: string]: CustomEvent<any>;
8
+ };
9
+ slots: {};
10
+ };
11
+ export type CropProps = typeof __propDef.props;
12
+ export type CropEvents = typeof __propDef.events;
13
+ export type CropSlots = typeof __propDef.slots;
14
+ export default class Crop extends SvelteComponent<CropProps, CropEvents, CropSlots> {
15
+ }
16
+ export {};
@@ -0,0 +1,271 @@
1
+ <script>import { createEventDispatcher } from "svelte";
2
+ import Handle from "./Handle.svelte";
3
+ import {} from "../ImageEditor.svelte";
4
+ import { clamp } from "../utils/pixi";
5
+ import { resize_and_reposition } from "./crop";
6
+ export let editor_box;
7
+ export let crop_constraint;
8
+ const dispatch = createEventDispatcher();
9
+ let _height = $editor_box.child_height;
10
+ let _width = $editor_box.child_width;
11
+ let _top = $editor_box.child_top - $editor_box.parent_top;
12
+ let _left = $editor_box.child_left - $editor_box.parent_left;
13
+ let _right = $editor_box.child_right - $editor_box.parent_left;
14
+ let _bottom = 0;
15
+ let dragging = false;
16
+ export let w_p;
17
+ export let h_p;
18
+ export let l_p;
19
+ export let t_p;
20
+ const positions = ["tl", "br", "tr", "bl", "t", "b", "l", "r"];
21
+ let finished;
22
+ let timer;
23
+ let triggered = false;
24
+ $: {
25
+ if (dragging || position_drag) {
26
+ clearTimeout(timer);
27
+ finished = false;
28
+ } else {
29
+ set_finished_with_timeout_and_delay();
30
+ }
31
+ }
32
+ function set_finished_with_timeout_and_delay() {
33
+ if (timer) {
34
+ clearTimeout(timer);
35
+ }
36
+ timer = setTimeout(() => {
37
+ if (triggered) {
38
+ dispatch("crop_end", {
39
+ x: l_p,
40
+ y: t_p,
41
+ width: w_p,
42
+ height: h_p
43
+ });
44
+ triggered = false;
45
+ }
46
+ finished = true;
47
+ position_drag = false;
48
+ }, 1e3);
49
+ }
50
+ function handle_change({
51
+ top,
52
+ bottom,
53
+ left,
54
+ right
55
+ }, position) {
56
+ _top = clamp(
57
+ top ? top - $editor_box.parent_top : _top,
58
+ $editor_box.child_top - $editor_box.parent_top,
59
+ $editor_box.child_bottom - $editor_box.parent_top
60
+ );
61
+ _left = clamp(
62
+ left ? left - $editor_box.parent_left : _left,
63
+ $editor_box.child_left - $editor_box.parent_left,
64
+ $editor_box.child_right - $editor_box.parent_left
65
+ );
66
+ _right = clamp(
67
+ right ? right - $editor_box.parent_left : _right,
68
+ $editor_box.child_left - $editor_box.parent_left,
69
+ $editor_box.child_right - $editor_box.parent_left
70
+ );
71
+ _bottom = clamp(
72
+ bottom ? bottom - $editor_box.parent_top : _bottom,
73
+ $editor_box.child_top - $editor_box.parent_top,
74
+ $editor_box.child_bottom - $editor_box.parent_top
75
+ );
76
+ _width = clamp(
77
+ right ? right - _left - $editor_box.parent_left : _width,
78
+ 0,
79
+ _right - _left
80
+ );
81
+ _width = clamp(
82
+ left ? _right - left + $editor_box.parent_left : _width,
83
+ 0,
84
+ _right - _left
85
+ );
86
+ _height = clamp(
87
+ bottom ? bottom - _top - $editor_box.parent_top : _height,
88
+ 0,
89
+ _bottom - _top
90
+ );
91
+ _height = clamp(
92
+ top ? _bottom - top + $editor_box.parent_top : _height,
93
+ 0,
94
+ _bottom - _top
95
+ );
96
+ const anchors_for_position = {
97
+ tl: "br",
98
+ tr: "bl",
99
+ bl: "tr",
100
+ br: "tl",
101
+ t: "b",
102
+ b: "t",
103
+ l: "r",
104
+ r: "l",
105
+ c: "c"
106
+ };
107
+ if (crop_constraint) {
108
+ const max_w = ["t", "b"].includes(position) ? $editor_box.child_width : _right - _left;
109
+ const max_h = ["l", "r"].includes(position) ? $editor_box.child_height : _bottom - _top;
110
+ let result = resize_and_reposition(
111
+ _width,
112
+ _height,
113
+ anchors_for_position[position],
114
+ crop_constraint,
115
+ max_w,
116
+ max_h
117
+ );
118
+ _width = result.new_width;
119
+ _height = result.new_height;
120
+ _left = _left + result.x_offset;
121
+ _top = _top + result.y_offset;
122
+ _right = _left + _width;
123
+ _bottom = _top + _height;
124
+ }
125
+ w_p = _width / $editor_box.child_width;
126
+ h_p = _height / $editor_box.child_height;
127
+ l_p = (_left - $editor_box.child_left + $editor_box.parent_left) / $editor_box.child_width;
128
+ t_p = (_top - $editor_box.child_top + $editor_box.parent_top) / $editor_box.child_height;
129
+ dispatch(triggered ? "crop_continue" : "crop_start", {
130
+ x: l_p,
131
+ y: t_p,
132
+ width: w_p,
133
+ height: h_p
134
+ });
135
+ triggered = true;
136
+ }
137
+ function resize() {
138
+ _width = w_p * $editor_box.child_width;
139
+ _height = h_p * $editor_box.child_height;
140
+ _left = l_p * $editor_box.child_width + ($editor_box.child_left - $editor_box.parent_left);
141
+ _top = t_p * $editor_box.child_height + ($editor_box.child_top - $editor_box.parent_top);
142
+ _right = _left + _width;
143
+ _bottom = _top + _height;
144
+ }
145
+ $:
146
+ $editor_box && resize();
147
+ let start_x = 0;
148
+ let start_y = 0;
149
+ let position_drag = false;
150
+ function handle_drag_start(e) {
151
+ position_drag = true;
152
+ start_x = e.clientX;
153
+ start_y = e.clientY;
154
+ if (!finished)
155
+ return;
156
+ finished = false;
157
+ dispatch("crop_start", {
158
+ x: l_p,
159
+ y: t_p,
160
+ width: w_p,
161
+ height: h_p
162
+ });
163
+ }
164
+ function handle_drag_end(e) {
165
+ if (!position_drag)
166
+ return;
167
+ position_drag = false;
168
+ }
169
+ function handle_dragging(e) {
170
+ if (!position_drag)
171
+ return;
172
+ const x_delta = e.clientX - start_x;
173
+ const y_delta = e.clientY - start_y;
174
+ _left = clamp(
175
+ _left + x_delta,
176
+ $editor_box.child_left - $editor_box.parent_left,
177
+ $editor_box.child_right - $editor_box.parent_left - _width
178
+ );
179
+ _top = clamp(
180
+ _top + y_delta,
181
+ $editor_box.child_top - $editor_box.parent_top,
182
+ $editor_box.child_bottom - $editor_box.parent_top - _height
183
+ );
184
+ _right = _left + _width;
185
+ _bottom = _top + _height;
186
+ l_p = (_left - $editor_box.child_left + $editor_box.parent_left) / $editor_box.child_width;
187
+ t_p = (_top - $editor_box.child_top + $editor_box.parent_top) / $editor_box.child_height;
188
+ start_x = e.clientX;
189
+ start_y = e.clientY;
190
+ dispatch("crop_continue", {
191
+ x: l_p,
192
+ y: t_p,
193
+ width: w_p,
194
+ height: h_p
195
+ });
196
+ triggered = true;
197
+ }
198
+ </script>
199
+
200
+ <svelte:window on:mousemove={handle_dragging} on:mouseup={handle_drag_end} />
201
+
202
+ <div class="wrap">
203
+ <div
204
+ class="box"
205
+ style:width="{_width}px"
206
+ style:height="{_height}px"
207
+ style:top="{_top}px"
208
+ style:left="{_left}px"
209
+ >
210
+ {#each positions as position}
211
+ <Handle
212
+ on:change={({ detail }) => handle_change(detail, position)}
213
+ bind:dragging
214
+ location={position}
215
+ />
216
+ {/each}
217
+
218
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
219
+ <div class="grid" class:finished on:mousedown={handle_drag_start}>
220
+ {#each { length: 25 } as _}
221
+ <div></div>
222
+ {/each}
223
+ </div>
224
+ </div>
225
+ </div>
226
+
227
+ <style>
228
+ .grid {
229
+ height: 100%;
230
+ width: 100%;
231
+ display: grid;
232
+ grid-template-rows: 1fr 1px 1fr 1px 1fr;
233
+ grid-template-columns: 1fr 1px 1fr 1px 1fr;
234
+ overflow: hidden;
235
+ transition: 0.2s;
236
+ opacity: 1;
237
+ /* pointer-events: none; */
238
+ }
239
+
240
+ .grid.finished {
241
+ opacity: 0;
242
+ }
243
+
244
+ .grid > div {
245
+ width: 100%;
246
+ height: 100%;
247
+ }
248
+
249
+ .grid > div:nth-of-type(even) {
250
+ background: black;
251
+ opacity: 0.5;
252
+ }
253
+
254
+ .wrap {
255
+ position: absolute;
256
+ top: 0;
257
+ left: 0;
258
+ width: 100%;
259
+ height: 100%;
260
+
261
+ /* transform: translateY(-20px); */
262
+ }
263
+
264
+ .box {
265
+ position: absolute;
266
+ width: 100%;
267
+ height: 100%;
268
+ border: 1px solid black;
269
+ z-index: var(--layer-top);
270
+ }
271
+ </style>
@@ -0,0 +1,41 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import { type EditorContext } from "../ImageEditor.svelte";
3
+ declare const __propDef: {
4
+ props: {
5
+ editor_box: EditorContext["editor_box"];
6
+ crop_constraint: number | null;
7
+ w_p: number;
8
+ h_p: number;
9
+ l_p: number;
10
+ t_p: number;
11
+ };
12
+ events: {
13
+ crop_start: CustomEvent<{
14
+ x: number;
15
+ y: number;
16
+ width: number;
17
+ height: number;
18
+ }>;
19
+ crop_continue: CustomEvent<{
20
+ x: number;
21
+ y: number;
22
+ width: number;
23
+ height: number;
24
+ }>;
25
+ crop_end: CustomEvent<{
26
+ x: number;
27
+ y: number;
28
+ width: number;
29
+ height: number;
30
+ }>;
31
+ } & {
32
+ [evt: string]: CustomEvent<any>;
33
+ };
34
+ slots: {};
35
+ };
36
+ export type CropperProps = typeof __propDef.props;
37
+ export type CropperEvents = typeof __propDef.events;
38
+ export type CropperSlots = typeof __propDef.slots;
39
+ export default class Cropper extends SvelteComponent<CropperProps, CropperEvents, CropperSlots> {
40
+ }
41
+ export {};