@pixerate/editor 0.102.0 → 0.105.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 +3 -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-4X5MIVCE.js +8036 -0
- package/dist/chunk-4X5MIVCE.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-ZZOTHJ4K.cjs → chunk-PV42JITT.cjs} +1 -1
- package/dist/{chunk-ZZOTHJ4K.cjs.map → chunk-PV42JITT.cjs.map} +1 -1
- package/dist/chunk-XYBJKUAU.js +1 -0
- package/dist/chunk-XYBJKUAU.js.map +1 -0
- package/dist/chunk-ZID226ZG.cjs +8036 -0
- package/dist/chunk-ZID226ZG.cjs.map +1 -0
- package/dist/compositor-Bc3PNP3C.d.cts +835 -0
- package/dist/compositor-BsYYllvR.d.ts +835 -0
- package/dist/export-_m3Es4ru.d.cts +3154 -0
- package/dist/export-iMrop3Jm.d.ts +3154 -0
- package/dist/homography-CZ-tFjay.d.cts +50 -0
- package/dist/homography-Ctfjoc1b.d.ts +50 -0
- package/dist/image-editor/index.cjs +2873 -9450
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +31 -3150
- package/dist/image-editor/index.d.ts +31 -3150
- package/dist/image-editor/index.js +2550 -9127
- package/dist/image-editor/index.js.map +1 -1
- package/dist/mixer-C1M1Nua_.d.cts +282 -0
- package/dist/mixer-Cu5a9Bzd.d.ts +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 +4733 -0
- package/dist/paint-editor/index.cjs.map +1 -0
- package/dist/paint-editor/index.d.cts +1680 -0
- package/dist/paint-editor/index.d.ts +1680 -0
- package/dist/paint-editor/index.js +4733 -0
- package/dist/paint-editor/index.js.map +1 -0
- package/dist/raster/index.d.cts +6 -835
- package/dist/raster/index.d.ts +6 -835
- package/dist/{surface-DIA-XatS.d.cts → surface-BBJN9wxg.d.cts} +1 -1
- package/dist/{surface-DIA-XatS.d.ts → surface-BBJN9wxg.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 +14 -5
- package/skills/pixerate-paint-editor/SKILL.md +203 -0
- /package/dist/{chunk-IB53LVGV.js.map → chunk-DS7KDKPX.js.map} +0 -0
|
@@ -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, BLEND_MODES as b, type Tile as c, type BlendModeInfo as d, type Rgb as e, type Rgba as f, TILE as g, TILE_SHIFT as h, isBlendMode as i, blendChannel as j, blendImageData as k, blendLum as l, blendPixel as m, blendRgb as n, canvasCompositeOperation as o, collectTiles as p, contentBounds as q, emptySurface as r, fillRect as s, finishTile 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, BLEND_MODES as b, type Tile as c, type BlendModeInfo as d, type Rgb as e, type Rgba as f, TILE as g, TILE_SHIFT as h, isBlendMode as i, blendChannel as j, blendImageData as k, blendLum as l, blendPixel as m, blendRgb as n, canvasCompositeOperation as o, collectTiles as p, contentBounds as q, emptySurface as r, fillRect as s, finishTile 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.105.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. |
|
|
@@ -172,8 +172,9 @@ batching.
|
|
|
172
172
|
### Photoshop files
|
|
173
173
|
|
|
174
174
|
1. **Inspect before opening.** `inspect_psd` lists every layer with the type it would become and
|
|
175
|
-
a status: `mapped` (held exactly), `approximated` (type,
|
|
176
|
-
|
|
175
|
+
a status: `mapped` (held exactly), `approximated` (type, fill and shape layers come in as their
|
|
176
|
+
stored pixels; linked smart objects as their stored pixels; Photoshop smart filters other than
|
|
177
|
+
Box Blur are kept but not drawn; Dissolve becomes Normal; effects with gradient midpoints or
|
|
177
178
|
smoothness, noise gradients, glow jitter, legacy bevels or patterns missing from the file are
|
|
178
179
|
drawn approximately) or
|
|
179
180
|
`dropped` (Brightness/Contrast, Exposure, Channel Mixer, Gradient Map, Selective Color and
|
|
@@ -187,12 +188,20 @@ batching.
|
|
|
187
188
|
and 32-bit files are converted to 8-bit RGB, and ICC profiles are ignored; the warnings say
|
|
188
189
|
so. Afterwards work with `list_layers` as usual: there is no Background source image, every
|
|
189
190
|
pixel comes from the layers.
|
|
190
|
-
4.
|
|
191
|
+
4. **Smart objects come in live**: embedded contents (a PSB opens as a nested document you can
|
|
192
|
+
edit with `edit_smart_object_contents`, a PNG as raster contents), the placement and warp, the
|
|
193
|
+
smart filters and the filter mask; the layer shows Photoshop's own pixels until you change it.
|
|
194
|
+
JPEG, TIFF and SVG contents are decoded only in a browser, so elsewhere such a smart object
|
|
195
|
+
cannot be transformed (the error says so). Photoshop filters we do not model stay in the list
|
|
196
|
+
(kind `psd`): hide, reorder, re-blend or remove them, and `export_psd` writes them back.
|
|
197
|
+
5. **`export_psd` writes the stack as it is**, in the source frame: crop and rotation are not
|
|
191
198
|
applied, layer filters and depth masks are baked, annotation layers are rasterized (only in
|
|
192
199
|
a browser). Effects are written as Photoshop layer styles: an effects block opened from a PSD
|
|
193
200
|
goes back byte for byte while its effects are unchanged, and the patterns effects use (the
|
|
194
201
|
built-in ones too) are embedded. Only the first outer glow, inner glow, bevel, satin and
|
|
195
|
-
pattern overlay of a layer fit in a PSD.
|
|
202
|
+
pattern overlay of a layer fit in a PSD. Smart objects are written as smart objects (an
|
|
203
|
+
unchanged one byte for byte); a Develop smart filter has no Photoshop filter and is left out of
|
|
204
|
+
the list (the pixels still show it). Read its `warnings` and pass them on. The file comes back as base64 (`data`).
|
|
196
205
|
|
|
197
206
|
## Best practices
|
|
198
207
|
|
|
@@ -277,7 +286,7 @@ batching.
|
|
|
277
286
|
| `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. |
|
|
278
287
|
| `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. |
|
|
279
288
|
| `render_preview` | See the edited image (crop, adjustments, layers, annotations) as a PNG, or with `layerId` one layer alone. `maxSide` 16..2048 px, default 512. Images cost tokens: render after a group of edits, use 512 for overall look and 1024+ to judge clipping, edges and masks. Fails in environments without rendering. |
|
|
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`. |
|
|
289
|
+
| `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 (`smart` for smart objects) and `status` (`mapped`, `approximated`, `dropped`) with `notes`, and the import `warnings`. Call before `import_psd`. |
|
|
281
290
|
| `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. |
|
|
282
291
|
| `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
292
|
| `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. |
|
|
@@ -0,0 +1,203 @@
|
|
|
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, mirror and kaleidoscope painting, perspective guides, tracing and reference images, colour harmonies, swatches, a mixing pad and pigment mixing, previews and PNG, JPEG, WebP, PSD and JSON output. Use when asked to paint, sketch, draw, shade, block in, texture with paper grain, mix colours, paint symmetric or in perspective, trace an image, or when paint_stroke, set_paper, replay_strokes, set_symmetry 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
|
+
- **Guides** are editor state saved with the document: a symmetry guide makes every stroke paint
|
|
25
|
+
its mirror or kaleidoscope copies (one stroke), a perspective guide snaps strokes to lines
|
|
26
|
+
towards one to three vanishing points, a tracing image sits under the paint (never exported)
|
|
27
|
+
and can supply stroke colours, and reference images float beside the canvas to pick from.
|
|
28
|
+
- **Undo**: one tool call that changes the painting is one undo step (`undo_paint`). Brush,
|
|
29
|
+
colour, view, hand and the Mixer Brush load are editor state, not undo steps.
|
|
30
|
+
|
|
31
|
+
## Working method
|
|
32
|
+
|
|
33
|
+
1. **Read.** `get_canvas_info` (size, paper, active layer, active brush, colour), then
|
|
34
|
+
`list_layers`. `render_preview` to see the painting before changing it.
|
|
35
|
+
2. **Choose the ground.** Pick a paper that suits the medium (`list_papers`, `set_paper`, or
|
|
36
|
+
`new_canvas` with `paper`): cold pressed or rough for broken, sparkling texture, sanded pastel
|
|
37
|
+
paper for pastel, charcoal paper for charcoal, cotton canvas or gesso for painterly work,
|
|
38
|
+
smooth bristol for ink. Set `depth` for how much texture you want.
|
|
39
|
+
3. **Block in big shapes first.** Put each pass on its own layer (`add_layer` with a name).
|
|
40
|
+
`fill_layer` gives a ground colour (flat) or a tonal layer that catches the grain
|
|
41
|
+
(`grain` 0.6..1, `pressure` 0.2..0.6). Paint large masses with a big soft pastel or airbrush
|
|
42
|
+
in a few long `paint_stroke`s rather than many small ones.
|
|
43
|
+
4. **Plan and mix colours before painting.** `color_harmony` gives a palette around a key colour
|
|
44
|
+
(on the painter's red-yellow-blue wheel by default). `mix_colors` predicts what paints mixed
|
|
45
|
+
in given parts look like (Kubelka-Munk: blue and yellow make green, white tints rather than
|
|
46
|
+
greys); the mixing pad (`mixing_pad_stroke`, `pick_mixing_pad_color`) mixes by hand with a
|
|
47
|
+
palette knife. Keep chosen colours as swatches (`add_swatch`). Use the result as the stroke
|
|
48
|
+
`color`; `set_color` makes it the default.
|
|
49
|
+
5. **Refine** with smaller brushes on new layers: pencil and ink for line, charcoal for value,
|
|
50
|
+
blender or smudge to soften edges, the Mixer Brush to blend wet into wet.
|
|
51
|
+
6. **Let the guides multiply your marks.** `set_symmetry` (mirror for faces and vases,
|
|
52
|
+
kaleidoscope for mandalas and ornaments) paints every copy from one stroke;
|
|
53
|
+
`set_perspective_guide` plus `paint_stroke` with `snapToPerspective` lays converging lines for
|
|
54
|
+
buildings and roads. To copy an image's composition and colours, `set_tracing_image` with
|
|
55
|
+
`sampleColors` and paint over it.
|
|
56
|
+
7. **Repeat and vary instead of drawing every mark.** Paint one good stroke, then
|
|
57
|
+
`replay_strokes` it with `dx` / `dy`, `rotate`, `scale`, `flipX`, `color`, `brushId` and
|
|
58
|
+
`repeat` for hatching, grass, foliage, rows, fans or spirals, in one undo step.
|
|
59
|
+
8. **Check** with `render_preview` after each block of work, not after each stroke.
|
|
60
|
+
`pick_color` reads exact values. Undo what made it worse.
|
|
61
|
+
9. **Deliver**: `export_image` (PNG, or JPEG / WebP in a browser), `export_psd` for Photoshop,
|
|
62
|
+
`save_document` to keep the painting with its strokes.
|
|
63
|
+
|
|
64
|
+
## Best practices
|
|
65
|
+
|
|
66
|
+
- **Big to small, dark to light (or light to dark), one decision per layer.** Name layers by
|
|
67
|
+
purpose ("Underpainting", "Shadows", "Line"). Lower a layer's `opacity` instead of repainting.
|
|
68
|
+
- **Pressure is your value control** on grainy media: points with `pressure` 0.2..0.4 give
|
|
69
|
+
texture-catching, broken marks; 0.8..1 fills the grain. Vary pressure along a stroke (swell in
|
|
70
|
+
the middle, lighten at the ends) for natural marks.
|
|
71
|
+
- **Give points a time `t`** (milliseconds, about 8..16 ms apart for natural speed) when using an
|
|
72
|
+
ink or brush pen: velocity dynamics thin fast strokes. Without `t` there is no velocity effect.
|
|
73
|
+
- **Tilt** (`altitude` near 0.3..0.6 radians with an `azimuth`) turns a pencil into broad side
|
|
74
|
+
shading; upright points draw a fine line.
|
|
75
|
+
- **Space points** about a third of the brush size apart or closer; the brush fills in dabs
|
|
76
|
+
between them. Long smooth curves need more points than straight lines.
|
|
77
|
+
- **Use `rotation: "stroke"`** for flat tips (pastel, charcoal, chisel marker) so the mark turns
|
|
78
|
+
with the path; `fixed` for calligraphic nibs.
|
|
79
|
+
- **Blend with flow, not opacity**: blender and smudge work best at flow 0.3..0.6; at full flow
|
|
80
|
+
the Mixer Brush paints only its own colour.
|
|
81
|
+
- **Pigment for paint, multiply for markers**: tip `blend: "pigment"` mixes subtractively on the
|
|
82
|
+
canvas; `multiply` darkens where marker strokes overlap. Pigment layers are written as Normal
|
|
83
|
+
to PSD (the export warns).
|
|
84
|
+
- **Save brushes you build** (`set_brush` then `save_brush`), and share them with
|
|
85
|
+
`export_brushes` / `import_brushes`.
|
|
86
|
+
|
|
87
|
+
## Tool reference
|
|
88
|
+
|
|
89
|
+
### Canvas and paper
|
|
90
|
+
|
|
91
|
+
| Tool | Use |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
| `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. |
|
|
94
|
+
| `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. |
|
|
95
|
+
| `set_canvas` | Resize the canvas (pixels stay put, anchored top-left) or change its `dpi`. Returns the canvas. |
|
|
96
|
+
| `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`. |
|
|
97
|
+
| `get_paper` | Read every setting of the current paper (pattern, seed, scale, tiling, depth, shading, dry and wet tuning). |
|
|
98
|
+
| `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. |
|
|
99
|
+
|
|
100
|
+
### Layers
|
|
101
|
+
|
|
102
|
+
| Tool | Use |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| `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. |
|
|
105
|
+
| `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. |
|
|
106
|
+
| `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. |
|
|
107
|
+
| `set_active_layer` | Make a layer the default target of strokes, fills and clears. Editor state. |
|
|
108
|
+
| `remove_layer` | Delete a layer (a group with its children). Prefer hiding it when the user may want it back. |
|
|
109
|
+
| `duplicate_layer` | Copy a layer directly above it (the copy becomes active): try a risky change on a copy. |
|
|
110
|
+
| `move_layer` | Reorder: `index` among siblings (0 = bottom), optionally into `parentId` (or `null` for the top level). |
|
|
111
|
+
| `merge_layer_down` | Merge a pixel layer into the pixel layer directly below (which keeps its settings). |
|
|
112
|
+
| `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. |
|
|
113
|
+
| `clear_layer` | Remove every pixel of a layer. Returns the bounds that were cleared. |
|
|
114
|
+
|
|
115
|
+
### Brushes
|
|
116
|
+
|
|
117
|
+
| Tool | Use |
|
|
118
|
+
| --- | --- |
|
|
119
|
+
| `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. |
|
|
120
|
+
| `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. |
|
|
121
|
+
| `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. |
|
|
122
|
+
| `save_brush` | Store the active brush in the user library under `id` (lowercase, digits, dashes) and `name`. Built-in ids are refused. |
|
|
123
|
+
| `remove_brush` | Delete a user brush. Built-in brushes cannot be removed. |
|
|
124
|
+
| `export_brushes` | Get a brush library file (JSON) of `ids`, or of every user brush. |
|
|
125
|
+
| `import_brushes` | Add the brushes of a library file to the user library; taken ids are skipped unless `replace`. Returns `added`, `skipped`, `problems`. |
|
|
126
|
+
| `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. |
|
|
127
|
+
|
|
128
|
+
### Colour
|
|
129
|
+
|
|
130
|
+
| Tool | Use |
|
|
131
|
+
| --- | --- |
|
|
132
|
+
| `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. |
|
|
133
|
+
| `set_color` | Set the default paint `color` (and `secondaryColor`). |
|
|
134
|
+
| `pick_color` | Read the colour at `x`, `y`: of the painting with its paper, or of one layer (with alpha). |
|
|
135
|
+
| `get_mixer_brush` | Read what the Mixer Brush carries: `reservoir`, `amount` left, `pickup`. |
|
|
136
|
+
| `load_mixer_brush` | Fill the Mixer Brush reservoir with a colour (keeps its pickup). |
|
|
137
|
+
| `clean_mixer_brush` | Empty the pickup well (and with `emptyReservoir` the paint). |
|
|
138
|
+
| `color_harmony` | Get a harmony (`kind`: complementary, split-complementary, analogous, triadic, tetradic, square, monochromatic) around `color` (default the paint colour), on the `ryb` painter's wheel (default; red ↔ green) or the `rgb` wheel (red ↔ cyan), `spread` degrees for analogous and split. Changes nothing. |
|
|
139
|
+
| `list_swatches` | Read the swatches (index, colour, name). |
|
|
140
|
+
| `add_swatch` | Keep a colour as a swatch (saved with the document). |
|
|
141
|
+
| `remove_swatch` | Remove a swatch by `index`. |
|
|
142
|
+
| `mixing_pad_stroke` | Paint on the 360 × 220 mixing pad (pad px): `tool` paint lays `color` with a pigment Mixer Brush, `knife` smears what is there and mixes it as paint. Scratch space, not the painting, no undo. |
|
|
143
|
+
| `pick_mixing_pad_color` | Read the mix on the pad at `x`, `y` (averaged over `radius`, default 3); `setColor` makes it the paint colour. Null where the pad is bare. |
|
|
144
|
+
| `clear_mixing_pad` | Wipe the pad. |
|
|
145
|
+
| `render_mixing_pad` | See the pad as a PNG. |
|
|
146
|
+
|
|
147
|
+
### Painting and strokes
|
|
148
|
+
|
|
149
|
+
| Tool | Use |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `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`, `snapToPerspective`. The symmetry guide adds its copies; a sampling tracing image supplies the colour when `color` is missing. 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. |
|
|
152
|
+
| `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. |
|
|
153
|
+
| `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. |
|
|
154
|
+
| `undo_paint` | Undo the last step. Returns what was undone and what is next. |
|
|
155
|
+
| `redo_paint` | Redo the step just undone. |
|
|
156
|
+
|
|
157
|
+
### Guides
|
|
158
|
+
|
|
159
|
+
| Tool | Use |
|
|
160
|
+
| --- | --- |
|
|
161
|
+
| `get_guides` | Read the symmetry guide (with how many copies a stroke paints), the perspective guide, the tracing image and the reference images. |
|
|
162
|
+
| `set_symmetry` | `mode` off, vertical, horizontal, dual, diagonal or kaleidoscope (`segments` 2..32, `mirror`), `center` (document px, default the canvas centre), `rotation`. Every stroke after it paints its copies as one stroke; recorded strokes keep their copies when replayed. |
|
|
163
|
+
| `set_perspective_guide` | One to three vanishing `points` (document px, may be off the canvas), `enabled`, `snap`. Pen strokes snap to the guide line through their start that best matches their direction (one-point also keeps horizontals and verticals, two-point verticals); `paint_stroke` snaps only with `snapToPerspective`. |
|
|
164
|
+
| `set_tracing_image` | Put a PNG (`png` base64 or data URL) under the paint, fitted to the canvas or at `rect`, at `opacity` (default 0.35), with `sampleColors` to take stroke colours from it. View only: never exported. |
|
|
165
|
+
| `update_tracing_image` | Change the tracing image's `opacity`, `visible`, `sampleColors` or `rect`. |
|
|
166
|
+
| `clear_tracing_image` | Remove the tracing image. |
|
|
167
|
+
| `add_reference_image` | Add a floating reference PNG (`name`, panel `x`, `y`, `displayWidth`). Returns its id and size. |
|
|
168
|
+
| `list_reference_images` | Read the reference images: id, name, size, placement, visibility. |
|
|
169
|
+
| `update_reference_image` | Move, resize, rename, show or hide a reference panel. |
|
|
170
|
+
| `remove_reference_image` | Remove a reference image. |
|
|
171
|
+
| `pick_reference_color` | Read a reference image's colour at its own pixel `x`, `y`; `setColor` makes it the paint colour. |
|
|
172
|
+
|
|
173
|
+
### View, input and output
|
|
174
|
+
|
|
175
|
+
| Tool | Use |
|
|
176
|
+
| --- | --- |
|
|
177
|
+
| `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. |
|
|
178
|
+
| `set_hand` | Say which hand holds the pen (`right` / `left`) for palm rejection. |
|
|
179
|
+
| `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. |
|
|
180
|
+
| `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. |
|
|
181
|
+
| `export_psd` | Export a PSD with every layer, the paper as a locked bottom layer, and the composite. Returns base64, size, `psb` and `warnings`. |
|
|
182
|
+
| `save_document` | Get the document JSON (canvas, paper, layers as PNG data URLs, strokes unless `strokes: false`). |
|
|
183
|
+
| `open_document` | Open a saved document JSON, replacing the painting and clearing the undo history. Returns the canvas, layers and any `problems`. |
|
|
184
|
+
|
|
185
|
+
## Pitfalls
|
|
186
|
+
|
|
187
|
+
- **Stroke-by-stroke drawing is slow and expensive.** Do not draw a detailed picture point by
|
|
188
|
+
point. Block in with fills and big strokes, then replay and vary a few good strokes.
|
|
189
|
+
- **A hidden or locked layer refuses paint**: show it (`update_layer visible true`) or unlock it.
|
|
190
|
+
`transparency` lock is not an error: paint only lands where the layer already has paint.
|
|
191
|
+
- **Depth 0 means no grain** whatever the brush; grainy media then look smooth. Smooth bristol
|
|
192
|
+
has depth 0.
|
|
193
|
+
- **Grain is fixed to the document**, not to the layer: moving content does not move the grain,
|
|
194
|
+
and two strokes on the same spot catch the same peaks.
|
|
195
|
+
- **Big soft brushes at full flow look flat.** Lower `flow` (airbrush 0.05..0.15) and build up.
|
|
196
|
+
- **JPEG and WebP need a browser**; in Node use PNG. Exports never upscale (`scale` ≤ 1).
|
|
197
|
+
- **Symmetry stays on until you turn it off.** Set `mode: "off"` after the symmetric part, or
|
|
198
|
+
every later stroke is mirrored too.
|
|
199
|
+
- **The tracing image is not in exports or previews of the painting alone**; paint over it on a
|
|
200
|
+
layer. Turn `sampleColors` off before painting your own colours, or strokes without `color`
|
|
201
|
+
keep taking its colours.
|
|
202
|
+
- **Recorded strokes are kept in saved documents**; `save_document` with `strokes: false` when
|
|
203
|
+
only the pixels matter (smaller JSON).
|
|
File without changes
|