@gradio/imageeditor 0.12.13 → 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.
- package/CHANGELOG.md +23 -0
- package/Example.svelte +1 -1
- package/IMAGE_EDITOR_OVERVIEW.md +224 -0
- package/ImageEditor.stories.svelte +4 -4
- package/Index.svelte +35 -46
- package/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +56 -103
- package/dist/Example.svelte.d.ts +1 -1
- package/dist/Index.svelte +29 -33
- package/dist/Index.svelte.d.ts +17 -16
- package/dist/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +47 -88
- package/dist/{shared/InteractiveImageEditor.svelte.d.ts → InteractiveImageEditor.svelte.d.ts} +13 -15
- package/dist/shared/Anchor.svelte +311 -0
- package/dist/shared/Anchor.svelte.d.ts +18 -0
- package/dist/shared/Controls.svelte +162 -23
- package/dist/shared/Controls.svelte.d.ts +7 -2
- package/dist/shared/{tools/IconButton.svelte → IconButton.svelte} +19 -3
- package/dist/shared/{tools/IconButton.svelte.d.ts → IconButton.svelte.d.ts} +4 -1
- package/dist/shared/ImageEditor.svelte +546 -289
- package/dist/shared/ImageEditor.svelte.d.ts +51 -56
- package/dist/shared/Layers.svelte +233 -0
- package/dist/shared/Layers.svelte.d.ts +35 -0
- package/dist/shared/Resize.svelte +218 -0
- package/dist/shared/Resize.svelte.d.ts +29 -0
- package/dist/shared/SecondaryToolbar.svelte +54 -0
- package/dist/shared/SecondaryToolbar.svelte.d.ts +35 -0
- package/dist/shared/Toolbar.svelte +337 -0
- package/dist/shared/Toolbar.svelte.d.ts +42 -0
- package/dist/shared/{tools → brush}/BrushOptions.svelte +68 -64
- package/dist/shared/{tools → brush}/BrushOptions.svelte.d.ts +9 -9
- package/dist/shared/{tools → brush}/BrushSize.svelte +2 -27
- package/dist/shared/{tools → brush}/ColorField.svelte +2 -1
- package/dist/shared/{tools → brush}/ColorField.svelte.d.ts +1 -0
- package/dist/shared/{tools → brush}/ColorPicker.svelte +81 -9
- package/dist/shared/{tools → brush}/ColorPicker.svelte.d.ts +1 -0
- package/dist/shared/{tools → brush}/ColorSwatch.svelte +78 -38
- package/dist/shared/{tools → brush}/ColorSwatch.svelte.d.ts +6 -2
- package/dist/shared/brush/brush-cursor.d.ts +101 -0
- package/dist/shared/brush/brush-cursor.js +327 -0
- package/dist/shared/brush/brush-textures.d.ts +71 -0
- package/dist/shared/brush/brush-textures.js +404 -0
- package/dist/shared/brush/brush-utils.d.ts +32 -0
- package/dist/shared/brush/brush-utils.js +59 -0
- package/dist/shared/brush/brush.d.ts +152 -0
- package/dist/shared/brush/brush.js +396 -0
- package/dist/shared/brush/types.d.ts +37 -0
- package/dist/shared/brush/types.js +1 -0
- package/dist/shared/core/editor.d.ts +252 -0
- package/dist/shared/core/editor.js +1221 -0
- package/dist/shared/crop/crop.d.ts +201 -0
- package/dist/shared/crop/crop.js +727 -0
- package/dist/shared/image/image.d.ts +89 -0
- package/dist/shared/image/image.js +185 -0
- package/dist/shared/resize/resize.d.ts +270 -0
- package/dist/shared/resize/resize.js +1413 -0
- package/dist/shared/types.d.ts +12 -0
- package/dist/shared/utils/pixi.d.ts +16 -57
- package/dist/shared/utils/pixi.js +15 -113
- package/dist/shared/zoom/zoom.d.ts +136 -0
- package/dist/shared/zoom/zoom.js +548 -0
- package/package.json +11 -10
- package/shared/Anchor.svelte +384 -0
- package/shared/Controls.svelte +194 -27
- package/shared/{tools/IconButton.svelte → IconButton.svelte} +21 -4
- package/shared/ImageEditor.svelte +682 -349
- package/shared/Layers.svelte +249 -0
- package/shared/Resize.svelte +239 -0
- package/shared/SecondaryToolbar.svelte +61 -0
- package/shared/Toolbar.svelte +386 -0
- package/shared/brush/BRUSH_TOOL.md +134 -0
- package/shared/brush/BrushOptions.svelte +200 -0
- package/shared/{tools → brush}/BrushSize.svelte +2 -30
- package/shared/{tools → brush}/ColorField.svelte +3 -1
- package/shared/{tools → brush}/ColorPicker.svelte +86 -9
- package/shared/{tools → brush}/ColorSwatch.svelte +95 -42
- package/shared/brush/brush-cursor.ts +408 -0
- package/shared/brush/brush-textures.ts +508 -0
- package/shared/brush/brush-utils.ts +76 -0
- package/shared/brush/brush.ts +506 -0
- package/shared/brush/types.ts +41 -0
- package/shared/core/EDITOR.md +182 -0
- package/shared/core/editor.ts +1730 -0
- package/shared/crop/CROP.md +139 -0
- package/shared/crop/crop.ts +1027 -0
- package/shared/image/IMAGE.md +135 -0
- package/shared/image/image.ts +300 -0
- package/shared/resize/resize.ts +1894 -0
- package/shared/types.ts +14 -0
- package/shared/utils/pixi.ts +19 -246
- package/shared/zoom/zoom.ts +729 -0
- package/dist/shared/layers/Layers.svelte +0 -231
- package/dist/shared/layers/Layers.svelte.d.ts +0 -18
- package/dist/shared/layers/utils.d.ts +0 -73
- package/dist/shared/layers/utils.js +0 -156
- package/dist/shared/tools/Brush.svelte +0 -215
- package/dist/shared/tools/Brush.svelte.d.ts +0 -29
- package/dist/shared/tools/Crop.svelte +0 -155
- package/dist/shared/tools/Crop.svelte.d.ts +0 -16
- package/dist/shared/tools/Cropper.svelte +0 -271
- package/dist/shared/tools/Cropper.svelte.d.ts +0 -41
- package/dist/shared/tools/Handle.svelte +0 -260
- package/dist/shared/tools/Handle.svelte.d.ts +0 -29
- package/dist/shared/tools/Sources.svelte +0 -257
- package/dist/shared/tools/Sources.svelte.d.ts +0 -34
- package/dist/shared/tools/Tools.svelte +0 -102
- package/dist/shared/tools/Tools.svelte.d.ts +0 -48
- package/dist/shared/tools/brush.d.ts +0 -62
- package/dist/shared/tools/brush.js +0 -133
- package/dist/shared/tools/crop.d.ts +0 -15
- package/dist/shared/tools/crop.js +0 -154
- package/dist/shared/tools/index.d.ts +0 -5
- package/dist/shared/tools/index.js +0 -5
- package/dist/shared/tools/sources.d.ts +0 -46
- package/dist/shared/tools/sources.js +0 -121
- package/dist/shared/tools/types.d.ts +0 -1
- package/shared/layers/Layers.svelte +0 -250
- package/shared/layers/utils.ts +0 -294
- package/shared/tools/Brush.svelte +0 -280
- package/shared/tools/BrushOptions.svelte +0 -180
- package/shared/tools/Crop.svelte +0 -189
- package/shared/tools/Cropper.svelte +0 -346
- package/shared/tools/Handle.svelte +0 -289
- package/shared/tools/Sources.svelte +0 -283
- package/shared/tools/Tools.svelte +0 -162
- package/shared/tools/brush.ts +0 -247
- package/shared/tools/crop.ts +0 -213
- package/shared/tools/index.ts +0 -5
- package/shared/tools/sources.ts +0 -195
- package/shared/tools/types.ts +0 -1
- /package/dist/shared/{tools → brush}/BrushSize.svelte.d.ts +0 -0
- /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
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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?:
|
|
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
|
-
|
|
57
|
-
|
|
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
|
-
|
|
60
|
-
|
|
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
|
|
80
|
-
get
|
|
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>
|