@pixerate/editor-svelte 0.161.1 → 0.162.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.
@@ -2,6 +2,7 @@
2
2
  import { imageRangeClass, imageSectionTitleClass } from './styles.js';
3
3
  import MaskEdgeCheck from './MaskEdgeCheck.svelte';
4
4
  import SelectionChangeCheck from './SelectionChangeCheck.svelte';
5
+ import SeparateSubjectPanel from './SeparateSubjectPanel.svelte';
5
6
  import type {
6
7
  AdjustmentKind,
7
8
  AdjustmentLayer,
@@ -170,6 +171,7 @@
170
171
  {/if}
171
172
  <MaskEdgeCheck {controller} selection={sel} />
172
173
  <SelectionChangeCheck {controller} selection={sel} />
174
+ <SeparateSubjectPanel {controller} selection={sel} class="mt-2" />
173
175
 
174
176
  <span class="font-semibold text-foreground uppercase tracking-wider text-[11px] mt-2">Layer Mask</span>
175
177
  <div class="flex gap-1 items-center">
@@ -0,0 +1,82 @@
1
+ <script lang="ts">
2
+ import type { ImageEditorController, SelectionMask } from '@pixerate/editor/image-editor';
3
+
4
+ /**
5
+ * Separate Subject: the selected subject onto its own masked layer over a background plate with
6
+ * the subject's area filled, in one undo step, as the `separate_subject` tool does. Shows progress
7
+ * while the fill runs and can be cancelled.
8
+ */
9
+ interface Props {
10
+ controller: ImageEditorController;
11
+ /** The current selection (`state.selection`): the subject to separate. */
12
+ selection?: SelectionMask | null;
13
+ class?: string;
14
+ }
15
+
16
+ let { controller, selection, class: className = '' }: Props = $props();
17
+
18
+ const button =
19
+ 'px-2 py-1 rounded-md border border-border bg-background text-[11px] text-foreground hover:bg-accent hover:text-accent-foreground disabled:opacity-40';
20
+ const sel = $derived(selection === undefined ? controller.getSelection() : selection);
21
+ let dilate = $state(8);
22
+ let fill = $state(true);
23
+ let progress = $state<string | null>(null);
24
+ let error = $state<string | null>(null);
25
+ let abort: AbortController | null = null;
26
+
27
+ async function run() {
28
+ error = null;
29
+ const ctl = new AbortController();
30
+ abort = ctl;
31
+ progress = 'Starting';
32
+ try {
33
+ await controller.separateSubject({
34
+ dilate,
35
+ fill: fill ? 'content-aware' : 'none',
36
+ signal: ctl.signal,
37
+ onProgress: (fraction, stage) => (progress = `${stage ?? 'Filling'} ${Math.round(fraction * 100)}%`),
38
+ });
39
+ } catch (err) {
40
+ if (!ctl.signal.aborted) error = err instanceof Error ? err.message : String(err);
41
+ } finally {
42
+ abort = null;
43
+ progress = null;
44
+ }
45
+ }
46
+ </script>
47
+
48
+ <div data-testid="separate-subject" class="flex flex-col gap-1.5 text-xs {className}">
49
+ <span class="font-semibold text-foreground uppercase tracking-wider text-[11px]">Separate Subject</span>
50
+ <p class="text-muted-foreground">The selection onto its own masked layer, over the background with the subject filled out.</p>
51
+ <div class="flex flex-wrap items-center gap-2">
52
+ <label class="flex items-center gap-1 text-muted-foreground">
53
+ Grow
54
+ <input
55
+ type="number"
56
+ min="0"
57
+ max="200"
58
+ aria-label="Separate grow"
59
+ value={dilate}
60
+ oninput={(e) => (dilate = Math.min(200, Math.max(0, Number((e.currentTarget as HTMLInputElement).value) || 0)))}
61
+ class="w-12 bg-background border border-border rounded px-1 py-0.5 text-foreground"
62
+ />
63
+ px
64
+ </label>
65
+ <label class="flex items-center gap-1 text-foreground">
66
+ <input type="checkbox" aria-label="Fill the background" checked={fill} onchange={(e) => (fill = (e.currentTarget as HTMLInputElement).checked)} />
67
+ Fill the background
68
+ </label>
69
+ </div>
70
+ <div class="flex gap-1">
71
+ <button type="button" class={button} disabled={!sel || progress !== null} onclick={run}>Separate Subject</button>
72
+ {#if progress !== null}
73
+ <button type="button" class={button} onclick={() => abort?.abort()}>Cancel</button>
74
+ {/if}
75
+ </div>
76
+ {#if progress !== null}
77
+ <p role="status" class="text-muted-foreground">{progress}</p>
78
+ {/if}
79
+ {#if error}
80
+ <p role="alert" class="text-destructive">{error}</p>
81
+ {/if}
82
+ </div>
@@ -0,0 +1,15 @@
1
+ import type { ImageEditorController, SelectionMask } from '@pixerate/editor/image-editor';
2
+ /**
3
+ * Separate Subject: the selected subject onto its own masked layer over a background plate with
4
+ * the subject's area filled, in one undo step, as the `separate_subject` tool does. Shows progress
5
+ * while the fill runs and can be cancelled.
6
+ */
7
+ interface Props {
8
+ controller: ImageEditorController;
9
+ /** The current selection (`state.selection`): the subject to separate. */
10
+ selection?: SelectionMask | null;
11
+ class?: string;
12
+ }
13
+ declare const SeparateSubjectPanel: import("svelte").Component<Props, {}, "">;
14
+ type SeparateSubjectPanel = ReturnType<typeof SeparateSubjectPanel>;
15
+ export default SeparateSubjectPanel;
@@ -10,6 +10,7 @@ import type SelectionOptionsBarComponent from "./SelectionOptionsBar.svelte";
10
10
  import type RefineEdgePanelComponent from "./RefineEdgePanel.svelte";
11
11
  import type MaskEdgeCheckComponent from "./MaskEdgeCheck.svelte";
12
12
  import type SelectionChangeCheckComponent from "./SelectionChangeCheck.svelte";
13
+ import type SeparateSubjectPanelComponent from "./SeparateSubjectPanel.svelte";
13
14
  import type PathsPanelComponent from "./PathsPanel.svelte";
14
15
  import type SelectAndMaskWorkspaceComponent from "./SelectAndMaskWorkspace.svelte";
15
16
  import type ContentAwareFillWorkspaceComponent from "./ContentAwareFillWorkspace.svelte";
@@ -40,6 +41,7 @@ export { default as SelectionOptionsBar } from './SelectionOptionsBar.svelte';
40
41
  export { default as RefineEdgePanel } from './RefineEdgePanel.svelte';
41
42
  export { default as MaskEdgeCheck } from './MaskEdgeCheck.svelte';
42
43
  export { default as SelectionChangeCheck } from './SelectionChangeCheck.svelte';
44
+ export { default as SeparateSubjectPanel } from './SeparateSubjectPanel.svelte';
43
45
  export { default as PathsPanel } from './PathsPanel.svelte';
44
46
  export { default as SelectAndMaskWorkspace } from './SelectAndMaskWorkspace.svelte';
45
47
  export { default as ContentAwareFillWorkspace } from './ContentAwareFillWorkspace.svelte';
@@ -72,6 +74,7 @@ export type SelectionOptionsBarProps = ComponentProps<typeof SelectionOptionsBar
72
74
  export type RefineEdgePanelProps = ComponentProps<typeof RefineEdgePanelComponent>;
73
75
  export type MaskEdgeCheckProps = ComponentProps<typeof MaskEdgeCheckComponent>;
74
76
  export type SelectionChangeCheckProps = ComponentProps<typeof SelectionChangeCheckComponent>;
77
+ export type SeparateSubjectPanelProps = ComponentProps<typeof SeparateSubjectPanelComponent>;
75
78
  export type PathsPanelProps = ComponentProps<typeof PathsPanelComponent>;
76
79
  export type SelectAndMaskWorkspaceProps = ComponentProps<typeof SelectAndMaskWorkspaceComponent>;
77
80
  export type ContentAwareFillWorkspaceProps = ComponentProps<typeof ContentAwareFillWorkspaceComponent>;
@@ -12,6 +12,7 @@ export { default as SelectionOptionsBar } from './SelectionOptionsBar.svelte';
12
12
  export { default as RefineEdgePanel } from './RefineEdgePanel.svelte';
13
13
  export { default as MaskEdgeCheck } from './MaskEdgeCheck.svelte';
14
14
  export { default as SelectionChangeCheck } from './SelectionChangeCheck.svelte';
15
+ export { default as SeparateSubjectPanel } from './SeparateSubjectPanel.svelte';
15
16
  export { default as PathsPanel } from './PathsPanel.svelte';
16
17
  export { default as SelectAndMaskWorkspace } from './SelectAndMaskWorkspace.svelte';
17
18
  export { default as ContentAwareFillWorkspace } from './ContentAwareFillWorkspace.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor-svelte",
3
- "version": "0.161.1",
3
+ "version": "0.162.0",
4
4
  "description": "Svelte bindings and prompt/rich-text components for @pixerate/editor",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -165,7 +165,7 @@
165
165
  "**/*.css"
166
166
  ],
167
167
  "dependencies": {
168
- "@pixerate/editor": "0.218.0"
168
+ "@pixerate/editor": "0.219.0"
169
169
  },
170
170
  "peerDependencies": {
171
171
  "@dagrejs/dagre": "^1.1.4",