@pixerate/editor 0.183.0 → 0.185.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/dist/{chunk-UHMSMUHK.cjs → chunk-C6TRAAG4.cjs} +3 -1
- package/dist/{chunk-Y46OMERN.js → chunk-GYYSPMVU.js} +3 -1
- package/dist/image-editor/controller.d.cts +152 -8
- package/dist/image-editor/controller.d.ts +152 -8
- package/dist/image-editor/index.cjs +1986 -832
- package/dist/image-editor/index.js +1209 -55
- package/dist/image-editor/layers/panel.d.cts +23 -1
- package/dist/image-editor/layers/panel.d.ts +23 -1
- package/dist/image-editor/selection/gesture.d.cts +40 -2
- package/dist/image-editor/selection/gesture.d.ts +40 -2
- package/dist/image-editor/selection/index.d.cts +1 -0
- package/dist/image-editor/selection/index.d.ts +1 -0
- package/dist/image-editor/selection/modify.d.cts +3 -2
- package/dist/image-editor/selection/modify.d.ts +3 -2
- package/dist/image-editor/selection/stroke.d.cts +8 -0
- package/dist/image-editor/selection/stroke.d.ts +8 -0
- package/dist/image-editor/selection/tool-options.d.cts +12 -2
- package/dist/image-editor/selection/tool-options.d.ts +12 -2
- package/dist/image-editor/selection/wand.d.cts +37 -0
- package/dist/image-editor/selection/wand.d.ts +37 -0
- package/dist/image-editor/selection-tools.d.cts +8 -3
- package/dist/image-editor/selection-tools.d.ts +8 -3
- package/dist/image-editor/tools.d.cts +8 -2
- package/dist/image-editor/tools.d.ts +8 -2
- package/dist/image-editor/types.d.cts +2 -0
- package/dist/image-editor/types.d.ts +2 -0
- package/dist/paint-editor/index.cjs +6 -6
- package/dist/paint-editor/index.js +1 -1
- package/package.json +1 -1
- package/skills/pixerate-image-editor/SKILL.md +12 -21
- package/skills/pixerate-image-editor/references/free-transform.md +22 -0
- package/skills/pixerate-image-selection-masking/SKILL.md +23 -2
|
@@ -6,6 +6,28 @@
|
|
|
6
6
|
import type { ImageEditorController } from '../controller.cjs';
|
|
7
7
|
import { type ImageLayer, type SmartFilter } from './model.cjs';
|
|
8
8
|
import type { LayerPlacement } from './ops.cjs';
|
|
9
|
+
/**
|
|
10
|
+
* A click on a layer's mask thumbnail, as in Photoshop: Ctrl/⌘-click loads the mask as the
|
|
11
|
+
* selection (with Shift adding, Alt subtracting, both intersecting), Shift-click turns the mask
|
|
12
|
+
* on or off, and a plain click makes the mask the paint target.
|
|
13
|
+
*/
|
|
14
|
+
export declare function maskThumbnailClick(controller: ImageEditorController, layer: ImageLayer, e: {
|
|
15
|
+
ctrlKey?: boolean;
|
|
16
|
+
metaKey?: boolean;
|
|
17
|
+
shiftKey?: boolean;
|
|
18
|
+
altKey?: boolean;
|
|
19
|
+
}): void;
|
|
20
|
+
/**
|
|
21
|
+
* A click on a layer's pixel thumbnail: Ctrl/⌘-click loads the layer's transparency as the
|
|
22
|
+
* selection (Shift adds, Alt subtracts, both intersect) and returns true; other clicks are left
|
|
23
|
+
* to the row (false).
|
|
24
|
+
*/
|
|
25
|
+
export declare function layerThumbnailClick(controller: ImageEditorController, layer: ImageLayer, e: {
|
|
26
|
+
ctrlKey?: boolean;
|
|
27
|
+
metaKey?: boolean;
|
|
28
|
+
shiftKey?: boolean;
|
|
29
|
+
altKey?: boolean;
|
|
30
|
+
}): boolean;
|
|
9
31
|
export interface LayerPanelRow {
|
|
10
32
|
layer: ImageLayer;
|
|
11
33
|
/** Nesting depth (0 = top level). */
|
|
@@ -34,7 +56,7 @@ export type DropZone = 'above' | 'below' | 'inside';
|
|
|
34
56
|
export declare function dropZone(fraction: number, isGroup: boolean): DropZone;
|
|
35
57
|
/** The placement for `move_layer` when `dragId` is dropped on row `targetId` in `zone`, or `null` for a no-op. */
|
|
36
58
|
export declare function dropPlacement(layers: readonly ImageLayer[], dragId: string, targetId: string, zone: DropZone): LayerPlacement | null;
|
|
37
|
-
export type LayerMenuAction = 'new-layer' | 'new-group' | 'duplicate' | 'delete' | 'group-selected' | 'ungroup' | 'merge-down' | 'merge-visible' | 'flatten' | 'via-copy' | 'via-cut' | 'add-mask' | 'add-mask-selection' | 'apply-mask' | 'delete-mask' | 'toggle-mask' | 'toggle-mask-link' | 'toggle-clip' | 'rasterize' | 'convert-smart' | 'edit-contents' | 'smart-via-copy' | 'add-filter-mask';
|
|
59
|
+
export type LayerMenuAction = 'new-layer' | 'new-group' | 'duplicate' | 'delete' | 'group-selected' | 'ungroup' | 'merge-down' | 'merge-visible' | 'flatten' | 'via-copy' | 'via-cut' | 'add-mask' | 'add-mask-selection' | 'add-mask-hide-selection' | 'add-mask-transparency' | 'select-transparency' | 'apply-mask' | 'delete-mask' | 'toggle-mask' | 'toggle-mask-link' | 'toggle-clip' | 'rasterize' | 'convert-smart' | 'edit-contents' | 'smart-via-copy' | 'add-filter-mask';
|
|
38
60
|
export interface LayerMenuItem {
|
|
39
61
|
action: LayerMenuAction;
|
|
40
62
|
label: string;
|
|
@@ -6,6 +6,28 @@
|
|
|
6
6
|
import type { ImageEditorController } from '../controller.js';
|
|
7
7
|
import { type ImageLayer, type SmartFilter } from './model.js';
|
|
8
8
|
import type { LayerPlacement } from './ops.js';
|
|
9
|
+
/**
|
|
10
|
+
* A click on a layer's mask thumbnail, as in Photoshop: Ctrl/⌘-click loads the mask as the
|
|
11
|
+
* selection (with Shift adding, Alt subtracting, both intersecting), Shift-click turns the mask
|
|
12
|
+
* on or off, and a plain click makes the mask the paint target.
|
|
13
|
+
*/
|
|
14
|
+
export declare function maskThumbnailClick(controller: ImageEditorController, layer: ImageLayer, e: {
|
|
15
|
+
ctrlKey?: boolean;
|
|
16
|
+
metaKey?: boolean;
|
|
17
|
+
shiftKey?: boolean;
|
|
18
|
+
altKey?: boolean;
|
|
19
|
+
}): void;
|
|
20
|
+
/**
|
|
21
|
+
* A click on a layer's pixel thumbnail: Ctrl/⌘-click loads the layer's transparency as the
|
|
22
|
+
* selection (Shift adds, Alt subtracts, both intersect) and returns true; other clicks are left
|
|
23
|
+
* to the row (false).
|
|
24
|
+
*/
|
|
25
|
+
export declare function layerThumbnailClick(controller: ImageEditorController, layer: ImageLayer, e: {
|
|
26
|
+
ctrlKey?: boolean;
|
|
27
|
+
metaKey?: boolean;
|
|
28
|
+
shiftKey?: boolean;
|
|
29
|
+
altKey?: boolean;
|
|
30
|
+
}): boolean;
|
|
9
31
|
export interface LayerPanelRow {
|
|
10
32
|
layer: ImageLayer;
|
|
11
33
|
/** Nesting depth (0 = top level). */
|
|
@@ -34,7 +56,7 @@ export type DropZone = 'above' | 'below' | 'inside';
|
|
|
34
56
|
export declare function dropZone(fraction: number, isGroup: boolean): DropZone;
|
|
35
57
|
/** The placement for `move_layer` when `dragId` is dropped on row `targetId` in `zone`, or `null` for a no-op. */
|
|
36
58
|
export declare function dropPlacement(layers: readonly ImageLayer[], dragId: string, targetId: string, zone: DropZone): LayerPlacement | null;
|
|
37
|
-
export type LayerMenuAction = 'new-layer' | 'new-group' | 'duplicate' | 'delete' | 'group-selected' | 'ungroup' | 'merge-down' | 'merge-visible' | 'flatten' | 'via-copy' | 'via-cut' | 'add-mask' | 'add-mask-selection' | 'apply-mask' | 'delete-mask' | 'toggle-mask' | 'toggle-mask-link' | 'toggle-clip' | 'rasterize' | 'convert-smart' | 'edit-contents' | 'smart-via-copy' | 'add-filter-mask';
|
|
59
|
+
export type LayerMenuAction = 'new-layer' | 'new-group' | 'duplicate' | 'delete' | 'group-selected' | 'ungroup' | 'merge-down' | 'merge-visible' | 'flatten' | 'via-copy' | 'via-cut' | 'add-mask' | 'add-mask-selection' | 'add-mask-hide-selection' | 'add-mask-transparency' | 'select-transparency' | 'apply-mask' | 'delete-mask' | 'toggle-mask' | 'toggle-mask-link' | 'toggle-clip' | 'rasterize' | 'convert-smart' | 'edit-contents' | 'smart-via-copy' | 'add-filter-mask';
|
|
38
60
|
export interface LayerMenuItem {
|
|
39
61
|
action: LayerMenuAction;
|
|
40
62
|
label: string;
|
|
@@ -4,14 +4,26 @@ import { type SelectionToolOptions } from './tool-options.cjs';
|
|
|
4
4
|
export interface GestureModifiers {
|
|
5
5
|
shiftKey?: boolean;
|
|
6
6
|
altKey?: boolean;
|
|
7
|
+
/** The click count of a mouse event (2 on a double-click). */
|
|
8
|
+
detail?: number;
|
|
7
9
|
}
|
|
10
|
+
/** `point` moved onto the nearest 45° ray from `from` (Shift with the polygonal lasso). */
|
|
11
|
+
export declare function snapTo45(from: ImagePoint, point: ImagePoint): ImagePoint;
|
|
8
12
|
/**
|
|
9
13
|
* Pointer gestures of the selection tools, shared by the React and Svelte image editors: feed
|
|
10
14
|
* it pointer positions in natural image pixels (`canvasToImagePoint(..., false)`).
|
|
11
15
|
*
|
|
12
16
|
* - Magic wand: selects on `begin` (async, as it may read pixels).
|
|
17
|
+
* - Color Range: on `begin`, samples the colour under the pointer and selects every similar pixel
|
|
18
|
+
* (with the modifiers, Shift-click adds a colour and Alt-click removes one, as the + and −
|
|
19
|
+
* eyedroppers).
|
|
13
20
|
* - Rectangle / ellipse: drag a box; a click without a drag deselects (replace mode).
|
|
14
21
|
* - Lasso: drag a free-hand path, closed on `end`.
|
|
22
|
+
* - Polygonal lasso: each click adds a corner (Shift: on a 45° ray from the last one), dragging
|
|
23
|
+
* adds a free-hand stretch; a double-click, a click on the first corner or Enter (`key`)
|
|
24
|
+
* closes it, Backspace removes the last corner and Escape cancels. It stays `active` between
|
|
25
|
+
* clicks, so feed it pointer moves without a button too.
|
|
26
|
+
* - Single row / column: a click selects a 1 px line across the image.
|
|
15
27
|
*
|
|
16
28
|
* Shift adds, Alt subtracts, both intersect (overriding the options bar mode). While dragging,
|
|
17
29
|
* {@link draftPath} is the outline to show (`RenderOptions.draftSelectionPath`).
|
|
@@ -23,6 +35,12 @@ export declare class SelectionGesture {
|
|
|
23
35
|
private points;
|
|
24
36
|
private current;
|
|
25
37
|
private modifiers;
|
|
38
|
+
/** Polygonal lasso corners while one is being drawn. */
|
|
39
|
+
private polygon;
|
|
40
|
+
private pressedAt;
|
|
41
|
+
private freehand;
|
|
42
|
+
/** A click this close to the first corner (natural pixels) closes a polygonal lasso. */
|
|
43
|
+
closeRadius: number;
|
|
26
44
|
/** The last error (e.g. pixels unavailable for the wand), for the UI to show. */
|
|
27
45
|
error: string | null;
|
|
28
46
|
constructor(controller: ImageEditorController, getOptions: () => SelectionToolOptions);
|
|
@@ -32,9 +50,29 @@ export declare class SelectionGesture {
|
|
|
32
50
|
/** Pointer down. Resolves once a wand click has been applied. */
|
|
33
51
|
begin(point: ImagePoint, modifiers?: GestureModifiers): Promise<void>;
|
|
34
52
|
/** Pointer move; returns true when the draft changed (re-render). */
|
|
35
|
-
move(point: ImagePoint): boolean;
|
|
53
|
+
move(point: ImagePoint, modifiers?: GestureModifiers): boolean;
|
|
36
54
|
/** Pointer up: commits the shape. Returns true when the selection changed. */
|
|
37
55
|
end(point?: ImagePoint, modifiers?: GestureModifiers): boolean;
|
|
38
|
-
/**
|
|
56
|
+
/** Closes a polygonal lasso and selects it. Returns true when the selection changed. */
|
|
57
|
+
close(): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Keys for a polygonal lasso being drawn: Enter closes it, Escape cancels, Backspace / Delete
|
|
60
|
+
* removes the last corner. Returns true when the key was used (the host prevents its default).
|
|
61
|
+
*/
|
|
62
|
+
key(key: string): boolean;
|
|
63
|
+
/** Abandons a drag (or a polygonal lasso) without changing the selection. */
|
|
39
64
|
cancel(): void;
|
|
40
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Edit shortcuts in select mode, as in Photoshop: Ctrl/⌘+C copies (with Shift, Copy Merged),
|
|
68
|
+
* Ctrl/⌘+X cuts, Ctrl/⌘+V pastes (with Shift, in place; with Alt+Shift, into the selection),
|
|
69
|
+
* Ctrl/⌘+D deselects, Ctrl/⌘+Shift+D reselects and Ctrl/⌘+Shift+I inverts. Returns true when
|
|
70
|
+
* the key was used (the host prevents its default); errors go to `onError`.
|
|
71
|
+
*/
|
|
72
|
+
export declare function handleSelectionShortcut(controller: ImageEditorController, e: {
|
|
73
|
+
key: string;
|
|
74
|
+
ctrlKey?: boolean;
|
|
75
|
+
metaKey?: boolean;
|
|
76
|
+
shiftKey?: boolean;
|
|
77
|
+
altKey?: boolean;
|
|
78
|
+
}, onError?: (message: string) => void): boolean;
|
|
@@ -4,14 +4,26 @@ import { type SelectionToolOptions } from './tool-options.js';
|
|
|
4
4
|
export interface GestureModifiers {
|
|
5
5
|
shiftKey?: boolean;
|
|
6
6
|
altKey?: boolean;
|
|
7
|
+
/** The click count of a mouse event (2 on a double-click). */
|
|
8
|
+
detail?: number;
|
|
7
9
|
}
|
|
10
|
+
/** `point` moved onto the nearest 45° ray from `from` (Shift with the polygonal lasso). */
|
|
11
|
+
export declare function snapTo45(from: ImagePoint, point: ImagePoint): ImagePoint;
|
|
8
12
|
/**
|
|
9
13
|
* Pointer gestures of the selection tools, shared by the React and Svelte image editors: feed
|
|
10
14
|
* it pointer positions in natural image pixels (`canvasToImagePoint(..., false)`).
|
|
11
15
|
*
|
|
12
16
|
* - Magic wand: selects on `begin` (async, as it may read pixels).
|
|
17
|
+
* - Color Range: on `begin`, samples the colour under the pointer and selects every similar pixel
|
|
18
|
+
* (with the modifiers, Shift-click adds a colour and Alt-click removes one, as the + and −
|
|
19
|
+
* eyedroppers).
|
|
13
20
|
* - Rectangle / ellipse: drag a box; a click without a drag deselects (replace mode).
|
|
14
21
|
* - Lasso: drag a free-hand path, closed on `end`.
|
|
22
|
+
* - Polygonal lasso: each click adds a corner (Shift: on a 45° ray from the last one), dragging
|
|
23
|
+
* adds a free-hand stretch; a double-click, a click on the first corner or Enter (`key`)
|
|
24
|
+
* closes it, Backspace removes the last corner and Escape cancels. It stays `active` between
|
|
25
|
+
* clicks, so feed it pointer moves without a button too.
|
|
26
|
+
* - Single row / column: a click selects a 1 px line across the image.
|
|
15
27
|
*
|
|
16
28
|
* Shift adds, Alt subtracts, both intersect (overriding the options bar mode). While dragging,
|
|
17
29
|
* {@link draftPath} is the outline to show (`RenderOptions.draftSelectionPath`).
|
|
@@ -23,6 +35,12 @@ export declare class SelectionGesture {
|
|
|
23
35
|
private points;
|
|
24
36
|
private current;
|
|
25
37
|
private modifiers;
|
|
38
|
+
/** Polygonal lasso corners while one is being drawn. */
|
|
39
|
+
private polygon;
|
|
40
|
+
private pressedAt;
|
|
41
|
+
private freehand;
|
|
42
|
+
/** A click this close to the first corner (natural pixels) closes a polygonal lasso. */
|
|
43
|
+
closeRadius: number;
|
|
26
44
|
/** The last error (e.g. pixels unavailable for the wand), for the UI to show. */
|
|
27
45
|
error: string | null;
|
|
28
46
|
constructor(controller: ImageEditorController, getOptions: () => SelectionToolOptions);
|
|
@@ -32,9 +50,29 @@ export declare class SelectionGesture {
|
|
|
32
50
|
/** Pointer down. Resolves once a wand click has been applied. */
|
|
33
51
|
begin(point: ImagePoint, modifiers?: GestureModifiers): Promise<void>;
|
|
34
52
|
/** Pointer move; returns true when the draft changed (re-render). */
|
|
35
|
-
move(point: ImagePoint): boolean;
|
|
53
|
+
move(point: ImagePoint, modifiers?: GestureModifiers): boolean;
|
|
36
54
|
/** Pointer up: commits the shape. Returns true when the selection changed. */
|
|
37
55
|
end(point?: ImagePoint, modifiers?: GestureModifiers): boolean;
|
|
38
|
-
/**
|
|
56
|
+
/** Closes a polygonal lasso and selects it. Returns true when the selection changed. */
|
|
57
|
+
close(): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Keys for a polygonal lasso being drawn: Enter closes it, Escape cancels, Backspace / Delete
|
|
60
|
+
* removes the last corner. Returns true when the key was used (the host prevents its default).
|
|
61
|
+
*/
|
|
62
|
+
key(key: string): boolean;
|
|
63
|
+
/** Abandons a drag (or a polygonal lasso) without changing the selection. */
|
|
39
64
|
cancel(): void;
|
|
40
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Edit shortcuts in select mode, as in Photoshop: Ctrl/⌘+C copies (with Shift, Copy Merged),
|
|
68
|
+
* Ctrl/⌘+X cuts, Ctrl/⌘+V pastes (with Shift, in place; with Alt+Shift, into the selection),
|
|
69
|
+
* Ctrl/⌘+D deselects, Ctrl/⌘+Shift+D reselects and Ctrl/⌘+Shift+I inverts. Returns true when
|
|
70
|
+
* the key was used (the host prevents its default); errors go to `onError`.
|
|
71
|
+
*/
|
|
72
|
+
export declare function handleSelectionShortcut(controller: ImageEditorController, e: {
|
|
73
|
+
key: string;
|
|
74
|
+
ctrlKey?: boolean;
|
|
75
|
+
metaKey?: boolean;
|
|
76
|
+
shiftKey?: boolean;
|
|
77
|
+
altKey?: boolean;
|
|
78
|
+
}, onError?: (message: string) => void): boolean;
|
|
@@ -31,7 +31,8 @@ export declare function greyMorphology(src: ArrayLike<number>, w: number, h: num
|
|
|
31
31
|
* use one morphology, the remainder blends with the next pixel, so 0.3 px differs from 1 px.
|
|
32
32
|
*/
|
|
33
33
|
export declare function shiftCoverage(src: ArrayLike<number>, w: number, h: number, amount: number): Float32Array;
|
|
34
|
-
|
|
34
|
+
/** `expand` / `contract` are Photoshop's names; `grow` / `shrink` are the same operations, kept as aliases. */
|
|
35
|
+
export type SelectionModifyOp = 'expand' | 'contract' | 'grow' | 'shrink' | 'feather' | 'border' | 'smooth';
|
|
35
36
|
export declare const SELECTION_MODIFY_OPS: readonly SelectionModifyOp[];
|
|
36
|
-
/** Select › Modify (
|
|
37
|
+
/** Select › Modify (expand, contract, feather, border, smooth; grow and shrink are aliases) by `radius` pixels. */
|
|
37
38
|
export declare function modifySelection(mask: SelectionMask, op: SelectionModifyOp, radius: number): SelectionMask;
|
|
@@ -31,7 +31,8 @@ export declare function greyMorphology(src: ArrayLike<number>, w: number, h: num
|
|
|
31
31
|
* use one morphology, the remainder blends with the next pixel, so 0.3 px differs from 1 px.
|
|
32
32
|
*/
|
|
33
33
|
export declare function shiftCoverage(src: ArrayLike<number>, w: number, h: number, amount: number): Float32Array;
|
|
34
|
-
|
|
34
|
+
/** `expand` / `contract` are Photoshop's names; `grow` / `shrink` are the same operations, kept as aliases. */
|
|
35
|
+
export type SelectionModifyOp = 'expand' | 'contract' | 'grow' | 'shrink' | 'feather' | 'border' | 'smooth';
|
|
35
36
|
export declare const SELECTION_MODIFY_OPS: readonly SelectionModifyOp[];
|
|
36
|
-
/** Select › Modify (
|
|
37
|
+
/** Select › Modify (expand, contract, feather, border, smooth; grow and shrink are aliases) by `radius` pixels. */
|
|
37
38
|
export declare function modifySelection(mask: SelectionMask, op: SelectionModifyOp, radius: number): SelectionMask;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type SelectionMask } from './mask.cjs';
|
|
2
|
+
/**
|
|
3
|
+
* The band Edit › Stroke paints along a selection's edge, `width` pixels wide: `inside` is the
|
|
4
|
+
* selection minus the selection contracted by `width`, `outside` the selection expanded by
|
|
5
|
+
* `width` minus the selection, and `center` straddles the edge by `width / 2` each way. Built
|
|
6
|
+
* from the exact distance transform the Modify commands use, so the band keeps soft edges.
|
|
7
|
+
*/
|
|
8
|
+
export declare function selectionRing(sel: SelectionMask, width: number, location: 'inside' | 'center' | 'outside'): SelectionMask;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type SelectionMask } from './mask.js';
|
|
2
|
+
/**
|
|
3
|
+
* The band Edit › Stroke paints along a selection's edge, `width` pixels wide: `inside` is the
|
|
4
|
+
* selection minus the selection contracted by `width`, `outside` the selection expanded by
|
|
5
|
+
* `width` minus the selection, and `center` straddles the edge by `width / 2` each way. Built
|
|
6
|
+
* from the exact distance transform the Modify commands use, so the band keeps soft edges.
|
|
7
|
+
*/
|
|
8
|
+
export declare function selectionRing(sel: SelectionMask, width: number, location: 'inside' | 'center' | 'outside'): SelectionMask;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { SelectionMask, SelectionMode } from './mask.cjs';
|
|
2
|
-
import type { ColorDistance } from './wand.cjs';
|
|
2
|
+
import type { ColorDistance, ColorRangePreset } from './wand.cjs';
|
|
3
3
|
import type { RefineEdgeParams } from './refine.cjs';
|
|
4
4
|
/** Selection tools of the image editor UI. */
|
|
5
|
-
export type SelectionToolKind = 'wand' | 'rect' | 'ellipse' | 'lasso';
|
|
5
|
+
export type SelectionToolKind = 'wand' | 'rect' | 'ellipse' | 'row' | 'column' | 'lasso' | 'polygon' | 'range';
|
|
6
6
|
export declare const SELECTION_TOOLS: readonly {
|
|
7
7
|
id: SelectionToolKind;
|
|
8
8
|
label: string;
|
|
9
9
|
}[];
|
|
10
|
+
/** Labels of the Color Range presets, in menu order. */
|
|
11
|
+
export declare const COLOR_RANGE_PRESET_LABELS: Record<ColorRangePreset, string>;
|
|
10
12
|
export declare const SELECTION_MODE_LABELS: Record<SelectionMode, string>;
|
|
11
13
|
/** The options bar of the selection tools (shared by the React and Svelte UIs). */
|
|
12
14
|
export interface SelectionToolOptions {
|
|
@@ -21,6 +23,14 @@ export interface SelectionToolOptions {
|
|
|
21
23
|
/** Sample the whole image (`composite`, default) or only the active pixel layer. */
|
|
22
24
|
sample?: 'composite' | 'active-layer';
|
|
23
25
|
distance: ColorDistance;
|
|
26
|
+
/** Feather new marquee, lasso, wand and Color Range selections by this many pixels (default 0). */
|
|
27
|
+
feather?: number;
|
|
28
|
+
/** Color Range: levels over which a sampled colour's coverage fades out (0..200, default 40). */
|
|
29
|
+
fuzziness?: number;
|
|
30
|
+
/** Color Range: limit each click to this radius in pixels (Localized Color Clusters; 0 = off). */
|
|
31
|
+
localized?: number;
|
|
32
|
+
/** Color Range: select everything except the sampled colours. */
|
|
33
|
+
rangeInvert?: boolean;
|
|
24
34
|
}
|
|
25
35
|
export declare const DEFAULT_SELECTION_TOOL_OPTIONS: SelectionToolOptions;
|
|
26
36
|
/**
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { SelectionMask, SelectionMode } from './mask.js';
|
|
2
|
-
import type { ColorDistance } from './wand.js';
|
|
2
|
+
import type { ColorDistance, ColorRangePreset } from './wand.js';
|
|
3
3
|
import type { RefineEdgeParams } from './refine.js';
|
|
4
4
|
/** Selection tools of the image editor UI. */
|
|
5
|
-
export type SelectionToolKind = 'wand' | 'rect' | 'ellipse' | 'lasso';
|
|
5
|
+
export type SelectionToolKind = 'wand' | 'rect' | 'ellipse' | 'row' | 'column' | 'lasso' | 'polygon' | 'range';
|
|
6
6
|
export declare const SELECTION_TOOLS: readonly {
|
|
7
7
|
id: SelectionToolKind;
|
|
8
8
|
label: string;
|
|
9
9
|
}[];
|
|
10
|
+
/** Labels of the Color Range presets, in menu order. */
|
|
11
|
+
export declare const COLOR_RANGE_PRESET_LABELS: Record<ColorRangePreset, string>;
|
|
10
12
|
export declare const SELECTION_MODE_LABELS: Record<SelectionMode, string>;
|
|
11
13
|
/** The options bar of the selection tools (shared by the React and Svelte UIs). */
|
|
12
14
|
export interface SelectionToolOptions {
|
|
@@ -21,6 +23,14 @@ export interface SelectionToolOptions {
|
|
|
21
23
|
/** Sample the whole image (`composite`, default) or only the active pixel layer. */
|
|
22
24
|
sample?: 'composite' | 'active-layer';
|
|
23
25
|
distance: ColorDistance;
|
|
26
|
+
/** Feather new marquee, lasso, wand and Color Range selections by this many pixels (default 0). */
|
|
27
|
+
feather?: number;
|
|
28
|
+
/** Color Range: levels over which a sampled colour's coverage fades out (0..200, default 40). */
|
|
29
|
+
fuzziness?: number;
|
|
30
|
+
/** Color Range: limit each click to this radius in pixels (Localized Color Clusters; 0 = off). */
|
|
31
|
+
localized?: number;
|
|
32
|
+
/** Color Range: select everything except the sampled colours. */
|
|
33
|
+
rangeInvert?: boolean;
|
|
24
34
|
}
|
|
25
35
|
export declare const DEFAULT_SELECTION_TOOL_OPTIONS: SelectionToolOptions;
|
|
26
36
|
/**
|
|
@@ -56,3 +56,40 @@ export declare function toneRange(pixels: PixelBuffer, range: ToneRangePreset |
|
|
|
56
56
|
* the centre, none 60° away) × chroma × (2 − max), so neutrals are never selected.
|
|
57
57
|
*/
|
|
58
58
|
export declare function hueRange(pixels: PixelBuffer, center: number): SelectionMask;
|
|
59
|
+
/** Hue centres (degrees) of the Color Range colour presets. */
|
|
60
|
+
export declare const HUE_RANGE_PRESETS: {
|
|
61
|
+
readonly reds: 0;
|
|
62
|
+
readonly yellows: 60;
|
|
63
|
+
readonly greens: 120;
|
|
64
|
+
readonly cyans: 180;
|
|
65
|
+
readonly blues: 240;
|
|
66
|
+
readonly magentas: 300;
|
|
67
|
+
};
|
|
68
|
+
/** Select › Color Range › Select menu: colours, tones and skin tones. */
|
|
69
|
+
export type ColorRangePreset = keyof typeof HUE_RANGE_PRESETS | ToneRangePreset | 'skinTones';
|
|
70
|
+
export declare const COLOR_RANGE_PRESETS: readonly ColorRangePreset[];
|
|
71
|
+
export declare function isColorRangePreset(v: unknown): v is ColorRangePreset;
|
|
72
|
+
/**
|
|
73
|
+
* Select › Color Range › Skin Tones: a heuristic over hue (full at 5–40°, none by 60° and −20°),
|
|
74
|
+
* HSV saturation (0.12–0.8) and value (above 0.3), so it covers light to dark skin and leaves
|
|
75
|
+
* out neutrals and saturated oranges. It also picks up skin-like wood, sand and leather.
|
|
76
|
+
*/
|
|
77
|
+
export declare function skinToneRange(pixels: PixelBuffer): SelectionMask;
|
|
78
|
+
/**
|
|
79
|
+
* A Color Range preset: `reds` … `magentas` (`hueRange`), `highlights` / `midtones` / `shadows`
|
|
80
|
+
* (`toneRange`, with `falloff` levels, default 20) or `skinTones` (`skinToneRange`).
|
|
81
|
+
*/
|
|
82
|
+
export declare function colorRangePreset(pixels: PixelBuffer, preset: ColorRangePreset, options?: {
|
|
83
|
+
falloff?: number;
|
|
84
|
+
}): SelectionMask;
|
|
85
|
+
export interface GrowSimilarOptions {
|
|
86
|
+
/** 0..255, the largest per-channel difference from a selected colour (default 32, as the wand). */
|
|
87
|
+
tolerance?: number;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Select › Grow: adds the pixels connected (4-neighbours) to the selection whose colour is
|
|
91
|
+
* within `tolerance` of a selected colour. Unlike Expand, it follows colour, not distance.
|
|
92
|
+
*/
|
|
93
|
+
export declare function growSelection(pixels: PixelBuffer, sel: SelectionMask, options?: GrowSimilarOptions): SelectionMask;
|
|
94
|
+
/** Select › Similar: adds every pixel in the image whose colour is within `tolerance` of a selected colour. */
|
|
95
|
+
export declare function selectSimilar(pixels: PixelBuffer, sel: SelectionMask, options?: GrowSimilarOptions): SelectionMask;
|
|
@@ -56,3 +56,40 @@ export declare function toneRange(pixels: PixelBuffer, range: ToneRangePreset |
|
|
|
56
56
|
* the centre, none 60° away) × chroma × (2 − max), so neutrals are never selected.
|
|
57
57
|
*/
|
|
58
58
|
export declare function hueRange(pixels: PixelBuffer, center: number): SelectionMask;
|
|
59
|
+
/** Hue centres (degrees) of the Color Range colour presets. */
|
|
60
|
+
export declare const HUE_RANGE_PRESETS: {
|
|
61
|
+
readonly reds: 0;
|
|
62
|
+
readonly yellows: 60;
|
|
63
|
+
readonly greens: 120;
|
|
64
|
+
readonly cyans: 180;
|
|
65
|
+
readonly blues: 240;
|
|
66
|
+
readonly magentas: 300;
|
|
67
|
+
};
|
|
68
|
+
/** Select › Color Range › Select menu: colours, tones and skin tones. */
|
|
69
|
+
export type ColorRangePreset = keyof typeof HUE_RANGE_PRESETS | ToneRangePreset | 'skinTones';
|
|
70
|
+
export declare const COLOR_RANGE_PRESETS: readonly ColorRangePreset[];
|
|
71
|
+
export declare function isColorRangePreset(v: unknown): v is ColorRangePreset;
|
|
72
|
+
/**
|
|
73
|
+
* Select › Color Range › Skin Tones: a heuristic over hue (full at 5–40°, none by 60° and −20°),
|
|
74
|
+
* HSV saturation (0.12–0.8) and value (above 0.3), so it covers light to dark skin and leaves
|
|
75
|
+
* out neutrals and saturated oranges. It also picks up skin-like wood, sand and leather.
|
|
76
|
+
*/
|
|
77
|
+
export declare function skinToneRange(pixels: PixelBuffer): SelectionMask;
|
|
78
|
+
/**
|
|
79
|
+
* A Color Range preset: `reds` … `magentas` (`hueRange`), `highlights` / `midtones` / `shadows`
|
|
80
|
+
* (`toneRange`, with `falloff` levels, default 20) or `skinTones` (`skinToneRange`).
|
|
81
|
+
*/
|
|
82
|
+
export declare function colorRangePreset(pixels: PixelBuffer, preset: ColorRangePreset, options?: {
|
|
83
|
+
falloff?: number;
|
|
84
|
+
}): SelectionMask;
|
|
85
|
+
export interface GrowSimilarOptions {
|
|
86
|
+
/** 0..255, the largest per-channel difference from a selected colour (default 32, as the wand). */
|
|
87
|
+
tolerance?: number;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Select › Grow: adds the pixels connected (4-neighbours) to the selection whose colour is
|
|
91
|
+
* within `tolerance` of a selected colour. Unlike Expand, it follows colour, not distance.
|
|
92
|
+
*/
|
|
93
|
+
export declare function growSelection(pixels: PixelBuffer, sel: SelectionMask, options?: GrowSimilarOptions): SelectionMask;
|
|
94
|
+
/** Select › Similar: adds every pixel in the image whose colour is within `tolerance` of a selected colour. */
|
|
95
|
+
export declare function selectSimilar(pixels: PixelBuffer, sel: SelectionMask, options?: GrowSimilarOptions): SelectionMask;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { AgentTool, AgentToolProvider } from '../tools/registry.cjs';
|
|
2
2
|
import type { ImageEditorController } from './controller.cjs';
|
|
3
3
|
/**
|
|
4
|
-
* Agent tools for selections and masks (part of `createImageEditorToolProvider`):
|
|
5
|
-
* `get_selection
|
|
6
|
-
*
|
|
4
|
+
* Agent tools for selections and masks (part of `createImageEditorToolProvider`): reading
|
|
5
|
+
* (`get_selection`), selecting (`select_all`, `deselect`, `invert_selection`, `select_rect`,
|
|
6
|
+
* `select_ellipse`, `select_polygon`, `select_line`, `magic_wand`, `select_color_range`,
|
|
7
|
+
* `grow_selection`, `select_similar`, `reselect`), loading (`load_selection_from_image`,
|
|
8
|
+
* `load_selection_from_mask`, `select_layer_transparency`), the view
|
|
9
|
+
* (`set_selection_display`), editing (`modify_selection`, `refine_selection`) and masking
|
|
10
|
+
* (`apply_selection_as_mask`). `select_region` and `select_by_color` are deprecated aliases.
|
|
11
|
+
* Coordinates are natural pixels of the source image.
|
|
7
12
|
*/
|
|
8
13
|
export declare function createImageSelectionTools(controller: ImageEditorController): AgentTool[];
|
|
9
14
|
/** Options for `createImageSegmentationToolProvider`. */
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { AgentTool, AgentToolProvider } from '../tools/registry.js';
|
|
2
2
|
import type { ImageEditorController } from './controller.js';
|
|
3
3
|
/**
|
|
4
|
-
* Agent tools for selections and masks (part of `createImageEditorToolProvider`):
|
|
5
|
-
* `get_selection
|
|
6
|
-
*
|
|
4
|
+
* Agent tools for selections and masks (part of `createImageEditorToolProvider`): reading
|
|
5
|
+
* (`get_selection`), selecting (`select_all`, `deselect`, `invert_selection`, `select_rect`,
|
|
6
|
+
* `select_ellipse`, `select_polygon`, `select_line`, `magic_wand`, `select_color_range`,
|
|
7
|
+
* `grow_selection`, `select_similar`, `reselect`), loading (`load_selection_from_image`,
|
|
8
|
+
* `load_selection_from_mask`, `select_layer_transparency`), the view
|
|
9
|
+
* (`set_selection_display`), editing (`modify_selection`, `refine_selection`) and masking
|
|
10
|
+
* (`apply_selection_as_mask`). `select_region` and `select_by_color` are deprecated aliases.
|
|
11
|
+
* Coordinates are natural pixels of the source image.
|
|
7
12
|
*/
|
|
8
13
|
export declare function createImageSelectionTools(controller: ImageEditorController): AgentTool[];
|
|
9
14
|
/** Options for `createImageSegmentationToolProvider`. */
|
|
@@ -23,8 +23,14 @@ export interface ImageEditorToolProviderOptions {
|
|
|
23
23
|
* - `render_preview {maxSide}`: the rendered image as a PNG, longest side at most `maxSide`.
|
|
24
24
|
* - `capture_view {region, rect?, ...}`: a screenshot of the whole image, the selection or a rect in
|
|
25
25
|
* natural pixels (up to 8× for close inspection), optionally with the selection shaded.
|
|
26
|
-
* - Selections and masks: `get_selection`, `
|
|
27
|
-
* `
|
|
26
|
+
* - Selections and masks: `get_selection`, `select_all`, `deselect`, `invert_selection`,
|
|
27
|
+
* `select_rect`, `select_ellipse`, `select_polygon`, `select_line`, `magic_wand`,
|
|
28
|
+
* `select_color_range`, `grow_selection`, `select_similar`, `reselect`,
|
|
29
|
+
* `select_layer_transparency`, `stroke_selection`, `crop_to_selection`, `content_aware_fill`,
|
|
30
|
+
* `copy_pixels`, `cut_pixels`, `paste_pixels`,
|
|
31
|
+
* `load_selection_from_image`, `load_selection_from_mask`, `set_selection_display`,
|
|
32
|
+
* `modify_selection`, `refine_selection`, `apply_selection_as_mask` and the deprecated
|
|
33
|
+
* `select_region` / `select_by_color` (see `createImageSelectionTools`).
|
|
28
34
|
* - Layers, geometry and history: `get_image_info`, `get_histogram`, `update_adjustment_layer`,
|
|
29
35
|
* `remove_adjustment_layer`, `move_adjustment_layer`, `set_crop`, `reset_crop`, `set_rotation`,
|
|
30
36
|
* `flip_image`, `undo_image`, `redo_image` (see `createImageEditTools`).
|
|
@@ -23,8 +23,14 @@ export interface ImageEditorToolProviderOptions {
|
|
|
23
23
|
* - `render_preview {maxSide}`: the rendered image as a PNG, longest side at most `maxSide`.
|
|
24
24
|
* - `capture_view {region, rect?, ...}`: a screenshot of the whole image, the selection or a rect in
|
|
25
25
|
* natural pixels (up to 8× for close inspection), optionally with the selection shaded.
|
|
26
|
-
* - Selections and masks: `get_selection`, `
|
|
27
|
-
* `
|
|
26
|
+
* - Selections and masks: `get_selection`, `select_all`, `deselect`, `invert_selection`,
|
|
27
|
+
* `select_rect`, `select_ellipse`, `select_polygon`, `select_line`, `magic_wand`,
|
|
28
|
+
* `select_color_range`, `grow_selection`, `select_similar`, `reselect`,
|
|
29
|
+
* `select_layer_transparency`, `stroke_selection`, `crop_to_selection`, `content_aware_fill`,
|
|
30
|
+
* `copy_pixels`, `cut_pixels`, `paste_pixels`,
|
|
31
|
+
* `load_selection_from_image`, `load_selection_from_mask`, `set_selection_display`,
|
|
32
|
+
* `modify_selection`, `refine_selection`, `apply_selection_as_mask` and the deprecated
|
|
33
|
+
* `select_region` / `select_by_color` (see `createImageSelectionTools`).
|
|
28
34
|
* - Layers, geometry and history: `get_image_info`, `get_histogram`, `update_adjustment_layer`,
|
|
29
35
|
* `remove_adjustment_layer`, `move_adjustment_layer`, `set_crop`, `reset_crop`, `set_rotation`,
|
|
30
36
|
* `flip_image`, `undo_image`, `redo_image` (see `createImageEditTools`).
|
|
@@ -311,6 +311,8 @@ export interface ImageEditorState {
|
|
|
311
311
|
selection?: SelectionMask | null;
|
|
312
312
|
/** Quick Mask view: tint the unselected area instead of drawing marching ants (view state). */
|
|
313
313
|
quickMask?: boolean;
|
|
314
|
+
/** How the canvas shows the selection (view state; `quickMask` mirrors `'quickMask'`). */
|
|
315
|
+
selectionDisplay?: 'ants' | 'quickMask' | 'none';
|
|
314
316
|
/**
|
|
315
317
|
* The layer stack, bottom to top. Opening an image gives one pixel layer, "Background", whose
|
|
316
318
|
* pixels are the source image. Layers are immutable: compare them by identity.
|
|
@@ -311,6 +311,8 @@ export interface ImageEditorState {
|
|
|
311
311
|
selection?: SelectionMask | null;
|
|
312
312
|
/** Quick Mask view: tint the unselected area instead of drawing marching ants (view state). */
|
|
313
313
|
quickMask?: boolean;
|
|
314
|
+
/** How the canvas shows the selection (view state; `quickMask` mirrors `'quickMask'`). */
|
|
315
|
+
selectionDisplay?: 'ants' | 'quickMask' | 'none';
|
|
314
316
|
/**
|
|
315
317
|
* The layer stack, bottom to top. Opening an image gives one pixel layer, "Background", whose
|
|
316
318
|
* pixels are the source image. Layers are immutable: compare them by identity.
|
|
@@ -7,7 +7,7 @@ var _chunkZ64NRDEHcjs = require('../chunk-Z64NRDEH.cjs');
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _chunkC6TRAAG4cjs = require('../chunk-C6TRAAG4.cjs');
|
|
11
11
|
require('../chunk-A2IS7EHE.cjs');
|
|
12
12
|
|
|
13
13
|
|
|
@@ -1653,11 +1653,11 @@ function header(state, options) {
|
|
|
1653
1653
|
return out;
|
|
1654
1654
|
}
|
|
1655
1655
|
function serializePaintDocument(state, options = {}) {
|
|
1656
|
-
const { layers, assets } =
|
|
1656
|
+
const { layers, assets } = _chunkC6TRAAG4cjs.serializeLayers.call(void 0, state.layers);
|
|
1657
1657
|
return { ...header(state, options), layers, assets };
|
|
1658
1658
|
}
|
|
1659
1659
|
async function serializePaintDocumentExternal(state, store, options = {}) {
|
|
1660
|
-
const { layers, assets } = await
|
|
1660
|
+
const { layers, assets } = await _chunkC6TRAAG4cjs.serializeLayersExternal.call(void 0, state.layers, store);
|
|
1661
1661
|
return { ...header(state, options), layers, assets };
|
|
1662
1662
|
}
|
|
1663
1663
|
function paintLayersOnly(layers, problems) {
|
|
@@ -1694,7 +1694,7 @@ function deserializePaintDocument(raw) {
|
|
|
1694
1694
|
const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
|
|
1695
1695
|
const paper = _chunkYQ5C5BVKcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
|
|
1696
1696
|
const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
|
|
1697
|
-
const layers = paintLayersOnly(
|
|
1697
|
+
const layers = paintLayersOnly(_chunkC6TRAAG4cjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
|
|
1698
1698
|
const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
|
|
1699
1699
|
const activeLayerId = wanted && _chunkHGTDMKNEcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkHGTDMKNEcjs.flattenLayers.call(void 0, layers), 'access', _70 => _70.filter, 'call', _71 => _71((l) => l.type === "pixel"), 'access', _72 => _72.pop, 'call', _73 => _73(), 'optionalAccess', _74 => _74.id]), () => ( null));
|
|
1700
1700
|
const wetEvents = Array.isArray(r.wetEvents) ? r.wetEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.clock) && typeof e.kind === "string") : [];
|
|
@@ -1710,7 +1710,7 @@ async function deserializePaintDocumentAsync(raw, store) {
|
|
|
1710
1710
|
if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
|
|
1711
1711
|
const r = raw;
|
|
1712
1712
|
const problems = [];
|
|
1713
|
-
const assets = await
|
|
1713
|
+
const assets = await _chunkC6TRAAG4cjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
|
|
1714
1714
|
const loaded = deserializePaintDocument({ ...r, assets });
|
|
1715
1715
|
return { ...loaded, problems: [...problems, ...loaded.problems] };
|
|
1716
1716
|
}
|
|
@@ -5409,7 +5409,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
|
|
|
5409
5409
|
return next.type === "group" ? { ...next, children: toStandard(next.children) } : next;
|
|
5410
5410
|
});
|
|
5411
5411
|
const layers = toStandard(dried);
|
|
5412
|
-
const result =
|
|
5412
|
+
const result = _chunkC6TRAAG4cjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
|
|
5413
5413
|
for (const [mode, names] of changed) {
|
|
5414
5414
|
const label = _nullishCoalesce(_optionalChain([_chunkCWM3CUUXcjs.BLEND_MODES, 'access', _271 => _271.find, 'call', _272 => _272((m) => m.id === mode), 'optionalAccess', _273 => _273.label]), () => ( mode));
|
|
5415
5415
|
const std = _nullishCoalesce(_optionalChain([_chunkCWM3CUUXcjs.BLEND_MODES, 'access', _274 => _274.find, 'call', _275 => _275((m) => m.id === _chunkCWM3CUUXcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _276 => _276.label]), () => ( _chunkCWM3CUUXcjs.standardBlendMode.call(void 0, mode)));
|