@gradio/imageeditor 0.12.14 → 0.13.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 (130) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/Example.svelte +1 -1
  3. package/IMAGE_EDITOR_OVERVIEW.md +224 -0
  4. package/ImageEditor.stories.svelte +4 -4
  5. package/Index.svelte +35 -46
  6. package/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +56 -103
  7. package/dist/Example.svelte.d.ts +1 -1
  8. package/dist/Index.svelte +29 -33
  9. package/dist/Index.svelte.d.ts +17 -16
  10. package/dist/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +47 -88
  11. package/dist/{shared/InteractiveImageEditor.svelte.d.ts → InteractiveImageEditor.svelte.d.ts} +13 -15
  12. package/dist/shared/Anchor.svelte +311 -0
  13. package/dist/shared/Anchor.svelte.d.ts +18 -0
  14. package/dist/shared/Controls.svelte +162 -23
  15. package/dist/shared/Controls.svelte.d.ts +7 -2
  16. package/dist/shared/{tools/IconButton.svelte → IconButton.svelte} +19 -3
  17. package/dist/shared/{tools/IconButton.svelte.d.ts → IconButton.svelte.d.ts} +4 -1
  18. package/dist/shared/ImageEditor.svelte +546 -289
  19. package/dist/shared/ImageEditor.svelte.d.ts +51 -56
  20. package/dist/shared/Layers.svelte +233 -0
  21. package/dist/shared/Layers.svelte.d.ts +35 -0
  22. package/dist/shared/Resize.svelte +218 -0
  23. package/dist/shared/Resize.svelte.d.ts +29 -0
  24. package/dist/shared/SecondaryToolbar.svelte +54 -0
  25. package/dist/shared/SecondaryToolbar.svelte.d.ts +35 -0
  26. package/dist/shared/Toolbar.svelte +337 -0
  27. package/dist/shared/Toolbar.svelte.d.ts +42 -0
  28. package/dist/shared/{tools → brush}/BrushOptions.svelte +68 -64
  29. package/dist/shared/{tools → brush}/BrushOptions.svelte.d.ts +9 -9
  30. package/dist/shared/{tools → brush}/BrushSize.svelte +2 -27
  31. package/dist/shared/{tools → brush}/ColorField.svelte +2 -1
  32. package/dist/shared/{tools → brush}/ColorField.svelte.d.ts +1 -0
  33. package/dist/shared/{tools → brush}/ColorPicker.svelte +81 -9
  34. package/dist/shared/{tools → brush}/ColorPicker.svelte.d.ts +1 -0
  35. package/dist/shared/{tools → brush}/ColorSwatch.svelte +78 -38
  36. package/dist/shared/{tools → brush}/ColorSwatch.svelte.d.ts +6 -2
  37. package/dist/shared/brush/brush-cursor.d.ts +101 -0
  38. package/dist/shared/brush/brush-cursor.js +327 -0
  39. package/dist/shared/brush/brush-textures.d.ts +71 -0
  40. package/dist/shared/brush/brush-textures.js +404 -0
  41. package/dist/shared/brush/brush-utils.d.ts +32 -0
  42. package/dist/shared/brush/brush-utils.js +59 -0
  43. package/dist/shared/brush/brush.d.ts +152 -0
  44. package/dist/shared/brush/brush.js +396 -0
  45. package/dist/shared/brush/types.d.ts +37 -0
  46. package/dist/shared/brush/types.js +1 -0
  47. package/dist/shared/core/editor.d.ts +252 -0
  48. package/dist/shared/core/editor.js +1221 -0
  49. package/dist/shared/crop/crop.d.ts +201 -0
  50. package/dist/shared/crop/crop.js +727 -0
  51. package/dist/shared/image/image.d.ts +89 -0
  52. package/dist/shared/image/image.js +185 -0
  53. package/dist/shared/resize/resize.d.ts +270 -0
  54. package/dist/shared/resize/resize.js +1413 -0
  55. package/dist/shared/types.d.ts +12 -0
  56. package/dist/shared/utils/pixi.d.ts +16 -57
  57. package/dist/shared/utils/pixi.js +15 -113
  58. package/dist/shared/zoom/zoom.d.ts +136 -0
  59. package/dist/shared/zoom/zoom.js +548 -0
  60. package/package.json +10 -9
  61. package/shared/Anchor.svelte +384 -0
  62. package/shared/Controls.svelte +194 -27
  63. package/shared/{tools/IconButton.svelte → IconButton.svelte} +21 -4
  64. package/shared/ImageEditor.svelte +682 -349
  65. package/shared/Layers.svelte +249 -0
  66. package/shared/Resize.svelte +239 -0
  67. package/shared/SecondaryToolbar.svelte +61 -0
  68. package/shared/Toolbar.svelte +386 -0
  69. package/shared/brush/BRUSH_TOOL.md +134 -0
  70. package/shared/brush/BrushOptions.svelte +200 -0
  71. package/shared/{tools → brush}/BrushSize.svelte +2 -30
  72. package/shared/{tools → brush}/ColorField.svelte +3 -1
  73. package/shared/{tools → brush}/ColorPicker.svelte +86 -9
  74. package/shared/{tools → brush}/ColorSwatch.svelte +95 -42
  75. package/shared/brush/brush-cursor.ts +408 -0
  76. package/shared/brush/brush-textures.ts +508 -0
  77. package/shared/brush/brush-utils.ts +76 -0
  78. package/shared/brush/brush.ts +506 -0
  79. package/shared/brush/types.ts +41 -0
  80. package/shared/core/EDITOR.md +182 -0
  81. package/shared/core/editor.ts +1730 -0
  82. package/shared/crop/CROP.md +139 -0
  83. package/shared/crop/crop.ts +1027 -0
  84. package/shared/image/IMAGE.md +135 -0
  85. package/shared/image/image.ts +300 -0
  86. package/shared/resize/resize.ts +1894 -0
  87. package/shared/types.ts +14 -0
  88. package/shared/utils/pixi.ts +19 -246
  89. package/shared/zoom/zoom.ts +729 -0
  90. package/dist/shared/layers/Layers.svelte +0 -231
  91. package/dist/shared/layers/Layers.svelte.d.ts +0 -18
  92. package/dist/shared/layers/utils.d.ts +0 -73
  93. package/dist/shared/layers/utils.js +0 -156
  94. package/dist/shared/tools/Brush.svelte +0 -215
  95. package/dist/shared/tools/Brush.svelte.d.ts +0 -29
  96. package/dist/shared/tools/Crop.svelte +0 -155
  97. package/dist/shared/tools/Crop.svelte.d.ts +0 -16
  98. package/dist/shared/tools/Cropper.svelte +0 -271
  99. package/dist/shared/tools/Cropper.svelte.d.ts +0 -41
  100. package/dist/shared/tools/Handle.svelte +0 -260
  101. package/dist/shared/tools/Handle.svelte.d.ts +0 -29
  102. package/dist/shared/tools/Sources.svelte +0 -257
  103. package/dist/shared/tools/Sources.svelte.d.ts +0 -34
  104. package/dist/shared/tools/Tools.svelte +0 -102
  105. package/dist/shared/tools/Tools.svelte.d.ts +0 -48
  106. package/dist/shared/tools/brush.d.ts +0 -62
  107. package/dist/shared/tools/brush.js +0 -133
  108. package/dist/shared/tools/crop.d.ts +0 -15
  109. package/dist/shared/tools/crop.js +0 -154
  110. package/dist/shared/tools/index.d.ts +0 -5
  111. package/dist/shared/tools/index.js +0 -5
  112. package/dist/shared/tools/sources.d.ts +0 -46
  113. package/dist/shared/tools/sources.js +0 -121
  114. package/dist/shared/tools/types.d.ts +0 -1
  115. package/shared/layers/Layers.svelte +0 -250
  116. package/shared/layers/utils.ts +0 -294
  117. package/shared/tools/Brush.svelte +0 -280
  118. package/shared/tools/BrushOptions.svelte +0 -180
  119. package/shared/tools/Crop.svelte +0 -189
  120. package/shared/tools/Cropper.svelte +0 -346
  121. package/shared/tools/Handle.svelte +0 -289
  122. package/shared/tools/Sources.svelte +0 -283
  123. package/shared/tools/Tools.svelte +0 -162
  124. package/shared/tools/brush.ts +0 -247
  125. package/shared/tools/crop.ts +0 -213
  126. package/shared/tools/index.ts +0 -5
  127. package/shared/tools/sources.ts +0 -195
  128. package/shared/tools/types.ts +0 -1
  129. /package/dist/shared/{tools → brush}/BrushSize.svelte.d.ts +0 -0
  130. /package/dist/shared/{tools/types.js → types.js} +0 -0
