@pixerate/editor 0.240.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.
Files changed (37) hide show
  1. package/dist/animation-editor/index.cjs +58 -58
  2. package/dist/animation-editor/index.js +3 -3
  3. package/dist/{brushstrokeRender-WB67GMUP.js → brushstrokeRender-MOYGEXOC.js} +2 -2
  4. package/dist/{brushstrokeRender-MPOM7BFW.cjs → brushstrokeRender-UKADOV5D.cjs} +5 -5
  5. package/dist/canvas/index.cjs +8 -8
  6. package/dist/canvas/index.js +1 -1
  7. package/dist/{chunk-NKTNLJUJ.cjs → chunk-5BR7LC24.cjs} +99 -11
  8. package/dist/{chunk-ZXNO3ZOX.cjs → chunk-7F4G74UQ.cjs} +35 -35
  9. package/dist/{chunk-AD7GA3TL.cjs → chunk-AFLMXITL.cjs} +23 -23
  10. package/dist/{chunk-PP6BXVRL.cjs → chunk-HGGJ36HR.cjs} +1 -1
  11. package/dist/{chunk-BBUE3UJL.cjs → chunk-HW72ABGR.cjs} +86 -86
  12. package/dist/{chunk-7YGBSFC6.js → chunk-ILM6GYAX.js} +1 -1
  13. package/dist/{chunk-THXFU3JB.cjs → chunk-KCMV2534.cjs} +2 -2
  14. package/dist/{chunk-3E36VDMJ.js → chunk-NE6OOKWJ.js} +1 -1
  15. package/dist/{chunk-RV5DKZHU.js → chunk-QP2B3MID.js} +1 -1
  16. package/dist/{chunk-UUBO6RB5.js → chunk-UDBDYZET.js} +1 -1
  17. package/dist/{chunk-PJYG6FCF.js → chunk-XBZK47LV.js} +98 -10
  18. package/dist/{chunk-XK4SST43.js → chunk-ZDPLZDTT.js} +1 -1
  19. package/dist/image-editor/index.cjs +775 -775
  20. package/dist/image-editor/index.js +4 -4
  21. package/dist/paint-editor/controller.d.cts +67 -0
  22. package/dist/paint-editor/controller.d.ts +67 -0
  23. package/dist/paint-editor/effect-paint.d.cts +60 -3
  24. package/dist/paint-editor/effect-paint.d.ts +60 -3
  25. package/dist/paint-editor/index.cjs +676 -430
  26. package/dist/paint-editor/index.js +282 -36
  27. package/dist/paint-editor/stickers.d.cts +6 -0
  28. package/dist/paint-editor/stickers.d.ts +6 -0
  29. package/dist/paint-editor/thick.d.cts +4 -0
  30. package/dist/paint-editor/thick.d.ts +4 -0
  31. package/dist/paint-editor/wet.d.cts +8 -0
  32. package/dist/paint-editor/wet.d.ts +8 -0
  33. package/dist/vector/index.cjs +962 -962
  34. package/dist/vector/index.js +4 -4
  35. package/package.json +1 -1
  36. package/skills/pixerate-paint-editor/SKILL.md +17 -21
  37. 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-UUBO6RB5.js";
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-3E36VDMJ.js";
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-7YGBSFC6.js";
733
- import "../chunk-PJYG6FCF.js";
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,12 @@ 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
+ };
115
121
  /** The stroke picked on a stroke layer, on the canvas or in the stroke panel (editor state, not an undo step). */
116
122
  selectedStroke: string | null;
117
123
  /** The sticker picked on the canvas or in the sticker panel (editor state, not an undo step). */
@@ -308,6 +314,15 @@ export declare class PaintEditorController {
308
314
  private dirty;
309
315
  private seedCounter;
310
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;
311
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`). */
312
327
  private paintedBounds;
313
328
  private guides;
@@ -559,11 +574,15 @@ export declare class PaintEditorController {
559
574
  * size, and brushes then take each pixel's colour (and alpha) from it, fixed to the canvas, as if
560
575
  * painting a hidden picture into view. `setColor` and `setPaint` go back to colour. Editor state,
561
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`).
562
579
  */
563
580
  setEffectPaint(source: {
564
581
  effect: string;
565
582
  values?: Record<string, EffectValue | null>;
566
583
  time?: number;
584
+ map?: unknown;
585
+ live?: boolean;
567
586
  }): Promise<PaintEffectPaint>;
568
587
  /** The rendered pixels of an effect paint at the current canvas size, or `null` when it has not been rendered. */
569
588
  private effectPaintImage;
@@ -1090,6 +1109,52 @@ export declare class PaintEditorController {
1090
1109
  * strokes over it); the other tiles are kept. Without it, or with `null`, every stroke is drawn.
1091
1110
  */
1092
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>;
1093
1158
  private stencilCache;
1094
1159
  private nextStencilId;
1095
1160
  /** The mask stencils' coverage over the canvas (cached), or `null` when none masks. */
@@ -1164,3 +1229,5 @@ export declare class PaintEditorController {
1164
1229
  export type { Tile };
1165
1230
  /** Largest tracing or reference image side, in pixels. */
1166
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,12 @@ 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
+ };
115
121
  /** The stroke picked on a stroke layer, on the canvas or in the stroke panel (editor state, not an undo step). */
116
122
  selectedStroke: string | null;
117
123
  /** The sticker picked on the canvas or in the sticker panel (editor state, not an undo step). */
@@ -308,6 +314,15 @@ export declare class PaintEditorController {
308
314
  private dirty;
309
315
  private seedCounter;
310
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;
311
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`). */
312
327
  private paintedBounds;
313
328
  private guides;
@@ -559,11 +574,15 @@ export declare class PaintEditorController {
559
574
  * size, and brushes then take each pixel's colour (and alpha) from it, fixed to the canvas, as if
560
575
  * painting a hidden picture into view. `setColor` and `setPaint` go back to colour. Editor state,
561
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`).
562
579
  */
563
580
  setEffectPaint(source: {
564
581
  effect: string;
565
582
  values?: Record<string, EffectValue | null>;
566
583
  time?: number;
584
+ map?: unknown;
585
+ live?: boolean;
567
586
  }): Promise<PaintEffectPaint>;
568
587
  /** The rendered pixels of an effect paint at the current canvas size, or `null` when it has not been rendered. */
569
588
  private effectPaintImage;
@@ -1090,6 +1109,52 @@ export declare class PaintEditorController {
1090
1109
  * strokes over it); the other tiles are kept. Without it, or with `null`, every stroke is drawn.
1091
1110
  */
1092
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>;
1093
1158
  private stencilCache;
1094
1159
  private nextStencilId;
1095
1160
  /** The mask stencils' coverage over the canvas (cached), or `null` when none masks. */
@@ -1164,3 +1229,5 @@ export declare class PaintEditorController {
1164
1229
  export type { Tile };
1165
1230
  /** Largest tracing or reference image side, in pixels. */
1166
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;
@@ -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
- /** Canvas-sized straight-alpha RGBA an effect paint was rendered to. */
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;
@@ -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
- /** Canvas-sized straight-alpha RGBA an effect paint was rendered to. */
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;