@pixerate/editor 0.101.0 → 0.103.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/THIRD_PARTY_NOTICES.md +2 -0
- package/dist/agent/index.cjs +7 -7
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.js +7 -7
- package/dist/canvas/index.cjs +3 -3
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.js +4 -4
- package/dist/{chunk-WIR377F6.js → chunk-67FRIOPZ.js} +15 -12
- package/dist/chunk-67FRIOPZ.js.map +1 -0
- package/dist/chunk-6BU5WU4R.cjs +1 -0
- package/dist/chunk-6BU5WU4R.cjs.map +1 -0
- package/dist/{chunk-IB53LVGV.js → chunk-DS7KDKPX.js} +1 -1
- package/dist/chunk-NQLQ2JOI.js +7176 -0
- package/dist/chunk-NQLQ2JOI.js.map +1 -0
- package/dist/{chunk-ZZOTHJ4K.cjs → chunk-PV42JITT.cjs} +1 -1
- package/dist/{chunk-ZZOTHJ4K.cjs.map → chunk-PV42JITT.cjs.map} +1 -1
- package/dist/chunk-VSMM7B3P.cjs +7176 -0
- package/dist/chunk-VSMM7B3P.cjs.map +1 -0
- package/dist/{chunk-WT6ZAWJP.cjs → chunk-WSTEXEKD.cjs} +27 -24
- package/dist/chunk-WSTEXEKD.cjs.map +1 -0
- package/dist/chunk-XYBJKUAU.js +1 -0
- package/dist/chunk-XYBJKUAU.js.map +1 -0
- package/dist/compositor-B1ZrKR89.d.ts +835 -0
- package/dist/compositor-CTMU-B1t.d.cts +835 -0
- package/dist/export-BLpMyCYg.d.ts +3139 -0
- package/dist/export-X9rY79p0.d.cts +3139 -0
- package/dist/homography-CZ-tFjay.d.cts +50 -0
- package/dist/homography-Ctfjoc1b.d.ts +50 -0
- package/dist/image-editor/index.cjs +3889 -8657
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +224 -2723
- package/dist/image-editor/index.d.ts +224 -2723
- package/dist/image-editor/index.js +3326 -8094
- package/dist/image-editor/index.js.map +1 -1
- package/dist/mixer-DG_9Yu2W.d.ts +282 -0
- package/dist/mixer-DGcH6HLu.d.cts +282 -0
- package/dist/paint/index.cjs +4 -3
- package/dist/paint/index.cjs.map +1 -1
- package/dist/paint/index.d.cts +3 -281
- package/dist/paint/index.d.ts +3 -281
- package/dist/paint/index.js +2 -1
- package/dist/paint-editor/index.cjs +3330 -0
- package/dist/paint-editor/index.cjs.map +1 -0
- package/dist/paint-editor/index.d.cts +1233 -0
- package/dist/paint-editor/index.d.ts +1233 -0
- package/dist/paint-editor/index.js +3330 -0
- package/dist/paint-editor/index.js.map +1 -0
- package/dist/raster/index.cjs +2 -2
- package/dist/raster/index.d.cts +6 -827
- package/dist/raster/index.d.ts +6 -827
- package/dist/raster/index.js +1 -1
- package/dist/{surface-DIA-XatS.d.cts → surface-AfHCH7BR.d.cts} +1 -1
- package/dist/{surface-DIA-XatS.d.ts → surface-AfHCH7BR.d.ts} +1 -1
- package/dist/tools/index.cjs +3 -3
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.js +3 -3
- package/dist/vector/index.d.cts +2 -1
- package/dist/vector/index.d.ts +2 -1
- package/dist/{warp-B8rAguzs.d.ts → warp-CWHZzE3x.d.ts} +2 -49
- package/dist/{warp-nYs2DPrx.d.cts → warp-D5jz_tN7.d.cts} +2 -49
- package/package.json +6 -1
- package/skills/README.md +1 -0
- package/skills/pixerate-image-editor/SKILL.md +69 -11
- package/skills/pixerate-paint-editor/SKILL.md +162 -0
- package/dist/chunk-WIR377F6.js.map +0 -1
- package/dist/chunk-WT6ZAWJP.cjs.map +0 -1
- /package/dist/{chunk-IB53LVGV.js.map → chunk-DS7KDKPX.js.map} +0 -0
package/dist/raster/index.js
CHANGED
|
@@ -190,4 +190,4 @@ declare function collectTiles(surface: TiledSurface, into: Set<Tile>): void;
|
|
|
190
190
|
/** True when two surfaces hold the same pixels (cheap when they share tiles). */
|
|
191
191
|
declare function surfacesEqual(a: TiledSurface, b: TiledSurface): boolean;
|
|
192
192
|
|
|
193
|
-
export { readRegion as A, type BlendMode as B, setLum as C, solidSurface as D, surfaceBytes as E, surfaceFromPixels as F, surfacesEqual as G, tileCoord as H, tileKey as I, tileRect as J, tilesInRect as K, translateSurface as L, type MaskSurface as M, uniformTile as N, writeRegion as O, type PixelSurface as P, type RasterRect as R, SurfaceDraft as S,
|
|
193
|
+
export { readRegion as A, type BlendMode as B, setLum as C, solidSurface as D, surfaceBytes as E, surfaceFromPixels as F, surfacesEqual as G, tileCoord as H, tileKey as I, tileRect as J, tilesInRect as K, translateSurface as L, type MaskSurface as M, uniformTile as N, writeRegion as O, type PixelSurface as P, type RasterRect as R, SurfaceDraft as S, type TileKey as T, TiledSurface as a, type Tile as b, BLEND_MODES as c, type BlendModeInfo as d, type Rgb as e, type Rgba as f, TILE as g, TILE_SHIFT as h, blendChannel as i, blendImageData as j, blendLum as k, blendPixel as l, blendRgb as m, canvasCompositeOperation as n, collectTiles as o, contentBounds as p, emptySurface as q, fillRect as r, finishTile as s, isBlendMode as t, isSeparableBlendMode as u, mixPigment8 as v, mixPigmentRgb as w, normalizeBlendMode as x, packRgba as y, readPixel as z };
|
|
@@ -190,4 +190,4 @@ declare function collectTiles(surface: TiledSurface, into: Set<Tile>): void;
|
|
|
190
190
|
/** True when two surfaces hold the same pixels (cheap when they share tiles). */
|
|
191
191
|
declare function surfacesEqual(a: TiledSurface, b: TiledSurface): boolean;
|
|
192
192
|
|
|
193
|
-
export { readRegion as A, type BlendMode as B, setLum as C, solidSurface as D, surfaceBytes as E, surfaceFromPixels as F, surfacesEqual as G, tileCoord as H, tileKey as I, tileRect as J, tilesInRect as K, translateSurface as L, type MaskSurface as M, uniformTile as N, writeRegion as O, type PixelSurface as P, type RasterRect as R, SurfaceDraft as S,
|
|
193
|
+
export { readRegion as A, type BlendMode as B, setLum as C, solidSurface as D, surfaceBytes as E, surfaceFromPixels as F, surfacesEqual as G, tileCoord as H, tileKey as I, tileRect as J, tilesInRect as K, translateSurface as L, type MaskSurface as M, uniformTile as N, writeRegion as O, type PixelSurface as P, type RasterRect as R, SurfaceDraft as S, type TileKey as T, TiledSurface as a, type Tile as b, BLEND_MODES as c, type BlendModeInfo as d, type Rgb as e, type Rgba as f, TILE as g, TILE_SHIFT as h, blendChannel as i, blendImageData as j, blendLum as k, blendPixel as l, blendRgb as m, canvasCompositeOperation as n, collectTiles as o, contentBounds as p, emptySurface as q, fillRect as r, finishTile as s, isBlendMode as t, isSeparableBlendMode as u, mixPigment8 as v, mixPigmentRgb as w, normalizeBlendMode as x, packRgba as y, readPixel as z };
|
package/dist/tools/index.cjs
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
var _chunkQIWFEEWGcjs = require('../chunk-QIWFEEWG.cjs');
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
var _chunkRIWPYSKUcjs = require('../chunk-RIWPYSKU.cjs');
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
|
|
@@ -39,19 +40,18 @@ var _chunkQIWFEEWGcjs = require('../chunk-QIWFEEWG.cjs');
|
|
|
39
40
|
|
|
40
41
|
|
|
41
42
|
|
|
42
|
-
var _chunkEI2MOVQ3cjs = require('../chunk-EI2MOVQ3.cjs');
|
|
43
43
|
|
|
44
44
|
|
|
45
|
+
var _chunkEI2MOVQ3cjs = require('../chunk-EI2MOVQ3.cjs');
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
|
|
49
50
|
|
|
50
51
|
|
|
51
|
-
var _chunkVJUVNERTcjs = require('../chunk-VJUVNERT.cjs');
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
var
|
|
54
|
+
var _chunkVJUVNERTcjs = require('../chunk-VJUVNERT.cjs');
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
|
package/dist/tools/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/editor/editor/packages/core/dist/tools/index.cjs"],"names":[],"mappings":"AAAA,0GAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B;AACE;
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/editor/editor/packages/core/dist/tools/index.cjs"],"names":[],"mappings":"AAAA,0GAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B;AACE;AACF,yDAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wtGAAC","file":"/home/runner/work/editor/editor/packages/core/dist/tools/index.cjs"}
|
package/dist/tools/index.js
CHANGED
|
@@ -12,6 +12,9 @@ import {
|
|
|
12
12
|
createToolRegistry,
|
|
13
13
|
toToolResult
|
|
14
14
|
} from "../chunk-PTMIGXZ2.js";
|
|
15
|
+
import {
|
|
16
|
+
validateJsonSchema
|
|
17
|
+
} from "../chunk-4FX5ACVG.js";
|
|
15
18
|
import {
|
|
16
19
|
CAPTURE_EXCLUDE_SELECTOR,
|
|
17
20
|
CAPTURE_OVERLAY_SELECTORS,
|
|
@@ -49,9 +52,6 @@ import {
|
|
|
49
52
|
toCapturedImageData,
|
|
50
53
|
unionCaptureRects
|
|
51
54
|
} from "../chunk-REOJJIY3.js";
|
|
52
|
-
import {
|
|
53
|
-
validateJsonSchema
|
|
54
|
-
} from "../chunk-4FX5ACVG.js";
|
|
55
55
|
export {
|
|
56
56
|
CAPTURE_EXCLUDE_SELECTOR,
|
|
57
57
|
CAPTURE_OVERLAY_SELECTORS,
|
package/dist/vector/index.d.cts
CHANGED
|
@@ -7,9 +7,10 @@ import { H as HistoryManager } from '../HistoryManager-DeQQMBCj.cjs';
|
|
|
7
7
|
import { C as CommandSpec } from '../registry-CaR7LC6W.cjs';
|
|
8
8
|
import { S as StrokeJoin, a as StrokeCap, P as PlanarMap, b as PathfinderOperation, c as PathfinderShape } from '../pathfinder-BZL8aSu0.cjs';
|
|
9
9
|
import { b as AnimationEasing } from '../easing-lM0Xo9Ni.cjs';
|
|
10
|
-
export {
|
|
10
|
+
export { a as applyVectorHomography, o as orderVectorQuad, s as solve8, h as vectorHomography, b as vectorHomographyKeepsQuad } from '../homography-CZ-tFjay.cjs';
|
|
11
11
|
import { A as AffineMatrix, V as Vec2 } from '../types-CwMPoRMU.cjs';
|
|
12
12
|
export { H as VectorHomography } from '../types-CwMPoRMU.cjs';
|
|
13
|
+
export { a as VECTOR_WARP_STYLES, b as VECTOR_WARP_STYLE_LABELS, W as VectorWarpPreset, d as dragVectorMeshPoint, e as evalVectorMesh, f as fitVectorMesh, i as isValidVectorMesh, m as mapVectorMeshPoints, p as pullVectorMesh, r as removeVectorMeshSplitU, c as removeVectorMeshSplitV, g as resizeVectorMesh, s as splitVectorMeshU, h as splitVectorMeshV, j as vectorIdentityMesh, w as vectorMeshColumns, k as vectorMeshControlBounds, l as vectorMeshEditPoints, n as vectorMeshGridCurves, o as vectorMeshParamAt, q as vectorMeshRows, t as vectorWarpPresetGrid, u as vectorWarpPresetMesh } from '../warp-D5jz_tN7.cjs';
|
|
13
14
|
import '../types-DsiXGmjo.cjs';
|
|
14
15
|
import '../schema-Di0CS6Pe.cjs';
|
|
15
16
|
|
package/dist/vector/index.d.ts
CHANGED
|
@@ -7,9 +7,10 @@ import { H as HistoryManager } from '../HistoryManager-DWSLd6Tf.js';
|
|
|
7
7
|
import { C as CommandSpec } from '../registry-rVtFJjRM.js';
|
|
8
8
|
import { S as StrokeJoin, a as StrokeCap, P as PlanarMap, b as PathfinderOperation, c as PathfinderShape } from '../pathfinder-CNtsbCRK.js';
|
|
9
9
|
import { b as AnimationEasing } from '../easing-lM0Xo9Ni.js';
|
|
10
|
-
export {
|
|
10
|
+
export { a as applyVectorHomography, o as orderVectorQuad, s as solve8, h as vectorHomography, b as vectorHomographyKeepsQuad } from '../homography-Ctfjoc1b.js';
|
|
11
11
|
import { A as AffineMatrix, V as Vec2 } from '../types-CwMPoRMU.js';
|
|
12
12
|
export { H as VectorHomography } from '../types-CwMPoRMU.js';
|
|
13
|
+
export { a as VECTOR_WARP_STYLES, b as VECTOR_WARP_STYLE_LABELS, W as VectorWarpPreset, d as dragVectorMeshPoint, e as evalVectorMesh, f as fitVectorMesh, i as isValidVectorMesh, m as mapVectorMeshPoints, p as pullVectorMesh, r as removeVectorMeshSplitU, c as removeVectorMeshSplitV, g as resizeVectorMesh, s as splitVectorMeshU, h as splitVectorMeshV, j as vectorIdentityMesh, w as vectorMeshColumns, k as vectorMeshControlBounds, l as vectorMeshEditPoints, n as vectorMeshGridCurves, o as vectorMeshParamAt, q as vectorMeshRows, t as vectorWarpPresetGrid, u as vectorWarpPresetMesh } from '../warp-CWHZzE3x.js';
|
|
13
14
|
import '../types-DsiXGmjo.js';
|
|
14
15
|
import '../schema-Di0CS6Pe.js';
|
|
15
16
|
|
|
@@ -1,51 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Perspective (projective) maps between quadrilaterals: Free Distort and Perspective in both the
|
|
5
|
-
* vector and the image editor. Pure maths; degenerate or non-finite input gives `null` instead of
|
|
6
|
-
* NaNs.
|
|
7
|
-
*
|
|
8
|
-
* Ported from ArtCraft (MIT OR Apache-2.0, © ArtCraft Team and contributors; see
|
|
9
|
-
* THIRD_PARTY_NOTICES.md): pdfcraft `crates/geom/src/perspective.rs` (`Homography::from_points`,
|
|
10
|
-
* `Homography::apply`, `solve8`, `order_quad`) and photocraft `crates/algo/src/transform.rs`
|
|
11
|
-
* (`Homography::square_to_quad`, `rect_to_quad`, `inverse`, `mul`, `local_scale`, `front_side`,
|
|
12
|
-
* `warp_output_bounds`, `convex_quad`).
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Gaussian elimination with partial pivoting on an 8×8 system (the 9th column of each row is the
|
|
17
|
-
* right-hand side). Null when the system is singular.
|
|
18
|
-
*/
|
|
19
|
-
declare function solve8(rows: readonly (readonly number[])[]): number[] | null;
|
|
20
|
-
/** The image of `p`, or null where the map sends it to infinity. */
|
|
21
|
-
declare function applyHomography(h: Homography, p: Vec2): Vec2 | null;
|
|
22
|
-
/**
|
|
23
|
-
* The projective map that takes each of `from` to the point at the same index of `to`. Null when
|
|
24
|
-
* three of either set are collinear or a coordinate is not finite.
|
|
25
|
-
*/
|
|
26
|
-
declare function homographyFromPoints(from: readonly Vec2[], to: readonly Vec2[]): Homography | null;
|
|
27
|
-
/**
|
|
28
|
-
* Whether `h` maps the whole convex quad `quad` without sending any of it through infinity (the
|
|
29
|
-
* denominator keeps one sign over it): what a usable distortion needs.
|
|
30
|
-
*/
|
|
31
|
-
declare function homographyKeepsQuad(h: Homography, quad: readonly Vec2[]): boolean;
|
|
32
|
-
/**
|
|
33
|
-
* The four corners in reading order for a y-down space: top-left, top-right, bottom-right,
|
|
34
|
-
* bottom-left, whatever order they come in. Null unless they form a convex quadrilateral with a
|
|
35
|
-
* non-negligible area.
|
|
36
|
-
*/
|
|
37
|
-
declare function orderQuad(points: readonly Vec2[]): Vec2[] | null;
|
|
38
|
-
/** The inverse map, or null for a singular one. */
|
|
39
|
-
declare function invertHomography(m: Homography): Homography | null;
|
|
40
|
-
/** An affine matrix (SVG order) as a homography. */
|
|
41
|
-
declare function homographyFromAffine(m: AffineMatrix): Homography;
|
|
42
|
-
/**
|
|
43
|
-
* The map taking box `r`'s corners onto `quad` (TL, TR, BR, BL), exact for parallelograms (then
|
|
44
|
-
* affine). Null for an empty box, a non-finite or degenerate quad, or a singular result.
|
|
45
|
-
*/
|
|
46
|
-
declare function rectToQuad(r: Box, quad: readonly Vec2[]): Homography | null;
|
|
47
|
-
/** Box `r`'s corners as a quad (TL, TR, BR, BL). */
|
|
48
|
-
declare function boxQuad(r: Box): Quad;
|
|
1
|
+
import { W as WarpStyle, a as WarpMesh, V as Vec2, B as Box } from './types-CwMPoRMU.js';
|
|
49
2
|
|
|
50
3
|
/**
|
|
51
4
|
* Warp geometry shared by the vector editor's envelopes and the image editor's Free Transform
|
|
@@ -162,4 +115,4 @@ declare function warpMeshEditPoints(m: WarpMesh): {
|
|
|
162
115
|
/** The mesh's grid lines (patch borders) as cubics `[p0, p1, p2, p3]`. */
|
|
163
116
|
declare function warpMeshGridCurves(m: WarpMesh): Vec2[][];
|
|
164
117
|
|
|
165
|
-
export {
|
|
118
|
+
export { type WarpPreset as W, WARP_STYLES as a, WARP_STYLE_LABELS as b, removeWarpMeshSplitV as c, dragWarpMeshPoint as d, evalWarpMesh as e, fitWarpMesh as f, resizeWarpMesh as g, splitWarpMeshV as h, isValidWarpMesh as i, identityWarpMesh as j, warpMeshControlBounds as k, warpMeshEditPoints as l, mapWarpMeshPoints as m, warpMeshGridCurves as n, warpMeshParamAt as o, pullWarpMesh as p, warpMeshRows as q, removeWarpMeshSplitU as r, splitWarpMeshU as s, warpPresetGrid as t, warpPresetMesh as u, warpMeshColumns as w };
|
|
@@ -1,51 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Perspective (projective) maps between quadrilaterals: Free Distort and Perspective in both the
|
|
5
|
-
* vector and the image editor. Pure maths; degenerate or non-finite input gives `null` instead of
|
|
6
|
-
* NaNs.
|
|
7
|
-
*
|
|
8
|
-
* Ported from ArtCraft (MIT OR Apache-2.0, © ArtCraft Team and contributors; see
|
|
9
|
-
* THIRD_PARTY_NOTICES.md): pdfcraft `crates/geom/src/perspective.rs` (`Homography::from_points`,
|
|
10
|
-
* `Homography::apply`, `solve8`, `order_quad`) and photocraft `crates/algo/src/transform.rs`
|
|
11
|
-
* (`Homography::square_to_quad`, `rect_to_quad`, `inverse`, `mul`, `local_scale`, `front_side`,
|
|
12
|
-
* `warp_output_bounds`, `convex_quad`).
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Gaussian elimination with partial pivoting on an 8×8 system (the 9th column of each row is the
|
|
17
|
-
* right-hand side). Null when the system is singular.
|
|
18
|
-
*/
|
|
19
|
-
declare function solve8(rows: readonly (readonly number[])[]): number[] | null;
|
|
20
|
-
/** The image of `p`, or null where the map sends it to infinity. */
|
|
21
|
-
declare function applyHomography(h: Homography, p: Vec2): Vec2 | null;
|
|
22
|
-
/**
|
|
23
|
-
* The projective map that takes each of `from` to the point at the same index of `to`. Null when
|
|
24
|
-
* three of either set are collinear or a coordinate is not finite.
|
|
25
|
-
*/
|
|
26
|
-
declare function homographyFromPoints(from: readonly Vec2[], to: readonly Vec2[]): Homography | null;
|
|
27
|
-
/**
|
|
28
|
-
* Whether `h` maps the whole convex quad `quad` without sending any of it through infinity (the
|
|
29
|
-
* denominator keeps one sign over it): what a usable distortion needs.
|
|
30
|
-
*/
|
|
31
|
-
declare function homographyKeepsQuad(h: Homography, quad: readonly Vec2[]): boolean;
|
|
32
|
-
/**
|
|
33
|
-
* The four corners in reading order for a y-down space: top-left, top-right, bottom-right,
|
|
34
|
-
* bottom-left, whatever order they come in. Null unless they form a convex quadrilateral with a
|
|
35
|
-
* non-negligible area.
|
|
36
|
-
*/
|
|
37
|
-
declare function orderQuad(points: readonly Vec2[]): Vec2[] | null;
|
|
38
|
-
/** The inverse map, or null for a singular one. */
|
|
39
|
-
declare function invertHomography(m: Homography): Homography | null;
|
|
40
|
-
/** An affine matrix (SVG order) as a homography. */
|
|
41
|
-
declare function homographyFromAffine(m: AffineMatrix): Homography;
|
|
42
|
-
/**
|
|
43
|
-
* The map taking box `r`'s corners onto `quad` (TL, TR, BR, BL), exact for parallelograms (then
|
|
44
|
-
* affine). Null for an empty box, a non-finite or degenerate quad, or a singular result.
|
|
45
|
-
*/
|
|
46
|
-
declare function rectToQuad(r: Box, quad: readonly Vec2[]): Homography | null;
|
|
47
|
-
/** Box `r`'s corners as a quad (TL, TR, BR, BL). */
|
|
48
|
-
declare function boxQuad(r: Box): Quad;
|
|
1
|
+
import { W as WarpStyle, a as WarpMesh, V as Vec2, B as Box } from './types-CwMPoRMU.cjs';
|
|
49
2
|
|
|
50
3
|
/**
|
|
51
4
|
* Warp geometry shared by the vector editor's envelopes and the image editor's Free Transform
|
|
@@ -162,4 +115,4 @@ declare function warpMeshEditPoints(m: WarpMesh): {
|
|
|
162
115
|
/** The mesh's grid lines (patch borders) as cubics `[p0, p1, p2, p3]`. */
|
|
163
116
|
declare function warpMeshGridCurves(m: WarpMesh): Vec2[][];
|
|
164
117
|
|
|
165
|
-
export {
|
|
118
|
+
export { type WarpPreset as W, WARP_STYLES as a, WARP_STYLE_LABELS as b, removeWarpMeshSplitV as c, dragWarpMeshPoint as d, evalWarpMesh as e, fitWarpMesh as f, resizeWarpMesh as g, splitWarpMeshV as h, isValidWarpMesh as i, identityWarpMesh as j, warpMeshControlBounds as k, warpMeshEditPoints as l, mapWarpMeshPoints as m, warpMeshGridCurves as n, warpMeshParamAt as o, pullWarpMesh as p, warpMeshRows as q, removeWarpMeshSplitU as r, splitWarpMeshU as s, warpPresetGrid as t, warpPresetMesh as u, warpMeshColumns as w };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixerate/editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.103.0",
|
|
4
4
|
"description": "UI-agnostic rich text and media editing core library",
|
|
5
5
|
"author": "Pixerate",
|
|
6
6
|
"license": "MIT",
|
|
@@ -89,6 +89,11 @@
|
|
|
89
89
|
"import": "./dist/image-editor/index.js",
|
|
90
90
|
"require": "./dist/image-editor/index.cjs"
|
|
91
91
|
},
|
|
92
|
+
"./paint-editor": {
|
|
93
|
+
"types": "./dist/paint-editor/index.d.ts",
|
|
94
|
+
"import": "./dist/paint-editor/index.js",
|
|
95
|
+
"require": "./dist/paint-editor/index.cjs"
|
|
96
|
+
},
|
|
92
97
|
"./commands": {
|
|
93
98
|
"types": "./dist/commands/index.d.ts",
|
|
94
99
|
"import": "./dist/commands/index.js",
|
package/skills/README.md
CHANGED
|
@@ -15,6 +15,7 @@ that uses the tools can load the matching skill.
|
|
|
15
15
|
| [`pixerate-chart`](pixerate-chart/SKILL.md) | Chart specs, data, series, presets, trendlines, Office and Mermaid charts. |
|
|
16
16
|
| [`pixerate-diagram`](pixerate-diagram/SKILL.md) | Mermaid diagrams: nodes, edges, groups, layout. |
|
|
17
17
|
| [`pixerate-image-editor`](pixerate-image-editor/SKILL.md) | Adjustments, adjustment layers, selections and masks. |
|
|
18
|
+
| [`pixerate-paint-editor`](pixerate-paint-editor/SKILL.md) | Natural-media painting: paper and grain, dry-media brushes, the brush library, strokes as data, pigment mixing. |
|
|
18
19
|
| [`pixerate-animation-editor`](pixerate-animation-editor/SKILL.md) | Vector animation: shots, commands, timing, Flair and Lottie. |
|
|
19
20
|
| [`pixerate-video-editor`](pixerate-video-editor/SKILL.md) | Non-linear video editing: tracks, clips, transitions, export. |
|
|
20
21
|
| [`pixerate-generation`](pixerate-generation/SKILL.md) | Planning, estimating and running paid media generation. |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pixerate-image-editor
|
|
3
|
-
description: How to colour-correct, composite and retouch a photo in the Pixerate image editor through its agent tools - layers (pixel, adjustment, group and
|
|
3
|
+
description: description: How to colour-correct, composite and retouch a photo in the Pixerate image editor through its agent tools - layers (pixel, adjustment, group, annotation and smart object layers with masks, clipping, blend modes, opacity and fill; merge, flatten, filters), smart objects (non-destructive transforms, smart filters, linked contents, edit contents), live layer effects (shadows, glows, bevels, overlays, strokes), base adjustments, adjustment layers (curves, levels, hue/saturation and more), selections and masks, Free Transform (scale, rotate, skew, distort, warp), crop, rotate, flip, Mixer Brush, undo, PSD, histogram and previews. Use when asked to edit, grade, correct, crop, straighten or mask an image, add a shadow, glow or outline, transform or warp a layer, make a smart object, or open or save a PSD, or when get_adjustments, set_adjustments, list_layers, add_layer_effect, transform_layer, convert_to_smart_object, paint_stroke, select_by_color, import_psd or render_preview are available.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Image editor
|
|
@@ -12,9 +12,10 @@ its mask, opacity and blend mode) and every annotation is its own layer on top.
|
|
|
12
12
|
shows the whole stack. Edits never touch the source pixels. The base controls edit the develop
|
|
13
13
|
filter of the active pixel layer (the Background unless another pixel layer is active); base
|
|
14
14
|
`blur` blurs that layer (or, in documents saved before layers with blur and adjustment layers,
|
|
15
|
-
the output after the layers), and base `opacity` is the output's alpha. Pixel, annotation
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
the output after the layers), and base `opacity` is the output's alpha. Pixel, annotation, group
|
|
16
|
+
and smart object layers can carry live effects (shadows, glows, bevels, overlays, strokes). A smart
|
|
17
|
+
object places contents (pixels or a nested layer document) through a transform and smart filters,
|
|
18
|
+
re-rendered from the contents on every change. Also an optional selection and crop/rotate/flip. See `pixerate-agent-tools` for errors, namespacing and command
|
|
18
19
|
batching.
|
|
19
20
|
|
|
20
21
|
- **Control ids** for base adjustments: `brightness`, `contrast`, `exposure`, `temperature`,
|
|
@@ -88,6 +89,33 @@ batching.
|
|
|
88
89
|
rotation and move into one `transform_layer` call (or one matrix) instead of several.
|
|
89
90
|
5. **Look**: `render_preview`, or `capture_view` at the edges; each call is one undo step.
|
|
90
91
|
|
|
92
|
+
### Smart objects
|
|
93
|
+
|
|
94
|
+
1. **Convert before repeated or uncertain changes**: `convert_to_smart_object` (one pixel layer, or
|
|
95
|
+
several siblings that nest as a layer document). A converted pixel layer looks exactly the same
|
|
96
|
+
and keeps its id; its filters become smart filters. From then on every transform and filter is
|
|
97
|
+
re-rendered from the contents, so scaling down and back up, or rotating twelve times, loses
|
|
98
|
+
nothing.
|
|
99
|
+
2. **Read it**: `get_smart_object` gives the contents (size, kind, instances), the placement
|
|
100
|
+
(corners, warp, and scale / rotate in percent and degrees of the contents' own size) and the
|
|
101
|
+
smart filters with their ids.
|
|
102
|
+
3. **Transform**: `set_smart_object_transform` sets the transform absolutely (scale 100 = the
|
|
103
|
+
contents' own size, `x`, `y` = where its centre goes; or `corners`, `matrix`, and a `warp` in
|
|
104
|
+
contents pixels, `null` to remove). `transform_layer`, `warp_layer`, `flip_layer` and
|
|
105
|
+
`rotate_layer_90` also work on a smart object, relative to its current placement, and never
|
|
106
|
+
degrade it. `offset_layer` moves it by whole pixels.
|
|
107
|
+
4. **Filter non-destructively**: `add_smart_filter` (`develop` or `blur`, each with its own
|
|
108
|
+
`blend` and `opacity`; kinds can repeat), then `update_smart_filter`, `move_smart_filter`,
|
|
109
|
+
`remove_smart_filter` and `set_smart_filters_enabled`. `set_smart_filter_mask` limits where the
|
|
110
|
+
filters show; paint it with `paint_stroke` / `fill_pixels` `channel: "filter-mask"`.
|
|
111
|
+
5. **Contents**: `copy_smart_object` with `linked: true` shares the contents (edit once, both
|
|
112
|
+
change), `linked: false` makes them independent. `edit_smart_object_contents` opens the
|
|
113
|
+
contents as their own document: every tool then works inside them until
|
|
114
|
+
`close_smart_object_contents` (`save: false` discards). `replace_smart_object_contents` swaps
|
|
115
|
+
in a new image for every linked instance; `export_smart_object_contents` returns the file.
|
|
116
|
+
6. **Finish**: `rasterize_smart_object` only when the user wants plain pixels to paint on; the
|
|
117
|
+
placement and filters are then gone.
|
|
118
|
+
|
|
91
119
|
### Layer effects
|
|
92
120
|
|
|
93
121
|
1. **Effects are live and per layer**: drop and inner shadows, outer and inner glows,
|
|
@@ -224,6 +252,12 @@ batching.
|
|
|
224
252
|
which `bounds` in the result shows.
|
|
225
253
|
- **Unlink a mask** (`set_layer_mask_properties` `linked: false`) when the pixels should move
|
|
226
254
|
under a fixed mask (a picture inside a frame); link it again afterwards.
|
|
255
|
+
- **Smart objects for anything you may scale again.** Convert first, then transform as often as
|
|
256
|
+
needed; set exact sizes with `set_smart_object_transform` `scaleX` / `scaleY` (percent of the
|
|
257
|
+
contents) rather than chaining relative scales. Prefer smart filters over layer filters when
|
|
258
|
+
the user may want to mask, blend or reorder them later.
|
|
259
|
+
- **Linked or not**: duplicate a smart object `linked: true` for repeated elements that must stay
|
|
260
|
+
identical (a logo placed twice); use `linked: false` when the copies will be edited apart.
|
|
227
261
|
- **Merge Down only onto an opaque, 100 % lower layer** when the result must look the same:
|
|
228
262
|
the merged layer keeps the lower layer's opacity and blend, so a faded lower layer fades the
|
|
229
263
|
merged content too, and a blend mode on the upper layer stops seeing what was below the lower
|
|
@@ -238,7 +272,7 @@ batching.
|
|
|
238
272
|
| `get_adjustments` | Read the current state: `values` by control id, `process` version (1 or 2), and `layers` bottom to top with id, kind, params, opacity, blend, enabled and mask. Call first, and to find layer ids. |
|
|
239
273
|
| `list_controls` | Get every base control (id, label, section, min, max, step, default, `requiresProcess`), each layer kind's settable controls (plus `opacity`), the blend mode ids and the `layers.<layerId>.<controlId>` path format. Call once per session before writing. |
|
|
240
274
|
| `get_selection` | Read the active selection: `empty`, `bounds` (natural pixels), `area` in pixels, `percent` of the image and a description. Check it after every select or modify step and before masking: a wand that covered 90% of the image is the wrong selection. |
|
|
241
|
-
| `list_layers` | Read the layer stack bottom to top as a tree: id, type (`pixel`, `adjustment`, `group`, `annotation`), name, document `bounds` of pixel layers, visibility, opacity, `fillOpacity`, blend, `clipped`, locks, a `mask` summary, an `effects` summary (master switch, scale, effect ids and kinds), pixel-layer `filters` (the Background's `develop` filter is the base adjustments), adjustment `kind` and `params`, group `children`, and which layer is `active`. Call it to understand a document with more than the Background before changing it; adjustment layer ids work with every adjustment-layer tool. |
|
|
275
|
+
| `list_layers` | Read the layer stack bottom to top as a tree: id, type (`pixel`, `adjustment`, `group`, `annotation`, `smart`; smart objects add their `contents`, `smartFilters` and `filterMask`), name, document `bounds` of pixel layers, visibility, opacity, `fillOpacity`, blend, `clipped`, locks, a `mask` summary, an `effects` summary (master switch, scale, effect ids and kinds), pixel-layer `filters` (the Background's `develop` filter is the base adjustments), adjustment `kind` and `params`, group `children`, and which layer is `active`. Call it to understand a document with more than the Background before changing it; adjustment layer ids work with every adjustment-layer tool. |
|
|
242
276
|
| `list_layer_effects` | Read one layer's effects: `enabled` (master switch), `scale` (Scale Effects), `margin` (px they reach beyond the shape), `fromPsd`, and every effect with `id`, `kind`, `label` and all its settings. Also returns the `globalLight`, the `patterns` pattern effects can use and the effect `kinds`. Call before changing effects you did not add. |
|
|
243
277
|
| `get_image_info` | Read the geometry: source `image` size, `crop` box (source pixels, or null), `rotation` degrees, `flipH` / `flipV`, the `output` size after crop and rotation, the layer count and `canUndo` / `canRedo`. Call before cropping or selecting so coordinates are right. |
|
|
244
278
|
| `get_histogram` | Judge exposure numerically: per channel and luminance `mean`, `p1` and `p99` (0..255), and `clipping` percent at pure black and white per channel. Reads the last render, so call `render_preview` first. `bins` (16, 32, 64 or 256) adds the counts. Cheaper than another image for checking a tonal change. |
|
|
@@ -246,6 +280,8 @@ batching.
|
|
|
246
280
|
| `inspect_psd` | Read a PSD / PSB (`data` base64) without opening it: size, `depth`, `colorMode`, `resolution`, every layer bottom first with `psdKind`, the `type` it would become and `status` (`mapped`, `approximated`, `dropped`) with `notes`, and the import `warnings`. Call before `import_psd`. |
|
|
247
281
|
| `export_psd` | Save the document as an 8-bit RGB PSD (PSB above 30000 px) with layers, groups, adjustment layers and masks. Returns `data` (base64), `size` in bytes, `psb` and `warnings` (crop or rotation not applied, filters and depth masks baked, annotations rasterized or left out, Pigment blends written as Normal). Changes nothing. |
|
|
248
282
|
| `get_transform_frame` | Before a transform: what it would move (`content`, `moved`: pixels, mask, selection), its `frame` (document bounds of the content), `corners` (top-left, top-right, bottom-right, bottom-left) and `center`. `meshColumns` / `meshRows` also return an identity warp `mesh` over the frame to edit for `warp_layer`. Changes nothing. |
|
|
283
|
+
| `get_smart_object` | Read a smart object: `contents` (`id` shared by linked instances, `name`, `kind` raster or document, `width` / `height`, `decoded`, `fileType`, `linkedPath`, `instances`), `placement` (`corners`, `warp` in contents px, `interpolation`, and when `affine` the `scaleX` / `scaleY` in percent of the contents, `rotate`, `skewX`, `center`, `bounds`) and `smartFilters` (`enabled`, `filters` bottom to top with ids, settings, `blend`, `opacity`; kind `psd` is a Photoshop filter kept but not drawn; the filter `mask`). Call before changing a smart object. |
|
|
284
|
+
| `export_smart_object_contents` | Export Contents: the contents as a file (`name`, `mimeType`, `byteLength`, `base64`): the file they came from while unedited, else a PNG (raster) or PSD / PSB (nested document). Changes nothing. |
|
|
249
285
|
| `capture_view` | Inspect detail in natural image pixels (the space of `get_selection` and `select_region`, before crop and rotation): `region` `content` (whole image, default), `selection` or `rect`; small regions are enlarged up to 8× with hard pixel edges, so a 64 px rect shows real pixels. `includeOverlays: true` shades unselected pixels and outlines the crop: use it to check a mask's edge before `apply_selection_as_mask`. Returns the `rect` and `scale`. Use `render_preview` for the final framed result. |
|
|
250
286
|
|
|
251
287
|
### Write
|
|
@@ -267,7 +303,7 @@ batching.
|
|
|
267
303
|
| `flip_image` | Mirror the image `horizontal` (left-right) or `vertical`. Avoid flipping images with text, logos or recognisable places. |
|
|
268
304
|
| `undo_image` | Undo the last edit (one tool call is one step). Returns `canUndo` / `canRedo`. |
|
|
269
305
|
| `redo_image` | Redo the edit you just undid. |
|
|
270
|
-
| `set_active_layer` | Make a layer active (`layerId`) and choose the paint `target` (`pixels` or `mask`). Base sliders then edit that pixel layer's develop filter. Not an undo step. Returns the layer. |
|
|
306
|
+
| `set_active_layer` | Make a layer active (`layerId`) and choose the paint `target` (`pixels`, `mask`, or a smart object's `filter-mask`). Base sliders then edit that pixel layer's develop filter. Not an undo step. Returns the layer. |
|
|
271
307
|
| `add_pixel_layer` | Add a pixel layer above the active layer (or at `aboveId` / `belowId` / `parentId` / `index`): empty, `color` `#rrggbb[aa]` over the canvas, or `image` (PNG data URL or base64; other formats only in a browser) at `x`, `y`; with `name`, `opacity`, `blend`. Returns the layer with its id and bounds. |
|
|
272
308
|
| `duplicate_layer` | Copy a layer (groups with their children) directly above it, e.g. before a destructive change. Returns the copy. |
|
|
273
309
|
| `remove_layer` | Delete a layer or group (refused when locked). Prefer hiding with `set_layer_properties`. Returns the remaining top-level ids. |
|
|
@@ -279,8 +315,8 @@ batching.
|
|
|
279
315
|
| `merge_down` | Composite a layer onto the pixel layer below it (masks, fill and filters baked). Destructive; see Best practices. Returns the merged layer. |
|
|
280
316
|
| `merge_visible` | Composite all visible top-level layers into one layer; hidden ones stay. Destructive. |
|
|
281
317
|
| `flatten_image` | Composite everything visible into one Background; hidden layers are discarded. Destructive; do it only when asked. |
|
|
282
|
-
| `offset_layer` | Move a pixel layer and its linked mask to `x`, `y` or by `dx`, `dy` (integers, document px; an unlinked mask stays put). Refused when its position is locked. Returns the offset and bounds. |
|
|
283
|
-
| `transform_layer` | Free Transform a pixel layer (with its linked mask), the selected pixels (`content` `selection`), a copy of them on a new layer (`selection-copy`) or an unlinked mask (`channel` `mask`). Give the transform one way: `scaleX` / `scaleY` (percent), `rotate`, `skewX` / `skewY` (degrees), `dx` / `dy` (px) about `reference` (an anchor or `{x, y}`, default `center`); or `matrix` `[a, b, c, d, e, f]`; or `corners` (the frame's new corners: distort / perspective, kept convex). `interpolation` nearest, bilinear or bicubic (default). One undo step. Returns `layerId` (the new layer for a copy), `moved`, `frame`, `corners` and the new `bounds`. |
|
|
318
|
+
| `offset_layer` | Move a pixel layer or smart object and its linked mask to `x`, `y` (a smart object's top-left corner) or by `dx`, `dy` (integers, document px; an unlinked mask stays put). Refused when its position is locked. Returns the offset and bounds. |
|
|
319
|
+
| `transform_layer` | Free Transform a pixel layer or smart object (with its linked mask; a smart object re-renders from its contents and always moves whole), the selected pixels (`content` `selection`), a copy of them on a new layer (`selection-copy`) or an unlinked mask (`channel` `mask`). Give the transform one way: `scaleX` / `scaleY` (percent), `rotate`, `skewX` / `skewY` (degrees), `dx` / `dy` (px) about `reference` (an anchor or `{x, y}`, default `center`); or `matrix` `[a, b, c, d, e, f]`; or `corners` (the frame's new corners: distort / perspective, kept convex). `interpolation` nearest, bilinear or bicubic (default). One undo step. Returns `layerId` (the new layer for a copy), `moved`, `frame`, `corners` and the new `bounds`. |
|
|
284
320
|
| `warp_layer` | Warp the same targets as `transform_layer` through a preset (`style` arc … twist, `bend` −100..100 default 50, `horizontal` / `vertical` distortion, `orientation`) or a `mesh` (`columns`, `rows`, (3·columns + 1) × (3·rows + 1) `points` in document px; start from `get_transform_frame`'s identity mesh). One undo step. Returns the new `bounds`. |
|
|
285
321
|
| `transform_selection` | Transform only the selection outline (Transform Selection): the same numeric fields, `matrix` or `corners` as `transform_layer`, over the selection's bounds. Pixels do not change. Needs a selection. Returns the new selection `bounds`. |
|
|
286
322
|
| `flip_layer` | Mirror a pixel layer, its selected pixels or a copy (`content`) `horizontal` or `vertical` about the frame's centre, exactly. For the whole image use `flip_image`. Returns the new `bounds`. |
|
|
@@ -290,7 +326,20 @@ batching.
|
|
|
290
326
|
| `apply_layer_mask` | Bake a pixel layer's mask into its alpha and remove it. Destructive. |
|
|
291
327
|
| `remove_layer_mask` | Delete a mask without applying it; disable it instead to keep it. |
|
|
292
328
|
| `layer_via_copy` | Copy the selected pixels of a pixel layer (default the active one) to a new layer above it; `cut: true` removes them from the source. Needs a selection. Returns the new layer. |
|
|
293
|
-
| `rasterize_layer` | Turn an annotation layer into pixels (same id and properties; browser only) or bake a pixel layer's develop / blur filters into its pixels. Do it before painting over an annotation, or when the user wants the filters fixed. Destructive. |
|
|
329
|
+
| `rasterize_layer` | Turn an annotation layer into pixels (same id and properties; browser only), a smart object into a pixel layer (as `rasterize_smart_object`), or bake a pixel layer's develop / blur filters into its pixels. Do it before painting over an annotation, or when the user wants the filters fixed. Destructive. |
|
|
330
|
+
| `convert_to_smart_object` | Convert sibling `layerIds` (default the active layer) to one smart object at the top one's position, optional `name`. One pixel layer keeps its id, look and properties (filters become smart filters); several layers, groups or adjustments nest as a layer document. Returns the `layer` and the `smartObject` summary. |
|
|
331
|
+
| `rasterize_smart_object` | Turn a smart object into a pixel layer holding what it shows now (smart filters baked; same id, mask, effects, opacity, blend). Destructive: the contents and filters are gone. Returns the layer. |
|
|
332
|
+
| `set_smart_object_transform` | Set a smart object's transform absolutely: `corners`, `matrix` (contents → document), or `scaleX` / `scaleY` (percent of the contents), `rotate`, `skewX`, `skewY`, `x`, `y` (where the contents' centre goes; unset numbers keep their values); `warp` preset or mesh in contents px, `null` removes it; `interpolation`. Re-renders from the contents. Returns `placement`, `masksMoved` and `bounds`. |
|
|
333
|
+
| `replace_smart_object_contents` | Replace Contents with `image` (PNG data URL or base64; other formats in a browser) for the smart object and every linked instance; each keeps its scale and rotation about the centre. Returns `contentsId`, the new size and `layerIds` changed. |
|
|
334
|
+
| `copy_smart_object` | Duplicate a smart object above it: `linked: true` shares the contents (edits show in both), `linked: false` (default, New Smart Object via Copy) gives independent contents. Returns the copy and its `contentsId`. |
|
|
335
|
+
| `edit_smart_object_contents` | Open a smart object's contents as their own document (raster contents as one pixel layer, "Layer 0") with their own undo; all tools then act inside them. Returns the size, `layerIds`, `layers` and `editing` (the open path). Always close it. |
|
|
336
|
+
| `close_smart_object_contents` | Close the innermost open contents: `save` true (default) writes them back and re-renders every linked instance (one undo step), false discards. Returns `layerId`, `changed`, `layerIds` and what is still `editing`. |
|
|
337
|
+
| `add_smart_filter` | Add a `develop` (brightness … tint) or `blur` (`radius`) smart filter with its own `blend` and `opacity`, at `index` (default top); kinds may repeat. Returns the `filter` (with id) and the stack. |
|
|
338
|
+
| `update_smart_filter` | Change one smart filter's settings, `enabled`, `blend` or `opacity` (`filterId` from `get_smart_object`); kind `psd` filters take only the last three. Returns the filter and the stack. |
|
|
339
|
+
| `remove_smart_filter` | Remove one smart filter (the filter mask goes with the last one). Returns the stack. |
|
|
340
|
+
| `move_smart_filter` | Move a smart filter to `index` (0 = bottom, applied first). Returns the stack. |
|
|
341
|
+
| `set_smart_filters_enabled` | Switch the whole smart filter stack off or on (`enabled`); each filter keeps its own flag. Returns the stack. |
|
|
342
|
+
| `set_smart_filter_mask` | Set the smart filter mask `from` `reveal-all`, `hide-all`, `selection`, `none` (remove) or `keep` (properties only), with `density`, `feather`, `enabled`, `linked`. Paint it with `channel: "filter-mask"`. Returns the mask summary. |
|
|
294
343
|
| `add_layer_filter` | Add a live `develop` (brightness … tint) or `blur` (`radius`) filter to a pixel layer; one of each kind. Returns the filters with ids. |
|
|
295
344
|
| `update_layer_filter` | Change a filter's values (`filterId` from `list_layers`). Returns the filters. |
|
|
296
345
|
| `remove_layer_filter` | Remove a filter. Returns the remaining filters. |
|
|
@@ -327,8 +376,17 @@ batching.
|
|
|
327
376
|
- `merge_down`, `merge_visible` and `flatten_image` merge annotation layers only in a browser
|
|
328
377
|
(they need a canvas); elsewhere they fail and say so.
|
|
329
378
|
- `paint_stroke`, `fill_pixels` and `clear_pixels` need a visible pixel layer (or a layer with a
|
|
330
|
-
raster mask and `channel: "mask"`); adjustment, group and
|
|
331
|
-
painted through their masks
|
|
379
|
+
raster mask and `channel: "mask"`); adjustment, group, annotation and smart object layers can
|
|
380
|
+
only be painted through their masks (and a smart object through `channel: "filter-mask"`).
|
|
381
|
+
To paint a smart object's pixels, `edit_smart_object_contents` or rasterize it. A layer with
|
|
382
|
+
`locks.pixels` refuses paint.
|
|
383
|
+
- While contents are open (`edit_smart_object_contents`), `list_layers` and every tool see the
|
|
384
|
+
contents, not the document, and `export_psd` / saving write the document without the open
|
|
385
|
+
edits. Close with `close_smart_object_contents` before anything else.
|
|
386
|
+
- Smart filters run over the canvas, like layer filters: a blur clamps at the canvas edge, and a
|
|
387
|
+
smart object is drawn only up to 512 px beyond the canvas. `get_transform_frame` on a smart
|
|
388
|
+
object returns the contents' rectangle (contents px) as the `frame`, and a warp `mesh` in
|
|
389
|
+
contents px.
|
|
332
390
|
- `mix_colors` predicts a mix; it does not paint. To paint the mix, pass `blend: "pigment"` to
|
|
333
391
|
`paint_stroke` (in `brush`) or `fill_pixels`, or set it on a layer.
|
|
334
392
|
- `pigment` has no PSD equivalent: `export_psd` writes those layers as Normal (the merged image
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pixerate-paint-editor
|
|
3
|
+
description: How to make a picture in the Pixerate paint editor (natural media in the spirit of Painter and Rebelle) through its agent tools - canvas and paper (generated grain, depth, colour, families from cold pressed watercolour to canvas and gesso), layers, dry-media brushes (pencil, pastel, charcoal, airbrush, marker, ink, erasers, blender, smudge, Mixer Brush) with pressure, tilt, barrel rotation and velocity, the brush library, strokes as data that replay and vary, pigment colour mixing, previews and PNG, JPEG, WebP, PSD and JSON output. Use when asked to paint, sketch, draw, shade, block in, texture a layer with paper grain, mix paint colours, vary or repeat strokes, or when paint_stroke, set_paper, list_brushes, replay_strokes, fill_layer or mix_colors are available.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Paint editor
|
|
7
|
+
|
|
8
|
+
A canvas (pixels and dpi) over a **paper**, with a stack of layers (pixel layers and groups with
|
|
9
|
+
opacity, blend modes, clipping and locks) on top. The paper is generated from a pattern and a
|
|
10
|
+
seed: its grain is a height map (peaks and valleys) that grain-responsive brushes follow, and it
|
|
11
|
+
is never part of a layer. Coordinates are document pixels, (0, 0) top-left, y down. See
|
|
12
|
+
`pixerate-agent-tools` for errors, namespacing and batching.
|
|
13
|
+
|
|
14
|
+
- **Brushes** are library presets (`list_brushes`): a tip from the shared engine (size,
|
|
15
|
+
hardness, spacing, angle, roundness, opacity, flow, blend), a **grain** response, pen dynamics
|
|
16
|
+
(pressure, tilt, velocity, jitter), a **rotation** mode (`fixed`, `stroke`, `barrel`) and an
|
|
17
|
+
engine: `dab` (most media), `eraser`, or `mixer` (Mixer Brush, blender, smudge: they pick up and
|
|
18
|
+
move paint already on the layer).
|
|
19
|
+
- **Grain**: a brush's grain response times the paper's `depth` decides how much light pressure
|
|
20
|
+
skips the valleys. Pencil, pastel and charcoal are grainy; airbrush, marker and ink are not.
|
|
21
|
+
- **Strokes are data.** Every stroke is recorded (brush, colour, raw points, seed, symmetry
|
|
22
|
+
copies) and gets a `strokeId`. `replay_strokes` paints recorded strokes again, exactly or
|
|
23
|
+
varied. That is the main way an agent should make many similar marks.
|
|
24
|
+
- **Undo**: one tool call that changes the painting is one undo step (`undo_paint`). Brush,
|
|
25
|
+
colour, view, hand and the Mixer Brush load are editor state, not undo steps.
|
|
26
|
+
|
|
27
|
+
## Working method
|
|
28
|
+
|
|
29
|
+
1. **Read.** `get_canvas_info` (size, paper, active layer, active brush, colour), then
|
|
30
|
+
`list_layers`. `render_preview` to see the painting before changing it.
|
|
31
|
+
2. **Choose the ground.** Pick a paper that suits the medium (`list_papers`, `set_paper`, or
|
|
32
|
+
`new_canvas` with `paper`): cold pressed or rough for broken, sparkling texture, sanded pastel
|
|
33
|
+
paper for pastel, charcoal paper for charcoal, cotton canvas or gesso for painterly work,
|
|
34
|
+
smooth bristol for ink. Set `depth` for how much texture you want.
|
|
35
|
+
3. **Block in big shapes first.** Put each pass on its own layer (`add_layer` with a name).
|
|
36
|
+
`fill_layer` gives a ground colour (flat) or a tonal layer that catches the grain
|
|
37
|
+
(`grain` 0.6..1, `pressure` 0.2..0.6). Paint large masses with a big soft pastel or airbrush
|
|
38
|
+
in a few long `paint_stroke`s rather than many small ones.
|
|
39
|
+
4. **Mix colours before painting.** `mix_colors` predicts what paints mixed in given parts look
|
|
40
|
+
like (Kubelka-Munk: blue and yellow make green, white tints rather than greys). Use the result
|
|
41
|
+
as the stroke `color`. `set_color` makes it the default.
|
|
42
|
+
5. **Refine** with smaller brushes on new layers: pencil and ink for line, charcoal for value,
|
|
43
|
+
blender or smudge to soften edges, the Mixer Brush to blend wet into wet.
|
|
44
|
+
6. **Repeat and vary instead of drawing every mark.** Paint one good stroke, then
|
|
45
|
+
`replay_strokes` it with `dx` / `dy`, `rotate`, `scale`, `flipX`, `color`, `brushId` and
|
|
46
|
+
`repeat` for hatching, grass, foliage, rows, fans or spirals, in one undo step.
|
|
47
|
+
7. **Check** with `render_preview` after each block of work, not after each stroke.
|
|
48
|
+
`pick_color` reads exact values. Undo what made it worse.
|
|
49
|
+
8. **Deliver**: `export_image` (PNG, or JPEG / WebP in a browser), `export_psd` for Photoshop,
|
|
50
|
+
`save_document` to keep the painting with its strokes.
|
|
51
|
+
|
|
52
|
+
## Best practices
|
|
53
|
+
|
|
54
|
+
- **Big to small, dark to light (or light to dark), one decision per layer.** Name layers by
|
|
55
|
+
purpose ("Underpainting", "Shadows", "Line"). Lower a layer's `opacity` instead of repainting.
|
|
56
|
+
- **Pressure is your value control** on grainy media: points with `pressure` 0.2..0.4 give
|
|
57
|
+
texture-catching, broken marks; 0.8..1 fills the grain. Vary pressure along a stroke (swell in
|
|
58
|
+
the middle, lighten at the ends) for natural marks.
|
|
59
|
+
- **Give points a time `t`** (milliseconds, about 8..16 ms apart for natural speed) when using an
|
|
60
|
+
ink or brush pen: velocity dynamics thin fast strokes. Without `t` there is no velocity effect.
|
|
61
|
+
- **Tilt** (`altitude` near 0.3..0.6 radians with an `azimuth`) turns a pencil into broad side
|
|
62
|
+
shading; upright points draw a fine line.
|
|
63
|
+
- **Space points** about a third of the brush size apart or closer; the brush fills in dabs
|
|
64
|
+
between them. Long smooth curves need more points than straight lines.
|
|
65
|
+
- **Use `rotation: "stroke"`** for flat tips (pastel, charcoal, chisel marker) so the mark turns
|
|
66
|
+
with the path; `fixed` for calligraphic nibs.
|
|
67
|
+
- **Blend with flow, not opacity**: blender and smudge work best at flow 0.3..0.6; at full flow
|
|
68
|
+
the Mixer Brush paints only its own colour.
|
|
69
|
+
- **Pigment for paint, multiply for markers**: tip `blend: "pigment"` mixes subtractively on the
|
|
70
|
+
canvas; `multiply` darkens where marker strokes overlap. Pigment layers are written as Normal
|
|
71
|
+
to PSD (the export warns).
|
|
72
|
+
- **Save brushes you build** (`set_brush` then `save_brush`), and share them with
|
|
73
|
+
`export_brushes` / `import_brushes`.
|
|
74
|
+
|
|
75
|
+
## Tool reference
|
|
76
|
+
|
|
77
|
+
### Canvas and paper
|
|
78
|
+
|
|
79
|
+
| Tool | Use |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| `get_canvas_info` | Read the canvas size and dpi, paper (preset, colour, depth), active layer, layer count, active brush id, colours, view, hand, number of recorded strokes, undo / redo labels and the blend modes. Call first. |
|
|
82
|
+
| `new_canvas` | Start over with a blank canvas: one empty layer over the paper. `width`, `height` (1..16384 px), `dpi`, `paper` preset id; missing ones keep the current values. Undo brings the old painting back. Returns the size, paper and layer id. |
|
|
83
|
+
| `set_canvas` | Resize the canvas (pixels stay put, anchored top-left) or change its `dpi`. Returns the canvas. |
|
|
84
|
+
| `list_papers` | Read the paper library: id, name, family, grain pattern, colour, depth and the wet-media properties (absorption, permeability, roughness, stored for later wet media). Call before `set_paper`. |
|
|
85
|
+
| `get_paper` | Read every setting of the current paper (pattern, seed, scale, tiling, depth, shading, dry and wet tuning). |
|
|
86
|
+
| `set_paper` | Change the paper: `preset`, then any of `color`, `depth` (0..1), `scale` (0.25..8), `seed` (another sheet), `pattern`, `tiling`, `shading`, `dry` / `wet` tuning (`contrast` 0..3, `invert`). Affects new strokes' grain and how the paper shows; strokes already painted keep their pixels. Returns the paper. |
|
|
87
|
+
|
|
88
|
+
### Layers
|
|
89
|
+
|
|
90
|
+
| Tool | Use |
|
|
91
|
+
| --- | --- |
|
|
92
|
+
| `list_layers` | Read the layers top first: id, name, type (`pixel` / `group`), visible, opacity, blend, clipped, locks, `active`, painted `bounds` (null when empty), parent and depth. |
|
|
93
|
+
| `add_layer` | Add an empty pixel layer (or `type: "group"`) above the active layer, above `aboveId`, or at the top of group `parentId`; it becomes active. Returns the layer. Put each pass of a painting on its own layer. |
|
|
94
|
+
| `update_layer` | Change `name`, `visible`, `opacity` (0..1), `blend`, `clipped` (clip to the layer below) or `locks` (`pixels`, `transparency`: paint only where there is paint, `position`, `all`). Returns the layer. |
|
|
95
|
+
| `set_active_layer` | Make a layer the default target of strokes, fills and clears. Editor state. |
|
|
96
|
+
| `remove_layer` | Delete a layer (a group with its children). Prefer hiding it when the user may want it back. |
|
|
97
|
+
| `duplicate_layer` | Copy a layer directly above it (the copy becomes active): try a risky change on a copy. |
|
|
98
|
+
| `move_layer` | Reorder: `index` among siblings (0 = bottom), optionally into `parentId` (or `null` for the top level). |
|
|
99
|
+
| `merge_layer_down` | Merge a pixel layer into the pixel layer directly below (which keeps its settings). |
|
|
100
|
+
| `fill_layer` | Fill a pixel layer with `color` at `opacity`: flat, or with `grain` 0..1 following the paper grain (`pressure` 0..1 decides how far into the valleys, default 0.5). The fastest way to lay a ground or a textured tone. Returns the bounds. |
|
|
101
|
+
| `clear_layer` | Remove every pixel of a layer. Returns the bounds that were cleared. |
|
|
102
|
+
|
|
103
|
+
### Brushes
|
|
104
|
+
|
|
105
|
+
| Tool | Use |
|
|
106
|
+
| --- | --- |
|
|
107
|
+
| `list_brushes` | Read the library (built-in and saved): id, name, category, engine, size, grain response, rotation, `builtin`; plus the active brush id and whether it is edited. |
|
|
108
|
+
| `get_brush` | Read every setting of a brush, or of the active brush as edited (no `id`). Read before changing a brush you did not build. |
|
|
109
|
+
| `set_brush` | Choose the active brush (`id`) and / or change it: `tip` (size px, hardness, spacing, angle, roundness, opacity, flow, smoothing, pressureSize, pressureOpacity, blend), `grain`, `pressureSmoothing`, `rotation`, `dynamics` (minSize, pressureFlow, tiltSize, tiltRoundness, tiltOpacity, velocitySize, velocityOpacity, jitters, scatter), `mixer`, `loadsColor`. Editor state. Returns the brush. |
|
|
110
|
+
| `save_brush` | Store the active brush in the user library under `id` (lowercase, digits, dashes) and `name`. Built-in ids are refused. |
|
|
111
|
+
| `remove_brush` | Delete a user brush. Built-in brushes cannot be removed. |
|
|
112
|
+
| `export_brushes` | Get a brush library file (JSON) of `ids`, or of every user brush. |
|
|
113
|
+
| `import_brushes` | Add the brushes of a library file to the user library; taken ids are skipped unless `replace`. Returns `added`, `skipped`, `problems`. |
|
|
114
|
+
| `render_brush_thumbnail` | See what a brush does: a PNG of a test stroke (S-curve, pressure swelling and fading) on the current paper. Cheaper than painting and undoing. |
|
|
115
|
+
|
|
116
|
+
### Colour
|
|
117
|
+
|
|
118
|
+
| Tool | Use |
|
|
119
|
+
| --- | --- |
|
|
120
|
+
| `mix_colors` | Predict a paint mix: `colors` with `weight` parts (and optional tinting `strength`). Returns `mixed` (#rrggbb, Kubelka-Munk) and the plain RGB average for comparison. Changes nothing. Use it to choose stroke colours. |
|
|
121
|
+
| `set_color` | Set the default paint `color` (and `secondaryColor`). |
|
|
122
|
+
| `pick_color` | Read the colour at `x`, `y`: of the painting with its paper, or of one layer (with alpha). |
|
|
123
|
+
| `get_mixer_brush` | Read what the Mixer Brush carries: `reservoir`, `amount` left, `pickup`. |
|
|
124
|
+
| `load_mixer_brush` | Fill the Mixer Brush reservoir with a colour (keeps its pickup). |
|
|
125
|
+
| `clean_mixer_brush` | Empty the pickup well (and with `emptyReservoir` the paint). |
|
|
126
|
+
|
|
127
|
+
### Painting and strokes
|
|
128
|
+
|
|
129
|
+
| Tool | Use |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `paint_stroke` | Paint one stroke through `points` (document px; `pressure` 0..1, `t` ms, `tiltX` / `tiltY` or `altitude` / `azimuth`, `twist`) with `brushId` (default the active brush), optional per-stroke `brush` changes, `color`, `layerId`, `seed`. Returns `layerId`, `bounds`, `dabs`, `strokeId` and for the mixer engine its `mixerLoad`. Refused on locked, hidden or group layers, with the fix in the message. |
|
|
132
|
+
| `list_strokes` | Read the recorded strokes, oldest first (default the last 100): id, layer, brush, colour, point count, seed, bounds. With `ids`, their points too. |
|
|
133
|
+
| `replay_strokes` | Paint recorded `strokeIds` again: exactly, or varied by `dx` / `dy` (px), `rotate` (degrees clockwise), `scale` (brush size follows), `flipX`, `origin`, `pressureScale`, `color`, `brushId`, `layerId`, `repeat` (each copy applies the variation again). One undo step. Returns the new stroke ids, bounds and layers. |
|
|
134
|
+
| `undo_paint` | Undo the last step. Returns what was undone and what is next. |
|
|
135
|
+
| `redo_paint` | Redo the step just undone. |
|
|
136
|
+
|
|
137
|
+
### View, input and output
|
|
138
|
+
|
|
139
|
+
| Tool | Use |
|
|
140
|
+
| --- | --- |
|
|
141
|
+
| `set_view` | Rotate (degrees), mirror or zoom the view, or `reset` it. View state only: pixels never resample. Mirroring is a quick check of a drawing's proportions. |
|
|
142
|
+
| `set_hand` | Say which hand holds the pen (`right` / `left`) for palm rejection. |
|
|
143
|
+
| `render_preview` | See the painting (or `layerIds`) as a PNG, longest side `maxSide` (16..2048, default 512), with or without the `paper`. Render after each block of work. |
|
|
144
|
+
| `export_image` | Export PNG (default), JPEG or WebP as base64, at `quality` and `scale` (≤ 1); `paper: false` gives a transparent PNG. JPEG / WebP need a browser canvas. |
|
|
145
|
+
| `export_psd` | Export a PSD with every layer, the paper as a locked bottom layer, and the composite. Returns base64, size, `psb` and `warnings`. |
|
|
146
|
+
| `save_document` | Get the document JSON (canvas, paper, layers as PNG data URLs, strokes unless `strokes: false`). |
|
|
147
|
+
| `open_document` | Open a saved document JSON, replacing the painting and clearing the undo history. Returns the canvas, layers and any `problems`. |
|
|
148
|
+
|
|
149
|
+
## Pitfalls
|
|
150
|
+
|
|
151
|
+
- **Stroke-by-stroke drawing is slow and expensive.** Do not draw a detailed picture point by
|
|
152
|
+
point. Block in with fills and big strokes, then replay and vary a few good strokes.
|
|
153
|
+
- **A hidden or locked layer refuses paint**: show it (`update_layer visible true`) or unlock it.
|
|
154
|
+
`transparency` lock is not an error: paint only lands where the layer already has paint.
|
|
155
|
+
- **Depth 0 means no grain** whatever the brush; grainy media then look smooth. Smooth bristol
|
|
156
|
+
has depth 0.
|
|
157
|
+
- **Grain is fixed to the document**, not to the layer: moving content does not move the grain,
|
|
158
|
+
and two strokes on the same spot catch the same peaks.
|
|
159
|
+
- **Big soft brushes at full flow look flat.** Lower `flow` (airbrush 0.05..0.15) and build up.
|
|
160
|
+
- **JPEG and WebP need a browser**; in Node use PNG. Exports never upscale (`scale` ≤ 1).
|
|
161
|
+
- **Recorded strokes are kept in saved documents**; `save_document` with `strokes: false` when
|
|
162
|
+
only the pixels matter (smaller JSON).
|