@@ -1,69 +1,56 @@
1
1
  import { SvelteComponent } from "svelte";
2
- import type { Writable } from "svelte/store";
3
- import type { Spring } from "svelte/motion";
4
- import { type PixiApp } from "./utils/pixi";
5
- import { type CommandManager, type CommandNode } from "./utils/commands";
6
2
  export declare const EDITOR_KEY: unique symbol;
7
3
  export type context_type = "bg" | "layers" | "crop" | "draw" | "erase";
8
- import { type tool } from "./tools";
9
- export interface EditorContext {
10
- pixi: Writable<PixiApp | null>;
11
- current_layer: Writable<LayerScene | null>;
12
- dimensions: Writable<[number, number]>;
13
- editor_box: Writable<{
14
- parent_width: number;
15
- parent_height: number;
16
- parent_left: number;
17
- parent_top: number;
18
- parent_right: number;
19
- parent_bottom: number;
20
- child_width: number;
21
- child_height: number;
22
- child_left: number;
23
- child_top: number;
24
- child_right: number;
25
- child_bottom: number;
26
- }>;
27
- active_tool: Writable<tool>;
28
- toolbar_box: Writable<DOMRect | Record<string, never>>;
29
- crop: Writable<[number, number, number, number]>;
30
- position_spring: Spring<{
31
- x: number;
32
- y: number;
33
- }>;
34
- command_manager: CommandManager;
35
- current_history: CommandManager["current_history"];
36
- register_context: (type: context_type, { reset_fn, init_fn }: {
37
- reset_fn?: () => void;
38
- init_fn?: (dimensions?: [number, number]) => void;
39
- }) => void;
40
- reset: (clear_image: boolean, dimensions: [number, number]) => void;
41
- }
42
- import { type LayerScene } from "./layers/utils";
43
- import { type ImageBlobs } from "./utils/pixi";
4
+ import { type Tool as ToolbarTool } from "./Toolbar.svelte";
5
+ import type { I18nFormatter } from "@gradio/utils";
6
+ import type { Client, FileData } from "@gradio/client";
7
+ import { type CommandNode } from "./utils/commands";
8
+ import { type Brush, type Eraser } from "./brush/types";
9
+ import type { LayerOptions, Source, Transform } from "./types";
10
+ import { type ImageBlobs } from "./types";
44
11
  declare const __propDef: {
45
12
  props: {
46
- antialias?: boolean | undefined;
47
- crop_size: [number, number] | undefined;
48
- changeable?: boolean | undefined;
49
- history: boolean;
50
- bg?: boolean | undefined;
51
- sources: ("clipboard" | "webcam" | "upload")[];
52
- crop_constraint?: boolean | undefined;
53
- canvas_size: [number, number] | undefined;
54
- parent_height: number;
13
+ antialias?: true | undefined;
55
14
  full_history?: (CommandNode | null) | undefined;
56
- height?: number | undefined;
57
- canvas_height?: number | undefined;
15
+ changeable?: boolean | undefined;
16
+ sources?: Source[] | undefined;
17
+ transforms?: Transform[] | undefined;
18
+ canvas_size: [number, number];
19
+ is_dragging?: boolean | undefined;
20
+ background_image?: boolean | undefined;
21
+ brush_options: Brush;
22
+ eraser_options: Eraser;
23
+ fixed_canvas?: boolean | undefined;
24
+ root: string;
25
+ mirror_webcam?: boolean | undefined;
26
+ i18n: I18nFormatter;
27
+ upload: Client["upload"];
28
+ composite: FileData | null;
29
+ layers: FileData[];
30
+ background: FileData | null;
31
+ border_region?: number | undefined;
32
+ layer_options: LayerOptions;
33
+ current_tool: ToolbarTool;
34
+ has_drawn?: boolean | undefined;
58
35
  get_blobs?: (() => Promise<ImageBlobs>) | undefined;
59
- handle_remove?: (() => void) | undefined;
60
- set_tool?: ((tool: tool) => void) | undefined;
36
+ add_image?: ((image: Blob | File) => void) | undefined;
37
+ add_image_from_url?: ((source: string | {
38
+ url: string;
39
+ meta: {
40
+ _type: string;
41
+ };
42
+ } | any) => Promise<void>) | undefined;
43
+ add_layers_from_url?: ((source: FileData[] | any) => Promise<void>) | undefined;
61
44
  };
62
45
  events: {
46
+ error: CustomEvent<string>;
47
+ drag: CustomEvent<any>;
63
48
  clear?: CustomEvent<undefined> | undefined;
64
49
  save: CustomEvent<void>;
65
50
  change: CustomEvent<void>;
66
- history: CustomEvent<Writable<CommandNode>>;
51
+ history: CustomEvent<import("svelte/store").Writable<CommandNode>>;
52
+ upload: CustomEvent<void>;
53
+ input: CustomEvent<void>;
67
54
  } & {
68
55
  [evt: string]: CustomEvent<any>;
69
56
  };
@@ -75,8 +62,16 @@ export type ImageEditorProps = typeof __propDef.props;
75
62
  export type ImageEditorEvents = typeof __propDef.events;
76
63
  export type ImageEditorSlots = typeof __propDef.slots;
77
64
  export default class ImageEditor extends SvelteComponent<ImageEditorProps, ImageEditorEvents, ImageEditorSlots> {
65
+ get antialias(): true;
66
+ get full_history(): CommandNode;
78
67
  get get_blobs(): () => Promise<ImageBlobs>;
79
- get handle_remove(): () => void;
80
- get set_tool(): (tool: tool) => void;
68
+ get add_image(): (image: Blob | File) => void;
69
+ get add_image_from_url(): (source: string | {
70
+ url: string;
71
+ meta: {
72
+ _type: string;
73
+ };
74
+ } | any) => Promise<void>;
75
+ get add_layers_from_url(): (source: FileData[] | any) => Promise<void>;
81
76
  }
82
77
  export {};
@@ -0,0 +1,233 @@
1
+ <script>import { click_outside } from "./utils/events";
2
+ import { Layers, Clear, ArrowUp, ArrowDown, Plus } from "@gradio/icons";
3
+ import { IconButton } from "@gradio/atoms";
4
+ import { createEventDispatcher } from "svelte";
5
+ const dispatch = createEventDispatcher();
6
+ export let layers;
7
+ export let enable_additional_layers = true;
8
+ export let enable_layers = true;
9
+ export let show_layers = false;
10
+ function new_layer() {
11
+ dispatch("new_layer");
12
+ }
13
+ function change_layer(id) {
14
+ dispatch("change_layer", id);
15
+ show_layers = false;
16
+ }
17
+ function move_layer(id, direction) {
18
+ dispatch("move_layer", { id, direction });
19
+ }
20
+ function delete_layer(id) {
21
+ dispatch("delete_layer", id);
22
+ }
23
+ </script>
24
+
25
+ {#if enable_layers}
26
+ <div
27
+ class="layer-wrap"
28
+ class:closed={!show_layers}
29
+ use:click_outside={() => (show_layers = false)}
30
+ >
31
+ <button
32
+ class="layer-title-button"
33
+ aria-label="Show Layers"
34
+ on:click|stopPropagation={() => (show_layers = !show_layers)}
35
+ >
36
+ {show_layers
37
+ ? "Layers"
38
+ : $layers.layers.find((l) => l.id === $layers.active_layer)?.name}
39
+ <span class="icon"><Layers /></span>
40
+ </button>
41
+ {#if show_layers}
42
+ <ul>
43
+ {#each $layers.layers as { id, name, user_created }, i (i)}
44
+ <li>
45
+ <button
46
+ class:selected_layer={$layers.active_layer === id}
47
+ aria-label={`layer-${i + 1}`}
48
+ on:click|stopPropagation={() => change_layer(id)}>{name}</button
49
+ >
50
+ {#if $layers.layers.length > 1}
51
+ <div>
52
+ {#if i > 0}
53
+ <IconButton
54
+ on:click={(e) => {
55
+ e.stopPropagation();
56
+ move_layer(id, "up");
57
+ }}
58
+ Icon={ArrowUp}
59
+ size="x-small"
60
+ />
61
+ {/if}
62
+ {#if i < $layers.layers.length - 1}
63
+ <IconButton
64
+ on:click={(e) => {
65
+ e.stopPropagation();
66
+ move_layer(id, "down");
67
+ }}
68
+ Icon={ArrowDown}
69
+ size="x-small"
70
+ />
71
+ {/if}
72
+ {#if $layers.layers.length > 1 && user_created}
73
+ <IconButton
74
+ on:click={(e) => {
75
+ e.stopPropagation();
76
+ delete_layer(id);
77
+ }}
78
+ Icon={Clear}
79
+ size="x-small"
80
+ />
81
+ {/if}
82
+ </div>
83
+ {/if}
84
+ </li>
85
+ {/each}
86
+ {#if enable_additional_layers}
87
+ <li class="add-layer">
88
+ <IconButton
89
+ Icon={Plus}
90
+ label="Add Layer"
91
+ on:click={(e) => {
92
+ e.stopPropagation();
93
+ new_layer();
94
+ }}
95
+ size="x-small"
96
+ />
97
+ </li>
98
+ {/if}
99
+ </ul>
100
+ {/if}
101
+ </div>
102
+ {/if}
103
+
104
+ <style>
105
+ .add-layer {
106
+ display: flex;
107
+ justify-content: center;
108
+ align-items: center;
109
+ margin: var(--spacing-sm) 0 0 0;
110
+ }
111
+
112
+ .add-layer :global(button) {
113
+ width: 100%;
114
+ }
115
+ .icon {
116
+ width: 14px;
117
+ color: var(--body-text-color);
118
+ transition: color 0.15s ease;
119
+ }
120
+
121
+ .layer-wrap {
122
+ /* position: absolute; */
123
+ display: flex;
124
+ justify-content: center;
125
+ align-items: center;
126
+ /* border: 1px solid var(--border-color-primary); */
127
+ /* z-index: var(--layer-1); */
128
+ /* border-radius: var(--radius-sm); */
129
+ /* background-color: var(--block-background-fill); */
130
+ width: 100%;
131
+ flex-direction: column;
132
+ /* bottom: 5px; */
133
+ /* right: 5px; */
134
+ /* border-bottom: 0;
135
+ border-right: 0; */
136
+ /* box-shadow: var(--shadow-drop); */
137
+ }
138
+
139
+ .layer-wrap button {
140
+ justify-content: space-between;
141
+ align-items: center;
142
+ width: 100%;
143
+ display: flex;
144
+ font-size: var(--text-sm);
145
+ line-height: var(--line-sm);
146
+ transition: all 0.15s ease;
147
+ padding: var(--spacing-md) var(--spacing-lg);
148
+ /* padding-right: var(--spacing-lg); */
149
+ border-radius: var(--radius-sm);
150
+ /* padding-left: 30px; */
151
+ }
152
+
153
+ button.layer-title-button {
154
+ width: 100%;
155
+ /* padding-left: 30px; */
156
+ }
157
+
158
+ .layer-wrap button:hover .icon {
159
+ color: var(--color-accent);
160
+ }
161
+
162
+ .selected_layer {
163
+ color: var(--color-accent);
164
+ font-weight: var(--weight-semibold);
165
+ }
166
+
167
+ ul {
168
+ /* position: absolute; */
169
+ bottom: 0;
170
+ right: 0;
171
+ /* background: var(--block-background-fill); */
172
+ width: 100%;
173
+ /* min-width: 100%; */
174
+ list-style: none;
175
+ z-index: var(--layer-top);
176
+ /* border: 1px solid var(--border-color-primary); */
177
+ /* border-radius: var(--radius-sm); */
178
+ /* box-shadow: var(--shadow-drop-lg); */
179
+ padding: var(--spacing-sm);
180
+ /* transform: translate(-1px, 1px); */
181
+ border-top: 1px solid var(--border-color-primary);
182
+ }
183
+
184
+ /* .sep {
185
+ height: 12px;
186
+ background-color: var(--block-border-color);
187
+ width: 1px;
188
+ display: block;
189
+ margin-left: var(--spacing-xl);
190
+ } */
191
+
192
+ li {
193
+ display: flex;
194
+ justify-content: space-between;
195
+ align-items: center;
196
+ /* border-radius: var(--radius-sm); */
197
+ transition: background-color 0.15s ease;
198
+ border-bottom: 1px solid var(--border-color-primary);
199
+ }
200
+
201
+ .layer-wrap ul > li > button {
202
+ padding-left: calc(var(--spacing-md));
203
+ }
204
+
205
+ li:hover {
206
+ background-color: var(--background-fill-secondary);
207
+ }
208
+
209
+ li:last-child {
210
+ border-bottom: none;
211
+ }
212
+ li:last-child:hover {
213
+ background-color: unset;
214
+ }
215
+
216
+ li div {
217
+ display: flex;
218
+ gap: var(--spacing-sm);
219
+ padding: var(--spacing-sm);
220
+ }
221
+ li > button {
222
+ padding: var(--spacing-sm) var(--spacing-md);
223
+ }
224
+
225
+ /* li > div > button {
226
+ opacity: 0.7;
227
+ transition: opacity 0.15s ease;
228
+ }
229
+
230
+ li > div > button:hover {
231
+ opacity: 1;
232
+ } */
233
+ </style>
@@ -0,0 +1,35 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { Writable } from "svelte/store";
3
+ declare const __propDef: {
4
+ props: {
5
+ layers: Writable<{
6
+ active_layer: string;
7
+ layers: {
8
+ name: string;
9
+ id: string;
10
+ user_created: boolean;
11
+ }[];
12
+ }>;
13
+ enable_additional_layers?: boolean | undefined;
14
+ enable_layers?: boolean | undefined;
15
+ show_layers?: boolean | undefined;
16
+ };
17
+ events: {
18
+ new_layer: CustomEvent<void>;
19
+ change_layer: CustomEvent<string>;
20
+ move_layer: CustomEvent<{
21
+ id: string;
22
+ direction: "up" | "down";
23
+ }>;
24
+ delete_layer: CustomEvent<string>;
25
+ } & {
26
+ [evt: string]: CustomEvent<any>;
27
+ };
28
+ slots: {};
29
+ };
30
+ export type LayersProps = typeof __propDef.props;
31
+ export type LayersEvents = typeof __propDef.events;
32
+ export type LayersSlots = typeof __propDef.slots;
33
+ export default class Layers extends SvelteComponent<LayersProps, LayersEvents, LayersSlots> {
34
+ }
35
+ export {};
@@ -0,0 +1,218 @@
1
+ <script context="module"></script>
2
+
3
+ <script>import { createEventDispatcher } from "svelte";
4
+ import Anchor from "./Anchor.svelte";
5
+ export let dimensions;
6
+ const dispatch = createEventDispatcher();
7
+ let selected_anchor = "center";
8
+ let scale = false;
9
+ let new_width = $dimensions?.width;
10
+ let new_height = $dimensions?.height;
11
+ function handle_click() {
12
+ dispatch("change", {
13
+ anchor: selected_anchor,
14
+ scale,
15
+ width: new_width,
16
+ height: new_height
17
+ });
18
+ }
19
+ function set_anchor(position) {
20
+ selected_anchor = position;
21
+ }
22
+ </script>
23
+
24
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
25
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
26
+ <div class="wrap" on:click|stopPropagation>
27
+ <div class="size-wrap">
28
+ <div class="size-input">
29
+ <label for="width">Width</label><input
30
+ type="number"
31
+ id="width"
32
+ bind:value={new_width}
33
+ />
34
+ </div>
35
+ <div class="size-input">
36
+ <label for="height">Height </label><input
37
+ type="number"
38
+ id="height"
39
+ bind:value={new_height}
40
+ />
41
+ </div>
42
+ </div>
43
+
44
+ <div class="scale-wrap">
45
+ <h2 class="image-will-label">Image will:</h2>
46
+ <div class="toggle-container">
47
+ <label class="radio-label">
48
+ <input
49
+ type="radio"
50
+ name="resize_mode"
51
+ value={true}
52
+ bind:group={scale}
53
+ />
54
+ <span class="radio-button">rescale</span>
55
+ </label>
56
+ <label class="radio-label">
57
+ <input
58
+ type="radio"
59
+ name="resize_mode"
60
+ value={false}
61
+ bind:group={scale}
62
+ />
63
+ <span class="radio-button">anchor</span>
64
+ </label>
65
+ </div>
66
+ </div>
67
+ <div class="anchor-wrap">
68
+ <Anchor on:position={(e) => set_anchor(e.detail)} />
69
+ </div>
70
+ <button class="apply-button" on:click={() => handle_click()}
71
+ >Resize Canvas</button
72
+ >
73
+ </div>
74
+
75
+ <!-- </div> -->
76
+
77
+ <style>
78
+ .wrap {
79
+ padding: var(--spacing-xl) var(--spacing-lg);
80
+ color: var(--block-label-text-color);
81
+ }
82
+
83
+ .size-wrap {
84
+ display: flex;
85
+ flex-direction: row;
86
+ gap: 10px;
87
+ }
88
+
89
+ .size-input {
90
+ display: flex;
91
+ flex-direction: column;
92
+ gap: var(--spacing-xxs);
93
+ }
94
+
95
+ label,
96
+ h2 {
97
+ display: flex;
98
+ align-items: center;
99
+ gap: 15px;
100
+
101
+ cursor: pointer;
102
+ color: var(--checkbox-label-text-color);
103
+ font-weight: var(--checkbox-label-text-weight);
104
+ font-size: var(--text-sm);
105
+ line-height: var(--line-md);
106
+ }
107
+
108
+ .scale-wrap {
109
+ display: flex;
110
+ flex-direction: column;
111
+ gap: var(--spacing-sm);
112
+ margin-top: var(--spacing-md);
113
+ }
114
+
115
+ input[type="number"] {
116
+ border: 1px solid var(--border-color-primary);
117
+ width: 60px;
118
+ border-radius: var(--radius-sm);
119
+ background-color: var(--checkbox-background-color-focus);
120
+ color: var(--body-text-color);
121
+ font-size: var(--text-sm);
122
+ transition: border-color 0.15s ease;
123
+ padding: var(--spacing-xs);
124
+ line-height: 1rem;
125
+ }
126
+
127
+ input[type="number"]:hover {
128
+ border-color: var(--color-accent-soft);
129
+ }
130
+
131
+ input[type="number"]:focus {
132
+ border-color: var(--color-accent);
133
+ outline: none;
134
+ box-shadow: 0 0 0 1px var(--color-accent-soft);
135
+ }
136
+
137
+ .image-will-label {
138
+ grid-column: 1;
139
+ }
140
+
141
+ .toggle-container {
142
+ display: flex;
143
+ grid-column: 2;
144
+ border-radius: var(--radius-sm);
145
+ border: 1px solid var(--border-color-primary);
146
+ overflow: hidden;
147
+ }
148
+
149
+ .toggle-container {
150
+ display: flex;
151
+ grid-column: 2;
152
+ border-radius: var(--radius-sm);
153
+ border: 1px solid var(--border-color-primary);
154
+ overflow: hidden;
155
+ }
156
+
157
+ .radio-label {
158
+ flex: 1;
159
+ margin: 0;
160
+ padding: 0;
161
+ position: relative;
162
+ cursor: pointer;
163
+ }
164
+
165
+ .radio-button {
166
+ display: flex;
167
+ justify-content: center;
168
+ align-items: center;
169
+ padding: var(--spacing-sm);
170
+ background: var(--checkbox-background-color);
171
+ color: var(--body-text-color);
172
+ font-size: var(--text-sm);
173
+ transition: background-color 0.15s ease;
174
+ width: 100%;
175
+ height: 100%;
176
+ }
177
+
178
+ input[type="radio"] {
179
+ position: absolute;
180
+ opacity: 0;
181
+ width: 0;
182
+ height: 0;
183
+ }
184
+
185
+ input[type="radio"]:not(:checked) + .radio-button:hover {
186
+ background: var(--checkbox-background-color-hover);
187
+ }
188
+
189
+ input[type="radio"]:checked + .radio-button {
190
+ background: var(--color-accent);
191
+ color: white;
192
+ }
193
+
194
+ .apply-button {
195
+ width: 100%;
196
+ margin-top: var(--spacing-md);
197
+ padding: var(--spacing-sm) var(--spacing-md);
198
+ background: var(--color-accent);
199
+ color: white;
200
+ border: none;
201
+ border-radius: var(--radius-sm);
202
+ font-size: var(--text-sm);
203
+ font-weight: var(--weight-semibold);
204
+ transition: all 0.15s ease;
205
+ }
206
+
207
+ .apply-button:hover {
208
+ background: var(--button-primary-background-fill-hover);
209
+ }
210
+
211
+ .anchor-wrap {
212
+ display: flex;
213
+ justify-content: center;
214
+ align-items: center;
215
+ flex-direction: column;
216
+ gap: 10px;
217
+ }
218
+ </style>
@@ -0,0 +1,29 @@
1
+ import { SvelteComponent } from "svelte";
2
+ export type Position = "top-left" | "top" | "top-right" | "left" | "center" | "right" | "bottom-left" | "bottom" | "bottom-right";
3
+ import type { Spring } from "svelte/motion";
4
+ declare const __propDef: {
5
+ props: {
6
+ dimensions: Spring<{
7
+ width: number;
8
+ height: number;
9
+ }>;
10
+ };
11
+ events: {
12
+ click: MouseEvent;
13
+ change: CustomEvent<{
14
+ anchor: Position;
15
+ scale: boolean;
16
+ width: number;
17
+ height: number;
18
+ }>;
19
+ } & {
20
+ [evt: string]: CustomEvent<any>;
21
+ };
22
+ slots: {};
23
+ };
24
+ export type ResizeProps = typeof __propDef.props;
25
+ export type ResizeEvents = typeof __propDef.events;
26
+ export type ResizeSlots = typeof __propDef.slots;
27
+ export default class Resize extends SvelteComponent<ResizeProps, ResizeEvents, ResizeSlots> {
28
+ }
29
+ export {};
@@ -0,0 +1,54 @@
1
+ <script>import Layers from "./Layers.svelte";
2
+ export let layers;
3
+ export let enable_additional_layers = true;
4
+ export let enable_layers = true;
5
+ export let show_layers = false;
6
+ </script>
7
+
8
+ <div class="toolbar-wrap-wrap">
9
+ <div class="toolbar-wrap">
10
+ {#if enable_layers}
11
+ <Layers
12
+ {layers}
13
+ {enable_additional_layers}
14
+ {enable_layers}
15
+ {show_layers}
16
+ on:new_layer
17
+ on:change_layer
18
+ on:move_layer
19
+ on:delete_layer
20
+ />
21
+ {/if}
22
+ </div>
23
+ </div>
24
+
25
+ <style>
26
+ .toolbar-wrap-wrap {
27
+ position: absolute;
28
+ right: 0;
29
+ bottom: 0;
30
+ width: fit-content;
31
+ max-height: 100%;
32
+ overflow-y: auto;
33
+ display: flex;
34
+ flex-direction: column-reverse;
35
+ }
36
+
37
+ .toolbar-wrap {
38
+ min-width: 110px;
39
+ display: flex;
40
+ flex-direction: column;
41
+ justify-content: center;
42
+ align-items: center;
43
+ position: relative;
44
+ right: 0;
45
+ bottom: 0;
46
+ border: 1px solid var(--block-border-color);
47
+ border-radius: 0;
48
+ border-top-left-radius: var(--radius-md);
49
+ border-right: none;
50
+ border-bottom: none;
51
+ z-index: 1000;
52
+ background-color: var(--block-background-fill);
53
+ }
54
+ </style>