@pixerate/editor 0.239.0 → 0.241.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation-editor/index.cjs +58 -58
- package/dist/animation-editor/index.js +3 -3
- package/dist/{brushstrokeRender-WB67GMUP.js → brushstrokeRender-MOYGEXOC.js} +2 -2
- package/dist/{brushstrokeRender-MPOM7BFW.cjs → brushstrokeRender-UKADOV5D.cjs} +5 -5
- package/dist/canvas/index.cjs +8 -8
- package/dist/canvas/index.js +1 -1
- package/dist/{chunk-NKTNLJUJ.cjs → chunk-5BR7LC24.cjs} +99 -11
- package/dist/{chunk-ZXNO3ZOX.cjs → chunk-7F4G74UQ.cjs} +35 -35
- package/dist/{chunk-AD7GA3TL.cjs → chunk-AFLMXITL.cjs} +23 -23
- package/dist/{chunk-PP6BXVRL.cjs → chunk-HGGJ36HR.cjs} +1 -1
- package/dist/{chunk-BBUE3UJL.cjs → chunk-HW72ABGR.cjs} +86 -86
- package/dist/{chunk-7YGBSFC6.js → chunk-ILM6GYAX.js} +1 -1
- package/dist/{chunk-THXFU3JB.cjs → chunk-KCMV2534.cjs} +2 -2
- package/dist/{chunk-3E36VDMJ.js → chunk-NE6OOKWJ.js} +1 -1
- package/dist/{chunk-RV5DKZHU.js → chunk-QP2B3MID.js} +1 -1
- package/dist/{chunk-UUBO6RB5.js → chunk-UDBDYZET.js} +1 -1
- package/dist/{chunk-PJYG6FCF.js → chunk-XBZK47LV.js} +98 -10
- package/dist/{chunk-XK4SST43.js → chunk-ZDPLZDTT.js} +1 -1
- package/dist/image-editor/index.cjs +775 -775
- package/dist/image-editor/index.js +4 -4
- package/dist/paint-editor/controller.d.cts +158 -1
- package/dist/paint-editor/controller.d.ts +158 -1
- package/dist/paint-editor/document.d.cts +7 -2
- package/dist/paint-editor/document.d.ts +7 -2
- package/dist/paint-editor/effect-paint.d.cts +60 -3
- package/dist/paint-editor/effect-paint.d.ts +60 -3
- package/dist/paint-editor/index.cjs +1246 -430
- package/dist/paint-editor/index.d.cts +1 -0
- package/dist/paint-editor/index.d.ts +1 -0
- package/dist/paint-editor/index.js +888 -72
- package/dist/paint-editor/live-strokes.d.cts +24 -0
- package/dist/paint-editor/live-strokes.d.ts +24 -0
- package/dist/paint-editor/stickers.d.cts +6 -0
- package/dist/paint-editor/stickers.d.ts +6 -0
- package/dist/paint-editor/thick.d.cts +4 -0
- package/dist/paint-editor/thick.d.ts +4 -0
- package/dist/paint-editor/ui.d.cts +24 -4
- package/dist/paint-editor/ui.d.ts +24 -4
- package/dist/paint-editor/wet.d.cts +8 -0
- package/dist/paint-editor/wet.d.ts +8 -0
- package/dist/vector/index.cjs +962 -962
- package/dist/vector/index.js +4 -4
- package/package.json +1 -1
- package/skills/pixerate-paint-editor/SKILL.md +38 -27
- package/skills/pixerate-paint-editor/references/effect-paint.md +25 -0
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
parseOpenTypeFont,
|
|
9
9
|
removeAnchorsKeepingShape,
|
|
10
10
|
traceField
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-UDBDYZET.js";
|
|
12
12
|
import {
|
|
13
13
|
ColorGmm,
|
|
14
14
|
GAMMA,
|
|
@@ -410,7 +410,7 @@ import {
|
|
|
410
410
|
writePsd,
|
|
411
411
|
xyToTempTint,
|
|
412
412
|
xyToUv
|
|
413
|
-
} from "../chunk-
|
|
413
|
+
} from "../chunk-NE6OOKWJ.js";
|
|
414
414
|
import {
|
|
415
415
|
parseCssColor
|
|
416
416
|
} from "../chunk-3CI7FRMK.js";
|
|
@@ -729,8 +729,8 @@ import {
|
|
|
729
729
|
warpMeshParamAt,
|
|
730
730
|
warpMeshRows,
|
|
731
731
|
warpPresetMesh
|
|
732
|
-
} from "../chunk-
|
|
733
|
-
import "../chunk-
|
|
732
|
+
} from "../chunk-ILM6GYAX.js";
|
|
733
|
+
import "../chunk-XBZK47LV.js";
|
|
734
734
|
import "../chunk-M6DNZNVY.js";
|
|
735
735
|
import {
|
|
736
736
|
bezierPathToSvg,
|
|
@@ -112,6 +112,14 @@ export interface PaintEditorState {
|
|
|
112
112
|
mixerLoad: MixerLoad;
|
|
113
113
|
view: PaintView;
|
|
114
114
|
hand: Hand;
|
|
115
|
+
/** Live effect paint: whether strokes on stroke layers play their effect, the frame rate cap and the time (ms) the view shows. Editor state. */
|
|
116
|
+
effectPlayback: {
|
|
117
|
+
playing: boolean;
|
|
118
|
+
fps: number;
|
|
119
|
+
time: number;
|
|
120
|
+
};
|
|
121
|
+
/** The stroke picked on a stroke layer, on the canvas or in the stroke panel (editor state, not an undo step). */
|
|
122
|
+
selectedStroke: string | null;
|
|
115
123
|
/** The sticker picked on the canvas or in the sticker panel (editor state, not an undo step). */
|
|
116
124
|
selectedSticker: string | null;
|
|
117
125
|
canUndo: boolean;
|
|
@@ -134,6 +142,19 @@ export interface PaintEditorState {
|
|
|
134
142
|
version: number;
|
|
135
143
|
}
|
|
136
144
|
/** A layer as tools and panels describe it. */
|
|
145
|
+
/** A change to a live stroke (`updateStroke`): every field is optional. */
|
|
146
|
+
export interface LiveStrokeUpdate {
|
|
147
|
+
/** Another brush preset; the stroke keeps its size. */
|
|
148
|
+
brushId?: string;
|
|
149
|
+
/** Brush settings to change (as `setBrush` takes), on top of `brushId` or the stroke's brush. */
|
|
150
|
+
brush?: Omit<PaintBrushInput, 'id'>;
|
|
151
|
+
/** A new colour #rrggbb (replaces gradient or effect paint). */
|
|
152
|
+
color?: string;
|
|
153
|
+
/** Paint: a colour, gradient paint or effect paint; `null` back to the plain colour. */
|
|
154
|
+
paint?: unknown;
|
|
155
|
+
/** Another jitter seed (particles, scatter and texture fall differently). */
|
|
156
|
+
seed?: number;
|
|
157
|
+
}
|
|
137
158
|
export interface PaintLayerInfo {
|
|
138
159
|
id: string;
|
|
139
160
|
name: string;
|
|
@@ -148,6 +169,8 @@ export interface PaintLayerInfo {
|
|
|
148
169
|
bounds: RasterRect | null;
|
|
149
170
|
parentId: string | null;
|
|
150
171
|
depth: number;
|
|
172
|
+
/** A live stroke layer (its pixels are drawn from its strokes, which stay editable): how many strokes it has. */
|
|
173
|
+
liveStrokes?: number;
|
|
151
174
|
}
|
|
152
175
|
export interface PaintStrokeInit {
|
|
153
176
|
/** Default the active layer. */
|
|
@@ -277,6 +300,7 @@ export declare class PaintEditorController {
|
|
|
277
300
|
private mixerLoad;
|
|
278
301
|
private view;
|
|
279
302
|
private hand;
|
|
303
|
+
private selectedStroke;
|
|
280
304
|
private selectedSticker;
|
|
281
305
|
/** A sticker drag in progress (`previewSticker`): the document before it, so the drop undoes in one step, and the one it showed last. */
|
|
282
306
|
private stickerPreview;
|
|
@@ -290,6 +314,17 @@ export declare class PaintEditorController {
|
|
|
290
314
|
private dirty;
|
|
291
315
|
private seedCounter;
|
|
292
316
|
private strokeCounter;
|
|
317
|
+
/** Live effect paint: playing and the frame rate cap (editor state), and the time the view shows. */
|
|
318
|
+
private effectPlaybackState;
|
|
319
|
+
private effectTime;
|
|
320
|
+
/** While a frame is drawn: the time live effect strokes are drawn at (else their own time). */
|
|
321
|
+
private liveEffectAt;
|
|
322
|
+
/** The view's stroke layers at `effectTime`, each with the document surface it was drawn from (stale once that changes). */
|
|
323
|
+
private animatedLayers;
|
|
324
|
+
/** `renderAnimationFrame` / `withEffectTime`: layer surfaces at another time, for one render. */
|
|
325
|
+
private frameOverride;
|
|
326
|
+
/** The area each stroke painted (document pixels; `null`: nothing), learnt as it is painted or drawn, so a stroke layer edit redraws only where it changes (see `drawLiveStrokes`). */
|
|
327
|
+
private paintedBounds;
|
|
293
328
|
private guides;
|
|
294
329
|
private swatches;
|
|
295
330
|
private readonly pad;
|
|
@@ -403,9 +438,10 @@ export declare class PaintEditorController {
|
|
|
403
438
|
private paintTarget;
|
|
404
439
|
setActiveLayer(id: string): void;
|
|
405
440
|
/** Adds an empty pixel layer or group above `aboveId` (default: the active layer) and makes it active. */
|
|
441
|
+
/** Adds a layer above the active one: `pixel` (default), `group`, or `strokes`, a live stroke layer whose strokes stay editable. */
|
|
406
442
|
addLayer(options?: {
|
|
407
443
|
name?: string;
|
|
408
|
-
type?: 'pixel' | 'group';
|
|
444
|
+
type?: 'pixel' | 'group' | 'strokes';
|
|
409
445
|
aboveId?: string;
|
|
410
446
|
parentId?: string | null;
|
|
411
447
|
}): PaintLayerInfo;
|
|
@@ -538,11 +574,15 @@ export declare class PaintEditorController {
|
|
|
538
574
|
* size, and brushes then take each pixel's colour (and alpha) from it, fixed to the canvas, as if
|
|
539
575
|
* painting a hidden picture into view. `setColor` and `setPaint` go back to colour. Editor state,
|
|
540
576
|
* not an undo step. Strokes that would paint with it throw while it renders. Returns the paint.
|
|
577
|
+
* With `map: { by: 'stroke' }` the effect lies along each stroke instead of the canvas; with
|
|
578
|
+
* `live`, strokes on a stroke layer keep playing it (see `setEffectPlayback`).
|
|
541
579
|
*/
|
|
542
580
|
setEffectPaint(source: {
|
|
543
581
|
effect: string;
|
|
544
582
|
values?: Record<string, EffectValue | null>;
|
|
545
583
|
time?: number;
|
|
584
|
+
map?: unknown;
|
|
585
|
+
live?: boolean;
|
|
546
586
|
}): Promise<PaintEffectPaint>;
|
|
547
587
|
/** The rendered pixels of an effect paint at the current canvas size, or `null` when it has not been rendered. */
|
|
548
588
|
private effectPaintImage;
|
|
@@ -1000,6 +1040,121 @@ export declare class PaintEditorController {
|
|
|
1000
1040
|
removeStickers(layerId: string | undefined, ids?: readonly string[]): string[];
|
|
1001
1041
|
/** Sets a layer's stickers (replays). */
|
|
1002
1042
|
replaceStickers(layerId: string, stickers: readonly Sticker[]): void;
|
|
1043
|
+
/** The document's `liveStrokes` without these layers (as a spread: `{}` when unchanged). */
|
|
1044
|
+
private liveStrokesWithout;
|
|
1045
|
+
private liveStrokeLayer;
|
|
1046
|
+
/** Whether a layer is a live stroke layer. */
|
|
1047
|
+
isLiveStrokeLayer(layerId: string): boolean;
|
|
1048
|
+
/** Makes an empty pixel layer a live stroke layer (one undo step). */
|
|
1049
|
+
convertToLiveStrokes(layerId?: string): PaintLayerInfo;
|
|
1050
|
+
/** A stroke layer's strokes, bottom first. */
|
|
1051
|
+
listLiveStrokes(layerId?: string): RecordedStroke[];
|
|
1052
|
+
/** The stroke layer holding a live stroke, and where. */
|
|
1053
|
+
private findLiveStroke;
|
|
1054
|
+
/**
|
|
1055
|
+
* Changes a live stroke's brush (a preset by `brushId`, keeping the stroke's size, and/or brush
|
|
1056
|
+
* settings), colour, paint or seed, and redraws its layer (one undo step). A new colour replaces
|
|
1057
|
+
* gradient or effect paint. Returns the stroke and the area that changed.
|
|
1058
|
+
*/
|
|
1059
|
+
updateStroke(id: string, update: LiveStrokeUpdate): {
|
|
1060
|
+
stroke: RecordedStroke;
|
|
1061
|
+
bounds: RasterRect;
|
|
1062
|
+
};
|
|
1063
|
+
/**
|
|
1064
|
+
* Replaces a live stroke's points, or moves, scales, rotates or flips them (`transform`, about
|
|
1065
|
+
* the stroke's centre unless an origin is given; the brush size scales too), and redraws its
|
|
1066
|
+
* layer (one undo step). Returns the stroke and the area that changed.
|
|
1067
|
+
*/
|
|
1068
|
+
editStrokePoints(id: string, edit: {
|
|
1069
|
+
points?: readonly PenPoint[];
|
|
1070
|
+
transform?: StrokeVariation;
|
|
1071
|
+
}): {
|
|
1072
|
+
stroke: RecordedStroke;
|
|
1073
|
+
bounds: RasterRect;
|
|
1074
|
+
};
|
|
1075
|
+
/** Deletes live strokes (one undo step). Returns the ids removed and the area that changed. */
|
|
1076
|
+
removeStrokes(ids: readonly string[]): {
|
|
1077
|
+
removed: string[];
|
|
1078
|
+
bounds: RasterRect | null;
|
|
1079
|
+
};
|
|
1080
|
+
/** Moves a live stroke to `index` in its layer (0 = bottom) and redraws (one undo step). Returns the new order. */
|
|
1081
|
+
reorderStroke(id: string, index: number): string[];
|
|
1082
|
+
/** Turns a stroke layer into a plain pixel layer with the same pixels (one undo step). */
|
|
1083
|
+
rasterizeLiveStrokes(layerId?: string): PaintLayerInfo;
|
|
1084
|
+
/** Sets a layer's live strokes and redraws it (replays). `null` makes it a plain pixel layer. */
|
|
1085
|
+
replaceLiveStrokes(layerId: string, strokes: readonly RecordedStroke[] | null): void;
|
|
1086
|
+
/**
|
|
1087
|
+
* The top-most stroke of a stroke layer (default the active layer) that painted the pixel at
|
|
1088
|
+
* (x, y) document pixels, or `null`. Strokes whose area holds the point are drawn alone, top
|
|
1089
|
+
* first, until one covers it.
|
|
1090
|
+
*/
|
|
1091
|
+
liveStrokeAt(layerId: string | undefined, x: number, y: number): RecordedStroke | null;
|
|
1092
|
+
/** Picks a stroke for the stroke panel and canvas (`null` for none). Editor state, not an undo step. */
|
|
1093
|
+
selectStroke(id: string | null): void;
|
|
1094
|
+
/** Where a live stroke painted (document pixels), or `null`. */
|
|
1095
|
+
liveStrokeArea(id: string): RasterRect | null;
|
|
1096
|
+
/** Commits a layer's new stroke list with its redrawn pixels, recorded for replays (one undo step). */
|
|
1097
|
+
private commitLiveStrokes;
|
|
1098
|
+
private withLiveStrokes;
|
|
1099
|
+
/** Where a stroke painted (document pixels): as learnt when it was painted or drawn, else an estimate from its points and brush. */
|
|
1100
|
+
private strokeArea;
|
|
1101
|
+
/** The areas strokes painted, or `null` when one is not known (a full redraw then). */
|
|
1102
|
+
private strokeAreas;
|
|
1103
|
+
/** Draws one stroke onto `surface` of a plain copy of the layer; returns the result and the area it painted. */
|
|
1104
|
+
private drawLiveStroke;
|
|
1105
|
+
/**
|
|
1106
|
+
* A stroke layer's pixels drawn from its strokes, bottom first. With `dirty` (the areas the old
|
|
1107
|
+
* strokes that changed had painted), only the tiles there and under any stroke whose area isn't
|
|
1108
|
+
* known yet are drawn again, from the strokes that reach them (a pixel depends only on the
|
|
1109
|
+
* strokes over it); the other tiles are kept. Without it, or with `null`, every stroke is drawn.
|
|
1110
|
+
*/
|
|
1111
|
+
private drawLiveStrokes;
|
|
1112
|
+
/** The view's layers: stroke layers playing live effects at `effectTime`, the rest as they are. */
|
|
1113
|
+
private animatedView;
|
|
1114
|
+
/** Stroke layers with live effect strokes, and the distinct live sources (frame 0). */
|
|
1115
|
+
private liveEffects;
|
|
1116
|
+
/** What plays: the live effect strokes and their layers, or `null` when nothing does. */
|
|
1117
|
+
getAnimation(): {
|
|
1118
|
+
layerIds: string[];
|
|
1119
|
+
strokes: number;
|
|
1120
|
+
sources: number;
|
|
1121
|
+
} | null;
|
|
1122
|
+
/** Plays or pauses live effect paint, and caps its frame rate (1..60). Editor state, not an undo step. */
|
|
1123
|
+
setEffectPlayback(update: {
|
|
1124
|
+
playing?: boolean;
|
|
1125
|
+
fps?: number;
|
|
1126
|
+
}): {
|
|
1127
|
+
playing: boolean;
|
|
1128
|
+
fps: number;
|
|
1129
|
+
time: number;
|
|
1130
|
+
};
|
|
1131
|
+
/** The surfaces of every stroke layer with live effects at `time` ms, drawn in full (frames rendered first). */
|
|
1132
|
+
private liveSurfacesAt;
|
|
1133
|
+
/**
|
|
1134
|
+
* Shows the live effects at `time` ms (each live stroke's effect at its own time plus `time`):
|
|
1135
|
+
* renders their frames, then redraws only where live effect strokes paint. Nothing in the
|
|
1136
|
+
* document changes. Resolves `false` when the document changed while frames rendered (the next
|
|
1137
|
+
* frame catches up).
|
|
1138
|
+
*/
|
|
1139
|
+
showEffectTime(time: number): Promise<boolean>;
|
|
1140
|
+
/**
|
|
1141
|
+
* Plays live effect paint in the view until `stop`: a frame per tick of `clock` (default
|
|
1142
|
+
* animation frames) at most `fps` a second, one render in flight. Idle while paused, while a
|
|
1143
|
+
* stroke is painted, or when nothing is live. The bindings start it while the editor is shown.
|
|
1144
|
+
*/
|
|
1145
|
+
playEffects(clock?: {
|
|
1146
|
+
now(): number;
|
|
1147
|
+
frame(cb: () => void): () => void;
|
|
1148
|
+
}): {
|
|
1149
|
+
stop(): void;
|
|
1150
|
+
};
|
|
1151
|
+
/**
|
|
1152
|
+
* Runs `fn` with the painting as it is `time` ms into its live effects (see `getAnimation`): for
|
|
1153
|
+
* exports at a moment. Nothing in the document changes.
|
|
1154
|
+
*/
|
|
1155
|
+
withEffectTime<T>(time: number, fn: () => T | Promise<T>): Promise<T>;
|
|
1156
|
+
/** The painting composited `time` ms into its live effects, like `compositePixels`. Nothing in the document changes. */
|
|
1157
|
+
renderAnimationFrame(time: number, options?: RenderOptions): Promise<PixelImage>;
|
|
1003
1158
|
private stencilCache;
|
|
1004
1159
|
private nextStencilId;
|
|
1005
1160
|
/** The mask stencils' coverage over the canvas (cached), or `null` when none masks. */
|
|
@@ -1074,3 +1229,5 @@ export declare class PaintEditorController {
|
|
|
1074
1229
|
export type { Tile };
|
|
1075
1230
|
/** Largest tracing or reference image side, in pixels. */
|
|
1076
1231
|
export declare const MAX_IMAGE_SIDE = 8192;
|
|
1232
|
+
/** The most live effects (distinct sources) a document plays at once: each needs a renderer. */
|
|
1233
|
+
export declare const MAX_LIVE_EFFECT_SOURCES = 8;
|
|
@@ -112,6 +112,14 @@ export interface PaintEditorState {
|
|
|
112
112
|
mixerLoad: MixerLoad;
|
|
113
113
|
view: PaintView;
|
|
114
114
|
hand: Hand;
|
|
115
|
+
/** Live effect paint: whether strokes on stroke layers play their effect, the frame rate cap and the time (ms) the view shows. Editor state. */
|
|
116
|
+
effectPlayback: {
|
|
117
|
+
playing: boolean;
|
|
118
|
+
fps: number;
|
|
119
|
+
time: number;
|
|
120
|
+
};
|
|
121
|
+
/** The stroke picked on a stroke layer, on the canvas or in the stroke panel (editor state, not an undo step). */
|
|
122
|
+
selectedStroke: string | null;
|
|
115
123
|
/** The sticker picked on the canvas or in the sticker panel (editor state, not an undo step). */
|
|
116
124
|
selectedSticker: string | null;
|
|
117
125
|
canUndo: boolean;
|
|
@@ -134,6 +142,19 @@ export interface PaintEditorState {
|
|
|
134
142
|
version: number;
|
|
135
143
|
}
|
|
136
144
|
/** A layer as tools and panels describe it. */
|
|
145
|
+
/** A change to a live stroke (`updateStroke`): every field is optional. */
|
|
146
|
+
export interface LiveStrokeUpdate {
|
|
147
|
+
/** Another brush preset; the stroke keeps its size. */
|
|
148
|
+
brushId?: string;
|
|
149
|
+
/** Brush settings to change (as `setBrush` takes), on top of `brushId` or the stroke's brush. */
|
|
150
|
+
brush?: Omit<PaintBrushInput, 'id'>;
|
|
151
|
+
/** A new colour #rrggbb (replaces gradient or effect paint). */
|
|
152
|
+
color?: string;
|
|
153
|
+
/** Paint: a colour, gradient paint or effect paint; `null` back to the plain colour. */
|
|
154
|
+
paint?: unknown;
|
|
155
|
+
/** Another jitter seed (particles, scatter and texture fall differently). */
|
|
156
|
+
seed?: number;
|
|
157
|
+
}
|
|
137
158
|
export interface PaintLayerInfo {
|
|
138
159
|
id: string;
|
|
139
160
|
name: string;
|
|
@@ -148,6 +169,8 @@ export interface PaintLayerInfo {
|
|
|
148
169
|
bounds: RasterRect | null;
|
|
149
170
|
parentId: string | null;
|
|
150
171
|
depth: number;
|
|
172
|
+
/** A live stroke layer (its pixels are drawn from its strokes, which stay editable): how many strokes it has. */
|
|
173
|
+
liveStrokes?: number;
|
|
151
174
|
}
|
|
152
175
|
export interface PaintStrokeInit {
|
|
153
176
|
/** Default the active layer. */
|
|
@@ -277,6 +300,7 @@ export declare class PaintEditorController {
|
|
|
277
300
|
private mixerLoad;
|
|
278
301
|
private view;
|
|
279
302
|
private hand;
|
|
303
|
+
private selectedStroke;
|
|
280
304
|
private selectedSticker;
|
|
281
305
|
/** A sticker drag in progress (`previewSticker`): the document before it, so the drop undoes in one step, and the one it showed last. */
|
|
282
306
|
private stickerPreview;
|
|
@@ -290,6 +314,17 @@ export declare class PaintEditorController {
|
|
|
290
314
|
private dirty;
|
|
291
315
|
private seedCounter;
|
|
292
316
|
private strokeCounter;
|
|
317
|
+
/** Live effect paint: playing and the frame rate cap (editor state), and the time the view shows. */
|
|
318
|
+
private effectPlaybackState;
|
|
319
|
+
private effectTime;
|
|
320
|
+
/** While a frame is drawn: the time live effect strokes are drawn at (else their own time). */
|
|
321
|
+
private liveEffectAt;
|
|
322
|
+
/** The view's stroke layers at `effectTime`, each with the document surface it was drawn from (stale once that changes). */
|
|
323
|
+
private animatedLayers;
|
|
324
|
+
/** `renderAnimationFrame` / `withEffectTime`: layer surfaces at another time, for one render. */
|
|
325
|
+
private frameOverride;
|
|
326
|
+
/** The area each stroke painted (document pixels; `null`: nothing), learnt as it is painted or drawn, so a stroke layer edit redraws only where it changes (see `drawLiveStrokes`). */
|
|
327
|
+
private paintedBounds;
|
|
293
328
|
private guides;
|
|
294
329
|
private swatches;
|
|
295
330
|
private readonly pad;
|
|
@@ -403,9 +438,10 @@ export declare class PaintEditorController {
|
|
|
403
438
|
private paintTarget;
|
|
404
439
|
setActiveLayer(id: string): void;
|
|
405
440
|
/** Adds an empty pixel layer or group above `aboveId` (default: the active layer) and makes it active. */
|
|
441
|
+
/** Adds a layer above the active one: `pixel` (default), `group`, or `strokes`, a live stroke layer whose strokes stay editable. */
|
|
406
442
|
addLayer(options?: {
|
|
407
443
|
name?: string;
|
|
408
|
-
type?: 'pixel' | 'group';
|
|
444
|
+
type?: 'pixel' | 'group' | 'strokes';
|
|
409
445
|
aboveId?: string;
|
|
410
446
|
parentId?: string | null;
|
|
411
447
|
}): PaintLayerInfo;
|
|
@@ -538,11 +574,15 @@ export declare class PaintEditorController {
|
|
|
538
574
|
* size, and brushes then take each pixel's colour (and alpha) from it, fixed to the canvas, as if
|
|
539
575
|
* painting a hidden picture into view. `setColor` and `setPaint` go back to colour. Editor state,
|
|
540
576
|
* not an undo step. Strokes that would paint with it throw while it renders. Returns the paint.
|
|
577
|
+
* With `map: { by: 'stroke' }` the effect lies along each stroke instead of the canvas; with
|
|
578
|
+
* `live`, strokes on a stroke layer keep playing it (see `setEffectPlayback`).
|
|
541
579
|
*/
|
|
542
580
|
setEffectPaint(source: {
|
|
543
581
|
effect: string;
|
|
544
582
|
values?: Record<string, EffectValue | null>;
|
|
545
583
|
time?: number;
|
|
584
|
+
map?: unknown;
|
|
585
|
+
live?: boolean;
|
|
546
586
|
}): Promise<PaintEffectPaint>;
|
|
547
587
|
/** The rendered pixels of an effect paint at the current canvas size, or `null` when it has not been rendered. */
|
|
548
588
|
private effectPaintImage;
|
|
@@ -1000,6 +1040,121 @@ export declare class PaintEditorController {
|
|
|
1000
1040
|
removeStickers(layerId: string | undefined, ids?: readonly string[]): string[];
|
|
1001
1041
|
/** Sets a layer's stickers (replays). */
|
|
1002
1042
|
replaceStickers(layerId: string, stickers: readonly Sticker[]): void;
|
|
1043
|
+
/** The document's `liveStrokes` without these layers (as a spread: `{}` when unchanged). */
|
|
1044
|
+
private liveStrokesWithout;
|
|
1045
|
+
private liveStrokeLayer;
|
|
1046
|
+
/** Whether a layer is a live stroke layer. */
|
|
1047
|
+
isLiveStrokeLayer(layerId: string): boolean;
|
|
1048
|
+
/** Makes an empty pixel layer a live stroke layer (one undo step). */
|
|
1049
|
+
convertToLiveStrokes(layerId?: string): PaintLayerInfo;
|
|
1050
|
+
/** A stroke layer's strokes, bottom first. */
|
|
1051
|
+
listLiveStrokes(layerId?: string): RecordedStroke[];
|
|
1052
|
+
/** The stroke layer holding a live stroke, and where. */
|
|
1053
|
+
private findLiveStroke;
|
|
1054
|
+
/**
|
|
1055
|
+
* Changes a live stroke's brush (a preset by `brushId`, keeping the stroke's size, and/or brush
|
|
1056
|
+
* settings), colour, paint or seed, and redraws its layer (one undo step). A new colour replaces
|
|
1057
|
+
* gradient or effect paint. Returns the stroke and the area that changed.
|
|
1058
|
+
*/
|
|
1059
|
+
updateStroke(id: string, update: LiveStrokeUpdate): {
|
|
1060
|
+
stroke: RecordedStroke;
|
|
1061
|
+
bounds: RasterRect;
|
|
1062
|
+
};
|
|
1063
|
+
/**
|
|
1064
|
+
* Replaces a live stroke's points, or moves, scales, rotates or flips them (`transform`, about
|
|
1065
|
+
* the stroke's centre unless an origin is given; the brush size scales too), and redraws its
|
|
1066
|
+
* layer (one undo step). Returns the stroke and the area that changed.
|
|
1067
|
+
*/
|
|
1068
|
+
editStrokePoints(id: string, edit: {
|
|
1069
|
+
points?: readonly PenPoint[];
|
|
1070
|
+
transform?: StrokeVariation;
|
|
1071
|
+
}): {
|
|
1072
|
+
stroke: RecordedStroke;
|
|
1073
|
+
bounds: RasterRect;
|
|
1074
|
+
};
|
|
1075
|
+
/** Deletes live strokes (one undo step). Returns the ids removed and the area that changed. */
|
|
1076
|
+
removeStrokes(ids: readonly string[]): {
|
|
1077
|
+
removed: string[];
|
|
1078
|
+
bounds: RasterRect | null;
|
|
1079
|
+
};
|
|
1080
|
+
/** Moves a live stroke to `index` in its layer (0 = bottom) and redraws (one undo step). Returns the new order. */
|
|
1081
|
+
reorderStroke(id: string, index: number): string[];
|
|
1082
|
+
/** Turns a stroke layer into a plain pixel layer with the same pixels (one undo step). */
|
|
1083
|
+
rasterizeLiveStrokes(layerId?: string): PaintLayerInfo;
|
|
1084
|
+
/** Sets a layer's live strokes and redraws it (replays). `null` makes it a plain pixel layer. */
|
|
1085
|
+
replaceLiveStrokes(layerId: string, strokes: readonly RecordedStroke[] | null): void;
|
|
1086
|
+
/**
|
|
1087
|
+
* The top-most stroke of a stroke layer (default the active layer) that painted the pixel at
|
|
1088
|
+
* (x, y) document pixels, or `null`. Strokes whose area holds the point are drawn alone, top
|
|
1089
|
+
* first, until one covers it.
|
|
1090
|
+
*/
|
|
1091
|
+
liveStrokeAt(layerId: string | undefined, x: number, y: number): RecordedStroke | null;
|
|
1092
|
+
/** Picks a stroke for the stroke panel and canvas (`null` for none). Editor state, not an undo step. */
|
|
1093
|
+
selectStroke(id: string | null): void;
|
|
1094
|
+
/** Where a live stroke painted (document pixels), or `null`. */
|
|
1095
|
+
liveStrokeArea(id: string): RasterRect | null;
|
|
1096
|
+
/** Commits a layer's new stroke list with its redrawn pixels, recorded for replays (one undo step). */
|
|
1097
|
+
private commitLiveStrokes;
|
|
1098
|
+
private withLiveStrokes;
|
|
1099
|
+
/** Where a stroke painted (document pixels): as learnt when it was painted or drawn, else an estimate from its points and brush. */
|
|
1100
|
+
private strokeArea;
|
|
1101
|
+
/** The areas strokes painted, or `null` when one is not known (a full redraw then). */
|
|
1102
|
+
private strokeAreas;
|
|
1103
|
+
/** Draws one stroke onto `surface` of a plain copy of the layer; returns the result and the area it painted. */
|
|
1104
|
+
private drawLiveStroke;
|
|
1105
|
+
/**
|
|
1106
|
+
* A stroke layer's pixels drawn from its strokes, bottom first. With `dirty` (the areas the old
|
|
1107
|
+
* strokes that changed had painted), only the tiles there and under any stroke whose area isn't
|
|
1108
|
+
* known yet are drawn again, from the strokes that reach them (a pixel depends only on the
|
|
1109
|
+
* strokes over it); the other tiles are kept. Without it, or with `null`, every stroke is drawn.
|
|
1110
|
+
*/
|
|
1111
|
+
private drawLiveStrokes;
|
|
1112
|
+
/** The view's layers: stroke layers playing live effects at `effectTime`, the rest as they are. */
|
|
1113
|
+
private animatedView;
|
|
1114
|
+
/** Stroke layers with live effect strokes, and the distinct live sources (frame 0). */
|
|
1115
|
+
private liveEffects;
|
|
1116
|
+
/** What plays: the live effect strokes and their layers, or `null` when nothing does. */
|
|
1117
|
+
getAnimation(): {
|
|
1118
|
+
layerIds: string[];
|
|
1119
|
+
strokes: number;
|
|
1120
|
+
sources: number;
|
|
1121
|
+
} | null;
|
|
1122
|
+
/** Plays or pauses live effect paint, and caps its frame rate (1..60). Editor state, not an undo step. */
|
|
1123
|
+
setEffectPlayback(update: {
|
|
1124
|
+
playing?: boolean;
|
|
1125
|
+
fps?: number;
|
|
1126
|
+
}): {
|
|
1127
|
+
playing: boolean;
|
|
1128
|
+
fps: number;
|
|
1129
|
+
time: number;
|
|
1130
|
+
};
|
|
1131
|
+
/** The surfaces of every stroke layer with live effects at `time` ms, drawn in full (frames rendered first). */
|
|
1132
|
+
private liveSurfacesAt;
|
|
1133
|
+
/**
|
|
1134
|
+
* Shows the live effects at `time` ms (each live stroke's effect at its own time plus `time`):
|
|
1135
|
+
* renders their frames, then redraws only where live effect strokes paint. Nothing in the
|
|
1136
|
+
* document changes. Resolves `false` when the document changed while frames rendered (the next
|
|
1137
|
+
* frame catches up).
|
|
1138
|
+
*/
|
|
1139
|
+
showEffectTime(time: number): Promise<boolean>;
|
|
1140
|
+
/**
|
|
1141
|
+
* Plays live effect paint in the view until `stop`: a frame per tick of `clock` (default
|
|
1142
|
+
* animation frames) at most `fps` a second, one render in flight. Idle while paused, while a
|
|
1143
|
+
* stroke is painted, or when nothing is live. The bindings start it while the editor is shown.
|
|
1144
|
+
*/
|
|
1145
|
+
playEffects(clock?: {
|
|
1146
|
+
now(): number;
|
|
1147
|
+
frame(cb: () => void): () => void;
|
|
1148
|
+
}): {
|
|
1149
|
+
stop(): void;
|
|
1150
|
+
};
|
|
1151
|
+
/**
|
|
1152
|
+
* Runs `fn` with the painting as it is `time` ms into its live effects (see `getAnimation`): for
|
|
1153
|
+
* exports at a moment. Nothing in the document changes.
|
|
1154
|
+
*/
|
|
1155
|
+
withEffectTime<T>(time: number, fn: () => T | Promise<T>): Promise<T>;
|
|
1156
|
+
/** The painting composited `time` ms into its live effects, like `compositePixels`. Nothing in the document changes. */
|
|
1157
|
+
renderAnimationFrame(time: number, options?: RenderOptions): Promise<PixelImage>;
|
|
1003
1158
|
private stencilCache;
|
|
1004
1159
|
private nextStencilId;
|
|
1005
1160
|
/** The mask stencils' coverage over the canvas (cached), or `null` when none masks. */
|
|
@@ -1074,3 +1229,5 @@ export declare class PaintEditorController {
|
|
|
1074
1229
|
export type { Tile };
|
|
1075
1230
|
/** Largest tracing or reference image side, in pixels. */
|
|
1076
1231
|
export declare const MAX_IMAGE_SIDE = 8192;
|
|
1232
|
+
/** The most live effects (distinct sources) a document plays at once: each needs a renderer. */
|
|
1233
|
+
export declare const MAX_LIVE_EFFECT_SOURCES = 8;
|
|
@@ -43,6 +43,11 @@ export interface PaintDocumentState {
|
|
|
43
43
|
paintEvents?: PaintEvent[];
|
|
44
44
|
/** Sticker layers: each layer's stickers, bottom first (its pixels are drawn from them). */
|
|
45
45
|
stickers?: Readonly<Record<string, Sticker[]>>;
|
|
46
|
+
/**
|
|
47
|
+
* Live stroke layers: each layer's strokes, bottom first. Its pixels are drawn from them, so each
|
|
48
|
+
* stroke's brush, colour and points stay editable (`updateStroke`).
|
|
49
|
+
*/
|
|
50
|
+
liveStrokes?: Readonly<Record<string, RecordedStroke[]>>;
|
|
46
51
|
/** Thick paint: each layer's height and material channels (layers without relief are missing). */
|
|
47
52
|
thick?: Readonly<Record<string, ThickChannels>>;
|
|
48
53
|
/** Effect layers: the provider effect each one is drawn from (layers that are gone are ignored). */
|
|
@@ -61,9 +66,9 @@ export interface PaintDocumentState {
|
|
|
61
66
|
/** A change a replay repeats besides strokes, recorded with how many strokes came before it. */
|
|
62
67
|
export interface PaintEvent {
|
|
63
68
|
at: number;
|
|
64
|
-
kind: 'fill' | 'clear' | 'flatten' | 'stickers';
|
|
69
|
+
kind: 'fill' | 'clear' | 'flatten' | 'stickers' | 'live-strokes';
|
|
65
70
|
layerId: string;
|
|
66
|
-
/** The fill's options (colour, opacity, grain, pressure, blend), or the layer's stickers after an edit. */
|
|
71
|
+
/** The fill's options (colour, opacity, grain, pressure, blend), or the layer's stickers or live strokes after an edit. */
|
|
67
72
|
data?: Record<string, unknown>;
|
|
68
73
|
}
|
|
69
74
|
/** A new layer id, unique in this session. */
|
|
@@ -43,6 +43,11 @@ export interface PaintDocumentState {
|
|
|
43
43
|
paintEvents?: PaintEvent[];
|
|
44
44
|
/** Sticker layers: each layer's stickers, bottom first (its pixels are drawn from them). */
|
|
45
45
|
stickers?: Readonly<Record<string, Sticker[]>>;
|
|
46
|
+
/**
|
|
47
|
+
* Live stroke layers: each layer's strokes, bottom first. Its pixels are drawn from them, so each
|
|
48
|
+
* stroke's brush, colour and points stay editable (`updateStroke`).
|
|
49
|
+
*/
|
|
50
|
+
liveStrokes?: Readonly<Record<string, RecordedStroke[]>>;
|
|
46
51
|
/** Thick paint: each layer's height and material channels (layers without relief are missing). */
|
|
47
52
|
thick?: Readonly<Record<string, ThickChannels>>;
|
|
48
53
|
/** Effect layers: the provider effect each one is drawn from (layers that are gone are ignored). */
|
|
@@ -61,9 +66,9 @@ export interface PaintDocumentState {
|
|
|
61
66
|
/** A change a replay repeats besides strokes, recorded with how many strokes came before it. */
|
|
62
67
|
export interface PaintEvent {
|
|
63
68
|
at: number;
|
|
64
|
-
kind: 'fill' | 'clear' | 'flatten' | 'stickers';
|
|
69
|
+
kind: 'fill' | 'clear' | 'flatten' | 'stickers' | 'live-strokes';
|
|
65
70
|
layerId: string;
|
|
66
|
-
/** The fill's options (colour, opacity, grain, pressure, blend), or the layer's stickers after an edit. */
|
|
71
|
+
/** The fill's options (colour, opacity, grain, pressure, blend), or the layer's stickers or live strokes after an edit. */
|
|
67
72
|
data?: Record<string, unknown>;
|
|
68
73
|
}
|
|
69
74
|
/** A new layer id, unique in this session. */
|
|
@@ -24,12 +24,59 @@ export interface PaintEffectPaint {
|
|
|
24
24
|
values: Record<string, EffectValue>;
|
|
25
25
|
/** Which moment of an animated effect, in ms. */
|
|
26
26
|
time: number;
|
|
27
|
+
/**
|
|
28
|
+
* How the effect lies on the paint: fixed to the canvas (missing, the default), or along each
|
|
29
|
+
* stroke (`by: 'stroke'`): the effect is rendered as a strip `length` px long and 256 px across,
|
|
30
|
+
* and each pixel takes the colour at (distance along the stroke, position across the tip).
|
|
31
|
+
*/
|
|
32
|
+
map?: PaintEffectStrokeMap;
|
|
33
|
+
/**
|
|
34
|
+
* Live: on a stroke layer the stroke keeps playing the effect (each frame drawn at the editor's
|
|
35
|
+
* effect time); elsewhere it bakes the frame at `time` like any effect paint.
|
|
36
|
+
*/
|
|
37
|
+
live?: boolean;
|
|
27
38
|
}
|
|
28
|
-
/**
|
|
39
|
+
/** Effect paint laid along the stroke. */
|
|
40
|
+
export interface PaintEffectStrokeMap {
|
|
41
|
+
by: 'stroke';
|
|
42
|
+
/** Strip length: px of stroke per repeat of the effect, 16..4096. */
|
|
43
|
+
length: number;
|
|
44
|
+
/** Past the strip's end: start again, run back (mirror), or hold the last colour (clamp). */
|
|
45
|
+
repeat: 'repeat' | 'mirror' | 'clamp';
|
|
46
|
+
}
|
|
47
|
+
/** How tall a stroke-mapped effect strip is rendered (the position across the tip maps onto it). */
|
|
48
|
+
export declare const EFFECT_STRIP_HEIGHT = 256;
|
|
49
|
+
export declare const EFFECT_MAP_REPEATS: readonly ["repeat", "mirror", "clamp"];
|
|
50
|
+
/** The size an effect paint renders at: the canvas, or its strip. */
|
|
51
|
+
export declare function effectPaintSize(p: PaintEffectPaint, canvas: {
|
|
52
|
+
width: number;
|
|
53
|
+
height: number;
|
|
54
|
+
}): {
|
|
55
|
+
width: number;
|
|
56
|
+
height: number;
|
|
57
|
+
};
|
|
58
|
+
/** A stroke map checked and rounded; throws a sentence naming the bad field. */
|
|
59
|
+
export declare function readEffectStrokeMap(raw: unknown): PaintEffectStrokeMap | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Straight-alpha RGBA an effect paint was rendered to: canvas-sized, or (with `map`) the strip
|
|
62
|
+
* laid along each stroke.
|
|
63
|
+
*/
|
|
29
64
|
export interface EffectPaintPixels {
|
|
30
65
|
width: number;
|
|
31
66
|
height: number;
|
|
32
67
|
data: ArrayLike<number>;
|
|
68
|
+
map?: PaintEffectStrokeMap;
|
|
69
|
+
}
|
|
70
|
+
/** Where a dab is on its stroke, for effect paint laid along the stroke. */
|
|
71
|
+
export interface EffectDabPlace {
|
|
72
|
+
x: number;
|
|
73
|
+
y: number;
|
|
74
|
+
/** Direction of travel, radians counter-clockwise with y up. */
|
|
75
|
+
direction: number;
|
|
76
|
+
/** The tip's radius (px): the position across the tip maps onto the strip's height. */
|
|
77
|
+
radius: number;
|
|
78
|
+
/** Path length (px) travelled to the dab. */
|
|
79
|
+
travel: number;
|
|
33
80
|
}
|
|
34
81
|
/** The cache key of an effect paint (the same source renders the same pixels). */
|
|
35
82
|
export declare function effectPaintKey(p: PaintEffectPaint): string;
|
|
@@ -42,6 +89,16 @@ export declare function readPaintEffectPaint(raw: unknown): PaintEffectPaint | n
|
|
|
42
89
|
* document rectangle) with the effect's colour at each pixel and multiplies `vals` by its alpha.
|
|
43
90
|
* Pixels off the canvas paint nothing.
|
|
44
91
|
*/
|
|
45
|
-
export declare function sampleEffectField(img: EffectPaintPixels, rect: RasterRect, vals: Float32Array, field: Float32Array): void;
|
|
92
|
+
export declare function sampleEffectField(img: EffectPaintPixels, rect: RasterRect, vals: Float32Array, field: Float32Array, dab?: EffectDabPlace | null): void;
|
|
46
93
|
/** The effect's colour (sRGB 0..1 into `out`) at a document point; returns its alpha 0..1 (0 off the canvas). */
|
|
47
|
-
export declare function sampleEffectAt(img: EffectPaintPixels, x: number, y: number, out: [number, number, number]): number;
|
|
94
|
+
export declare function sampleEffectAt(img: EffectPaintPixels, x: number, y: number, out: [number, number, number], dab?: EffectDabPlace | null): number;
|
|
95
|
+
/**
|
|
96
|
+
* Effect colours for one dab of a brush that mixes paint (wet and impasto brushes): fills `field`
|
|
97
|
+
* (sRGB 0..1, 3 per pixel of `rect`) with the effect's colour at each pixel, shifted by how far the
|
|
98
|
+
* brush's mixed paint (`mixed`) moved from the effect's colour at the dab's centre (`centre`, which
|
|
99
|
+
* the brush was loaded with), so paint the brush picked up still drags through the pattern. A clean
|
|
100
|
+
* brush paints the effect's colours exactly. `cov` is multiplied by the effect's alpha, rounded to
|
|
101
|
+
* `steps` levels when given (wet paint keeps its coverage on fixed steps so replays are exact).
|
|
102
|
+
* `dab` places it on its stroke, for effect paint laid along the stroke.
|
|
103
|
+
*/
|
|
104
|
+
export declare function effectDabField(img: EffectPaintPixels, rect: RasterRect, cov: Float32Array, centre: readonly [number, number, number], mixed: readonly [number, number, number], field: Float32Array, steps?: number, dab?: EffectDabPlace | null): void;
|