@pixerate/editor 0.275.1 → 0.276.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 +62 -62
- package/dist/animation-editor/index.js +6 -6
- package/dist/brushes/index.cjs +81 -70
- package/dist/brushes/index.js +17 -6
- package/dist/brushes/patch.d.cts +1 -1
- package/dist/brushes/patch.d.ts +1 -1
- package/dist/brushes/profiles.d.cts +2 -0
- package/dist/brushes/profiles.d.ts +2 -0
- package/dist/brushes/schema.d.cts +1 -0
- package/dist/brushes/schema.d.ts +1 -0
- package/dist/brushes/types.d.cts +22 -1
- package/dist/brushes/types.d.ts +22 -1
- package/dist/{brushstrokeRender-WGY4DZHF.js → brushstrokeRender-FK3ASUUJ.js} +5 -5
- package/dist/{brushstrokeRender-2RQL46WB.cjs → brushstrokeRender-I6MYFCOU.cjs} +21 -21
- package/dist/canvas/index.cjs +13 -13
- package/dist/canvas/index.js +1 -1
- package/dist/{chunk-Y2ISSVPH.js → chunk-4EM5NGCL.js} +167 -9
- package/dist/{chunk-Y354ETAE.cjs → chunk-5HR5CSLC.cjs} +49 -49
- package/dist/{chunk-LMG57L5A.js → chunk-CTHWXW5M.js} +121 -8
- package/dist/{chunk-43XJC3PP.js → chunk-CVBTJVRN.js} +1 -1
- package/dist/{chunk-RJGW3RQS.js → chunk-GHYJAMMS.js} +1 -1
- package/dist/{chunk-NIBFKXMD.cjs → chunk-IFWLZZCW.cjs} +619 -2
- package/dist/{chunk-G5TCMKX5.js → chunk-IJ6NSWKM.js} +2 -2
- package/dist/{chunk-C6VB7CPY.cjs → chunk-ISCAJBPQ.cjs} +1 -1
- package/dist/{chunk-W6JDUXP3.js → chunk-J23JOHPR.js} +1 -1
- package/dist/{chunk-IEEY5RJV.js → chunk-JNMNM3SL.js} +1 -1
- package/dist/{chunk-HVO6XCI4.js → chunk-JPB65KQ6.js} +1 -1
- package/dist/{chunk-ACTHSQOI.js → chunk-LDZOXESA.js} +618 -1
- package/dist/{chunk-DHC4E2DU.cjs → chunk-MITQGHN3.cjs} +121 -8
- package/dist/{chunk-STLTOISW.cjs → chunk-NPPMKMCU.cjs} +17 -17
- package/dist/{chunk-75SYKUOT.js → chunk-OS6OG7DN.js} +1 -1
- package/dist/{chunk-OLZXXAER.cjs → chunk-OY24XRYF.cjs} +408 -250
- package/dist/{chunk-6QNDGMK7.cjs → chunk-Q33V5PEF.cjs} +123 -42
- package/dist/{chunk-JDXWLCXF.cjs → chunk-QNNZA3V5.cjs} +2 -2
- package/dist/{chunk-T6KNJVBP.cjs → chunk-U26LUXCJ.cjs} +35 -35
- package/dist/{chunk-62MFUHSI.cjs → chunk-UQXULAMQ.cjs} +16 -16
- package/dist/{chunk-RAPNRK4R.cjs → chunk-X7XBEX3O.cjs} +88 -88
- package/dist/{chunk-MSWLJI4G.js → chunk-XMSH66VU.js} +2 -2
- package/dist/{chunk-ZM7IKQ4X.js → chunk-XVPQNX7O.js} +89 -8
- package/dist/{chunk-YYZC2EQO.cjs → chunk-ZIE6EJGR.cjs} +23 -23
- package/dist/image-editor/index.cjs +880 -852
- package/dist/image-editor/index.js +36 -8
- package/dist/paint/index.cjs +33 -5
- package/dist/paint/index.d.cts +1 -0
- package/dist/paint/index.d.ts +1 -0
- package/dist/paint/index.js +32 -4
- package/dist/paint/live-patterns.d.cts +149 -0
- package/dist/paint/live-patterns.d.ts +149 -0
- package/dist/paint/wet/world.d.cts +13 -0
- package/dist/paint/wet/world.d.ts +13 -0
- package/dist/paint-editor/brush-model.d.cts +7 -1
- package/dist/paint-editor/brush-model.d.ts +7 -1
- package/dist/paint-editor/controller.d.cts +52 -0
- package/dist/paint-editor/controller.d.ts +52 -0
- package/dist/paint-editor/index.cjs +850 -510
- package/dist/paint-editor/index.js +355 -15
- package/dist/paint-editor/ui.d.cts +5 -1
- package/dist/paint-editor/ui.d.ts +5 -1
- package/dist/paint-editor/wet-tools.d.cts +42 -0
- package/dist/paint-editor/wet-tools.d.ts +42 -0
- package/dist/paint-editor/wet.d.cts +22 -1
- package/dist/paint-editor/wet.d.ts +22 -1
- package/dist/vector/index.cjs +1002 -1002
- package/dist/vector/index.js +7 -7
- package/package.json +1 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live patterns: Gray-Scott reaction-diffusion fields `(U, V)` that grow inside wet paint and
|
|
3
|
+
* freeze where the paint dries.
|
|
4
|
+
*
|
|
5
|
+
* Each wet layer with live patterns active holds a sparse set of half-resolution (`128 × 128`)
|
|
6
|
+
* pattern tiles paired with the `256 × 256` tiles of `WetWorld`, outside the wet-media LBM kernel.
|
|
7
|
+
* Every wet simulation step runs Gray-Scott substeps gated by the wet layer's water (`P_RHO` +
|
|
8
|
+
* `P_SW > DRY_EPS`): where water remains, `U` and `V` react and diffuse into Turing spots,
|
|
9
|
+
* stripes, coral dendrites, mazes or worms; where the paint has dried, the reaction and diffusion
|
|
10
|
+
* rates drop to zero so the pattern freezes in place.
|
|
11
|
+
*/
|
|
12
|
+
import { TiledSurface, type RasterRect } from '../raster/surface.js';
|
|
13
|
+
/** Side length of one half-resolution pattern tile (`WET_TILE / 2`). */
|
|
14
|
+
export declare const PATTERN_TILE = 128;
|
|
15
|
+
/** Cells per pattern tile (`128 × 128`). */
|
|
16
|
+
export declare const PATTERN_CELLS: number;
|
|
17
|
+
/** Gray-Scott substeps run for each wet simulation step. */
|
|
18
|
+
export declare const PATTERN_SUBSTEPS = 4;
|
|
19
|
+
/** Threshold of `V` above which a cell counts as pattern-bearing in stats and relief. */
|
|
20
|
+
export declare const PATTERN_V_EPS = 0.02;
|
|
21
|
+
/** Named Gray-Scott Pearson pattern presets. */
|
|
22
|
+
export declare const LIVE_PATTERN_KINDS: readonly ["spots", "stripes", "coral", "maze", "worms"];
|
|
23
|
+
export type LivePatternKind = (typeof LIVE_PATTERN_KINDS)[number];
|
|
24
|
+
export interface LivePatternPresetInfo {
|
|
25
|
+
readonly kind: LivePatternKind;
|
|
26
|
+
readonly label: string;
|
|
27
|
+
readonly description: string;
|
|
28
|
+
readonly feed: number;
|
|
29
|
+
readonly kill: number;
|
|
30
|
+
}
|
|
31
|
+
/** Built-in Pearson (1993) feed / kill parameter presets. */
|
|
32
|
+
export declare const LIVE_PATTERN_PRESETS: Readonly<Record<LivePatternKind, LivePatternPresetInfo>>;
|
|
33
|
+
/** Resolved live-pattern parameters for a brush or wet layer. */
|
|
34
|
+
export interface LivePatternsSettings {
|
|
35
|
+
/** Named Gray-Scott preset (`spots`, `stripes`, `coral`, `maze`, `worms`). */
|
|
36
|
+
pattern: LivePatternKind;
|
|
37
|
+
/** Gray-Scott feed rate F (0.01..0.1). */
|
|
38
|
+
feed: number;
|
|
39
|
+
/** Gray-Scott kill rate k (0.03..0.08). */
|
|
40
|
+
kill: number;
|
|
41
|
+
/** Pattern feature scale (0.5..4, default 1). Scales the diffusion rates. */
|
|
42
|
+
scale: number;
|
|
43
|
+
/** Visual contrast of the V concentration field (0..2, default 1). */
|
|
44
|
+
contrast: number;
|
|
45
|
+
/** Optional hex colour (`#rrggbb`) that V blends the wet paint towards; `null` modulates pigment contrast. */
|
|
46
|
+
secondColor: string | null;
|
|
47
|
+
/** Impasto relief written to the layer's thick height map as patterns grow (0..1, default 0). */
|
|
48
|
+
relief: number;
|
|
49
|
+
}
|
|
50
|
+
export type LivePatternsInput = Partial<LivePatternsSettings>;
|
|
51
|
+
export declare const DEFAULT_LIVE_PATTERNS: Readonly<LivePatternsSettings>;
|
|
52
|
+
export declare function isLivePatternKind(v: unknown): v is LivePatternKind;
|
|
53
|
+
/** Normalizes a hex colour string (`#rgb` or `#rrggbb`) to lowercase `#rrggbb`, or `null`. */
|
|
54
|
+
export declare function normalizePatternHexColor(v: unknown, fallback?: string | null): string | null;
|
|
55
|
+
/** Parses a `#rrggbb` colour to `[r, g, b]` bytes, or `null`. */
|
|
56
|
+
export declare function parsePatternHexColor(hex: string | null): [number, number, number] | null;
|
|
57
|
+
/** Clamps and fills a `LivePatternsSettings` object from partial input. */
|
|
58
|
+
export declare function normalizeLivePatterns(raw?: LivePatternsInput | null | undefined, base?: LivePatternsSettings): LivePatternsSettings;
|
|
59
|
+
/** Deterministic 32-bit integer hash in `[0, 1)` shared between TypeScript and Swift. */
|
|
60
|
+
export declare function patternNoise(gx: number, gy: number, seed: number): number;
|
|
61
|
+
/** Summary statistics for one wet layer's Gray-Scott field. */
|
|
62
|
+
export interface LivePatternStats {
|
|
63
|
+
/** Whether live patterns are enabled on this layer. */
|
|
64
|
+
enabled: boolean;
|
|
65
|
+
/** Current Gray-Scott reaction-diffusion settings for this layer. */
|
|
66
|
+
settings: LivePatternsSettings;
|
|
67
|
+
/** Half-resolution (`128 × 128`) tiles currently holding pattern state. */
|
|
68
|
+
activeTiles: number;
|
|
69
|
+
/** Pattern cells (`2 × 2` px each) where `V >= PATTERN_V_EPS`. */
|
|
70
|
+
patternCells: number;
|
|
71
|
+
/** Pattern cells where `V >= PATTERN_V_EPS` that are still wet (actively growing). */
|
|
72
|
+
wetPatternCells: number;
|
|
73
|
+
/** Mean `V` concentration across active pattern cells (0..1). */
|
|
74
|
+
meanV: number;
|
|
75
|
+
/** Peak `V` concentration across the layer (0..1). */
|
|
76
|
+
maxV: number;
|
|
77
|
+
/** Document pixel bounding box of active pattern cells, or `null` when none. */
|
|
78
|
+
bounds: RasterRect | null;
|
|
79
|
+
}
|
|
80
|
+
export interface LivePatternTileState {
|
|
81
|
+
readonly u: Float64Array;
|
|
82
|
+
readonly v: Float64Array;
|
|
83
|
+
readonly bakedV: Float64Array;
|
|
84
|
+
}
|
|
85
|
+
export interface LivePatternFieldSnapshot {
|
|
86
|
+
readonly settings: LivePatternsSettings;
|
|
87
|
+
readonly enabled: boolean;
|
|
88
|
+
readonly tiles: ReadonlyMap<number, LivePatternTileState>;
|
|
89
|
+
readonly bytes: number;
|
|
90
|
+
}
|
|
91
|
+
/** Callback returning whether a half-res pattern cell `(tx, ty, lx, ly)` still holds water. */
|
|
92
|
+
export type WetCellPredicate = (tx: number, ty: number, lx: number, ly: number) => boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Per-wet-layer Gray-Scott reaction-diffusion field `(U, V)` stored in `128 × 128` tiles.
|
|
95
|
+
*/
|
|
96
|
+
export declare class LivePatternField {
|
|
97
|
+
width: number;
|
|
98
|
+
height: number;
|
|
99
|
+
tilesX: number;
|
|
100
|
+
tilesY: number;
|
|
101
|
+
settings: LivePatternsSettings;
|
|
102
|
+
enabled: boolean;
|
|
103
|
+
readonly tiles: Map<number, {
|
|
104
|
+
u: Float64Array;
|
|
105
|
+
v: Float64Array;
|
|
106
|
+
bakedV: Float64Array;
|
|
107
|
+
}>;
|
|
108
|
+
constructor(width: number, height: number, settings?: LivePatternsInput);
|
|
109
|
+
resize(width: number, height: number): void;
|
|
110
|
+
configure(settings: LivePatternsInput): LivePatternsSettings;
|
|
111
|
+
clear(): void;
|
|
112
|
+
private ensureTile;
|
|
113
|
+
/**
|
|
114
|
+
* Seeds Gray-Scott reagent `V` inside a circle at document coordinates `(cx, cy)` with document
|
|
115
|
+
* `radius` (pixels). Returns the number of half-resolution cells seeded.
|
|
116
|
+
*/
|
|
117
|
+
seedDisc(cx: number, cy: number, radius: number, seed?: number, strength?: number): number;
|
|
118
|
+
/**
|
|
119
|
+
* Advances the Gray-Scott reaction-diffusion field for `wetSteps` wet simulation steps.
|
|
120
|
+
* Only cells where `isWetCell(tx, ty, lx, ly)` is true update; dry cells have zero rate and freeze.
|
|
121
|
+
* Returns whether any cell updated.
|
|
122
|
+
*/
|
|
123
|
+
step(wetSteps: number, isWetCell: WetCellPredicate, canWakeTile?: (tx: number, ty: number) => boolean): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Bilinearly samples unbaked `V` (`max(0, v - bakedV)`) at document-tile pixel `(x, y)` in `0..255`.
|
|
126
|
+
*/
|
|
127
|
+
private sampleUnbakedV;
|
|
128
|
+
/**
|
|
129
|
+
* Blends the pattern's `V` concentration into a shaded `256 × 256` RGBA wet tile `out`.
|
|
130
|
+
* Returns whether any pixel in `out` was modified.
|
|
131
|
+
*/
|
|
132
|
+
shadeTile(tx: number, ty: number, out: Uint8ClampedArray, w: number, h: number): boolean;
|
|
133
|
+
/** Marks a tile's current `V` values as baked into the layer's base surface so they are not baked twice. */
|
|
134
|
+
markBaked(tx: number, ty: number): void;
|
|
135
|
+
/**
|
|
136
|
+
* When `settings.relief > 0`, writes pattern `V` ridges into a 1-channel thick height surface.
|
|
137
|
+
* Returns the updated height `TiledSurface`, or `currentHeight` when `relief <= 0` or nothing changed.
|
|
138
|
+
*/
|
|
139
|
+
applyReliefHeight(currentHeight: TiledSurface): TiledSurface;
|
|
140
|
+
/** Computes summary statistics of the layer's live pattern field. */
|
|
141
|
+
stats(isWetCell?: WetCellPredicate): LivePatternStats;
|
|
142
|
+
snapshot(): LivePatternFieldSnapshot;
|
|
143
|
+
restore(snap: LivePatternFieldSnapshot): void;
|
|
144
|
+
}
|
|
145
|
+
/** Shifts a `LivePatternFieldSnapshot` by `(tx0, ty0)` whole wet tiles for a resized canvas `to`. */
|
|
146
|
+
export declare function moveLivePatternSnapshot(snap: LivePatternFieldSnapshot, to: {
|
|
147
|
+
width: number;
|
|
148
|
+
height: number;
|
|
149
|
+
}, tx0: number, ty0: number): LivePatternFieldSnapshot;
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
* only feeds the display.
|
|
30
30
|
*/
|
|
31
31
|
import { TiledSurface, type RasterRect } from '../../raster/surface.cjs';
|
|
32
|
+
import { LivePatternField, type LivePatternFieldSnapshot, type LivePatternStats, type LivePatternsInput, type LivePatternsSettings } from '../live-patterns.cjs';
|
|
32
33
|
import { type WetPaper, type WetParams, type WetTilt } from './model.cjs';
|
|
33
34
|
import { type WetWorkerLayout } from './wasm.cjs';
|
|
34
35
|
import type { WetGpuEngine } from './gpu.cjs';
|
|
@@ -81,6 +82,8 @@ export interface WetLaneOptions {
|
|
|
81
82
|
flowStrength?: number;
|
|
82
83
|
/** The layer's light paint under the wet paint (one channel; default none). */
|
|
83
84
|
light?: TiledSurface | null;
|
|
85
|
+
/** Shared per-layer reaction-diffusion field outside the wet kernel. */
|
|
86
|
+
livePatterns?: LivePatternField;
|
|
84
87
|
/** Active ghost paint state on the layer, if any. */
|
|
85
88
|
ghost?: WetGhostState | null;
|
|
86
89
|
}
|
|
@@ -111,12 +114,15 @@ export interface WetSnapshot {
|
|
|
111
114
|
light?: TiledSurface;
|
|
112
115
|
lit?: boolean;
|
|
113
116
|
ghost?: WetGhostState | null;
|
|
117
|
+
livePatterns?: LivePatternFieldSnapshot;
|
|
114
118
|
}>;
|
|
115
119
|
/** Per active key: the current set and the deposit planes; and its last flags. */
|
|
116
120
|
readonly slots: ReadonlyMap<number, {
|
|
117
121
|
planes: Float32Array;
|
|
118
122
|
last: number;
|
|
119
123
|
}>;
|
|
124
|
+
/** Per-layer live-pattern snapshots (including layers whose water has already dried). */
|
|
125
|
+
readonly patterns?: ReadonlyMap<string, LivePatternFieldSnapshot>;
|
|
120
126
|
/** Bytes held. */
|
|
121
127
|
readonly bytes: number;
|
|
122
128
|
}
|
|
@@ -190,6 +196,13 @@ export declare class WetWorld {
|
|
|
190
196
|
removeLane(id: string): void;
|
|
191
197
|
getParams(id: string): WetParams;
|
|
192
198
|
setParams(id: string, params: Partial<WetParams>): WetParams;
|
|
199
|
+
getLivePatterns(id: string): LivePatternsSettings;
|
|
200
|
+
hasLivePatterns(id: string): boolean;
|
|
201
|
+
livePatternField(id: string): LivePatternField;
|
|
202
|
+
setLivePatterns(id: string, settings: LivePatternsInput): LivePatternsSettings;
|
|
203
|
+
seedLivePatterns(id: string, cx: number, cy: number, radius: number, seed?: number, strength?: number, settings?: LivePatternsInput): number;
|
|
204
|
+
livePatternStats(id: string): LivePatternStats;
|
|
205
|
+
private isPatternCellWet;
|
|
193
206
|
getTilt(): WetTilt;
|
|
194
207
|
setTilt(tilt: Partial<WetTilt>): WetTilt;
|
|
195
208
|
/** Changes the paper: heights of live tiles are refilled, rates repacked. */
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
* only feeds the display.
|
|
30
30
|
*/
|
|
31
31
|
import { TiledSurface, type RasterRect } from '../../raster/surface.js';
|
|
32
|
+
import { LivePatternField, type LivePatternFieldSnapshot, type LivePatternStats, type LivePatternsInput, type LivePatternsSettings } from '../live-patterns.js';
|
|
32
33
|
import { type WetPaper, type WetParams, type WetTilt } from './model.js';
|
|
33
34
|
import { type WetWorkerLayout } from './wasm.js';
|
|
34
35
|
import type { WetGpuEngine } from './gpu.js';
|
|
@@ -81,6 +82,8 @@ export interface WetLaneOptions {
|
|
|
81
82
|
flowStrength?: number;
|
|
82
83
|
/** The layer's light paint under the wet paint (one channel; default none). */
|
|
83
84
|
light?: TiledSurface | null;
|
|
85
|
+
/** Shared per-layer reaction-diffusion field outside the wet kernel. */
|
|
86
|
+
livePatterns?: LivePatternField;
|
|
84
87
|
/** Active ghost paint state on the layer, if any. */
|
|
85
88
|
ghost?: WetGhostState | null;
|
|
86
89
|
}
|
|
@@ -111,12 +114,15 @@ export interface WetSnapshot {
|
|
|
111
114
|
light?: TiledSurface;
|
|
112
115
|
lit?: boolean;
|
|
113
116
|
ghost?: WetGhostState | null;
|
|
117
|
+
livePatterns?: LivePatternFieldSnapshot;
|
|
114
118
|
}>;
|
|
115
119
|
/** Per active key: the current set and the deposit planes; and its last flags. */
|
|
116
120
|
readonly slots: ReadonlyMap<number, {
|
|
117
121
|
planes: Float32Array;
|
|
118
122
|
last: number;
|
|
119
123
|
}>;
|
|
124
|
+
/** Per-layer live-pattern snapshots (including layers whose water has already dried). */
|
|
125
|
+
readonly patterns?: ReadonlyMap<string, LivePatternFieldSnapshot>;
|
|
120
126
|
/** Bytes held. */
|
|
121
127
|
readonly bytes: number;
|
|
122
128
|
}
|
|
@@ -190,6 +196,13 @@ export declare class WetWorld {
|
|
|
190
196
|
removeLane(id: string): void;
|
|
191
197
|
getParams(id: string): WetParams;
|
|
192
198
|
setParams(id: string, params: Partial<WetParams>): WetParams;
|
|
199
|
+
getLivePatterns(id: string): LivePatternsSettings;
|
|
200
|
+
hasLivePatterns(id: string): boolean;
|
|
201
|
+
livePatternField(id: string): LivePatternField;
|
|
202
|
+
setLivePatterns(id: string, settings: LivePatternsInput): LivePatternsSettings;
|
|
203
|
+
seedLivePatterns(id: string, cx: number, cy: number, radius: number, seed?: number, strength?: number, settings?: LivePatternsInput): number;
|
|
204
|
+
livePatternStats(id: string): LivePatternStats;
|
|
205
|
+
private isPatternCellWet;
|
|
193
206
|
getTilt(): WetTilt;
|
|
194
207
|
setTilt(tilt: Partial<WetTilt>): WetTilt;
|
|
195
208
|
/** Changes the paper: heights of live tiles are refilled, rates repacked. */
|
|
@@ -8,7 +8,9 @@ import { type BlenderSettings, type SmudgeSettings } from '../paint/blending.cjs
|
|
|
8
8
|
import type { MixingModel } from '../paint/exchange.cjs';
|
|
9
9
|
import { type PaintGradientSource, type PaintSource } from '../paint/gradient-paint.cjs';
|
|
10
10
|
import { type MixerSettings } from '../paint/mixer.cjs';
|
|
11
|
+
import { DEFAULT_LIVE_PATTERNS, LIVE_PATTERN_KINDS, LIVE_PATTERN_PRESETS, normalizeLivePatterns, type LivePatternKind, type LivePatternsInput, type LivePatternsSettings } from '../paint/live-patterns.cjs';
|
|
11
12
|
import { type BristleSettings, type ParticleSettings, type StickerSettings } from './mark-settings.cjs';
|
|
13
|
+
export { DEFAULT_LIVE_PATTERNS, LIVE_PATTERN_KINDS, LIVE_PATTERN_PRESETS, normalizeLivePatterns, type LivePatternKind, type LivePatternsInput, type LivePatternsSettings };
|
|
12
14
|
/**
|
|
13
15
|
* How a brush makes marks: `dab` (dabs into a stroke buffer, or dab by dab through the pick-up /
|
|
14
16
|
* mix exchange when its behaviour asks for it), `eraser` (removes alpha), `mixer` (the Mixer
|
|
@@ -291,6 +293,8 @@ export interface PaintBrush {
|
|
|
291
293
|
spray: SpraySettings | null;
|
|
292
294
|
/** Dab engines: texture inside the tip (missing: none). Recorded with the stroke, source ref included, so replays match. */
|
|
293
295
|
tipGrain?: TipGrainSettings;
|
|
296
|
+
/** Wet engine: Gray-Scott reaction-diffusion pattern seeded into the wet paint (missing: none). */
|
|
297
|
+
livePatterns?: LivePatternsSettings;
|
|
294
298
|
/**
|
|
295
299
|
* The brush's own gradient paint (`@pixerate/editor/paint` `PaintGradientSource`), used instead
|
|
296
300
|
* of the editor's paint; `null` (default): the editor's paint. Stops may be `paint` / `secondary`
|
|
@@ -317,7 +321,7 @@ export interface SpraySettings {
|
|
|
317
321
|
size: number;
|
|
318
322
|
}
|
|
319
323
|
export declare const DEFAULT_SPRAY: Readonly<SpraySettings>;
|
|
320
|
-
export type PaintBrushInput = Partial<Omit<PaintBrush, 'tip' | 'dynamics' | 'mixer' | 'behavior' | 'blender' | 'smudge' | 'wet' | 'impasto' | 'particle' | 'bristle' | 'sticker' | 'paint' | 'light' | 'fluorescence' | 'thermochromic' | 'iridescence' | 'ghost' | 'mutation' | 'spray' | 'tipGrain'>> & {
|
|
324
|
+
export type PaintBrushInput = Partial<Omit<PaintBrush, 'tip' | 'dynamics' | 'mixer' | 'behavior' | 'blender' | 'smudge' | 'wet' | 'impasto' | 'particle' | 'bristle' | 'sticker' | 'paint' | 'light' | 'fluorescence' | 'thermochromic' | 'iridescence' | 'ghost' | 'mutation' | 'spray' | 'tipGrain' | 'livePatterns'>> & {
|
|
321
325
|
spray?: Partial<SpraySettings> | null;
|
|
322
326
|
/** Tip grain (`null` removes it). */
|
|
323
327
|
tipGrain?: Partial<TipGrainSettings> | null;
|
|
@@ -325,6 +329,8 @@ export type PaintBrushInput = Partial<Omit<PaintBrush, 'tip' | 'dynamics' | 'mix
|
|
|
325
329
|
ghost?: Partial<GhostSettings> | null;
|
|
326
330
|
/** Mutation paint (`null` removes it). */
|
|
327
331
|
mutation?: Partial<MutationSettings> | null;
|
|
332
|
+
/** Live reaction-diffusion patterns (`null` removes it). */
|
|
333
|
+
livePatterns?: LivePatternsInput | null;
|
|
328
334
|
light?: Partial<LightSettings>;
|
|
329
335
|
fluorescence?: Partial<FluorescenceSettings> | number;
|
|
330
336
|
thermochromic?: Partial<ThermochromicSettings>;
|
|
@@ -8,7 +8,9 @@ import { type BlenderSettings, type SmudgeSettings } from '../paint/blending.js'
|
|
|
8
8
|
import type { MixingModel } from '../paint/exchange.js';
|
|
9
9
|
import { type PaintGradientSource, type PaintSource } from '../paint/gradient-paint.js';
|
|
10
10
|
import { type MixerSettings } from '../paint/mixer.js';
|
|
11
|
+
import { DEFAULT_LIVE_PATTERNS, LIVE_PATTERN_KINDS, LIVE_PATTERN_PRESETS, normalizeLivePatterns, type LivePatternKind, type LivePatternsInput, type LivePatternsSettings } from '../paint/live-patterns.js';
|
|
11
12
|
import { type BristleSettings, type ParticleSettings, type StickerSettings } from './mark-settings.js';
|
|
13
|
+
export { DEFAULT_LIVE_PATTERNS, LIVE_PATTERN_KINDS, LIVE_PATTERN_PRESETS, normalizeLivePatterns, type LivePatternKind, type LivePatternsInput, type LivePatternsSettings };
|
|
12
14
|
/**
|
|
13
15
|
* How a brush makes marks: `dab` (dabs into a stroke buffer, or dab by dab through the pick-up /
|
|
14
16
|
* mix exchange when its behaviour asks for it), `eraser` (removes alpha), `mixer` (the Mixer
|
|
@@ -291,6 +293,8 @@ export interface PaintBrush {
|
|
|
291
293
|
spray: SpraySettings | null;
|
|
292
294
|
/** Dab engines: texture inside the tip (missing: none). Recorded with the stroke, source ref included, so replays match. */
|
|
293
295
|
tipGrain?: TipGrainSettings;
|
|
296
|
+
/** Wet engine: Gray-Scott reaction-diffusion pattern seeded into the wet paint (missing: none). */
|
|
297
|
+
livePatterns?: LivePatternsSettings;
|
|
294
298
|
/**
|
|
295
299
|
* The brush's own gradient paint (`@pixerate/editor/paint` `PaintGradientSource`), used instead
|
|
296
300
|
* of the editor's paint; `null` (default): the editor's paint. Stops may be `paint` / `secondary`
|
|
@@ -317,7 +321,7 @@ export interface SpraySettings {
|
|
|
317
321
|
size: number;
|
|
318
322
|
}
|
|
319
323
|
export declare const DEFAULT_SPRAY: Readonly<SpraySettings>;
|
|
320
|
-
export type PaintBrushInput = Partial<Omit<PaintBrush, 'tip' | 'dynamics' | 'mixer' | 'behavior' | 'blender' | 'smudge' | 'wet' | 'impasto' | 'particle' | 'bristle' | 'sticker' | 'paint' | 'light' | 'fluorescence' | 'thermochromic' | 'iridescence' | 'ghost' | 'mutation' | 'spray' | 'tipGrain'>> & {
|
|
324
|
+
export type PaintBrushInput = Partial<Omit<PaintBrush, 'tip' | 'dynamics' | 'mixer' | 'behavior' | 'blender' | 'smudge' | 'wet' | 'impasto' | 'particle' | 'bristle' | 'sticker' | 'paint' | 'light' | 'fluorescence' | 'thermochromic' | 'iridescence' | 'ghost' | 'mutation' | 'spray' | 'tipGrain' | 'livePatterns'>> & {
|
|
321
325
|
spray?: Partial<SpraySettings> | null;
|
|
322
326
|
/** Tip grain (`null` removes it). */
|
|
323
327
|
tipGrain?: Partial<TipGrainSettings> | null;
|
|
@@ -325,6 +329,8 @@ export type PaintBrushInput = Partial<Omit<PaintBrush, 'tip' | 'dynamics' | 'mix
|
|
|
325
329
|
ghost?: Partial<GhostSettings> | null;
|
|
326
330
|
/** Mutation paint (`null` removes it). */
|
|
327
331
|
mutation?: Partial<MutationSettings> | null;
|
|
332
|
+
/** Live reaction-diffusion patterns (`null` removes it). */
|
|
333
|
+
livePatterns?: LivePatternsInput | null;
|
|
328
334
|
light?: Partial<LightSettings>;
|
|
329
335
|
fluorescence?: Partial<FluorescenceSettings> | number;
|
|
330
336
|
thermochromic?: Partial<ThermochromicSettings>;
|
|
@@ -50,6 +50,7 @@ import { PaintWetLayers, type PaintWetOptions, type WetEngineInfo, type WetGpuMo
|
|
|
50
50
|
import { type WetParams, type WetTilt } from '../paint/wet/model.cjs';
|
|
51
51
|
import { type WetFlowSpec } from '../paint/wet/flow.cjs';
|
|
52
52
|
import { type WetBackendInfo } from '../paint/wet/world.cjs';
|
|
53
|
+
import { type LivePatternKind, type LivePatternStats, type LivePatternsInput } from '../paint/live-patterns.cjs';
|
|
53
54
|
import { type TimeLapse, type TimeLapseOptions } from './replay.cjs';
|
|
54
55
|
import { EffectsSlot } from '../effects/helpers.cjs';
|
|
55
56
|
import type { EffectDescription, EffectProvider, EffectValue } from '../effects/types.cjs';
|
|
@@ -121,6 +122,13 @@ export interface PaintWetStateInfo {
|
|
|
121
122
|
/** Engine B is shading the wet paint now. */
|
|
122
123
|
gpuActive: boolean;
|
|
123
124
|
}
|
|
125
|
+
/** One layer's Gray-Scott live-pattern state and wet coverage. */
|
|
126
|
+
export interface PaintLayerLivePatternsInfo extends LivePatternStats {
|
|
127
|
+
layerId: string;
|
|
128
|
+
wet: boolean;
|
|
129
|
+
wetCells: number;
|
|
130
|
+
wetBounds: RasterRect | null;
|
|
131
|
+
}
|
|
124
132
|
export interface PaintEditorState {
|
|
125
133
|
document: PaintDocumentState;
|
|
126
134
|
/** The active brush (possibly edited from its preset). */
|
|
@@ -1406,6 +1414,50 @@ export declare class PaintEditorController {
|
|
|
1406
1414
|
ty: number;
|
|
1407
1415
|
data: Uint8ClampedArray;
|
|
1408
1416
|
}>;
|
|
1417
|
+
private layerLivePatternsInfo;
|
|
1418
|
+
private checkLivePatternsInput;
|
|
1419
|
+
/**
|
|
1420
|
+
* Reads a layer's Gray-Scott reaction-diffusion live patterns (`layerId`, default the active
|
|
1421
|
+
* layer), plus all layers with wet paint or live patterns and the built-in Pearson presets.
|
|
1422
|
+
*/
|
|
1423
|
+
getLivePatterns(layerId?: string): PaintLayerLivePatternsInfo & {
|
|
1424
|
+
layers: PaintLayerLivePatternsInfo[];
|
|
1425
|
+
presets: Readonly<Record<LivePatternKind, {
|
|
1426
|
+
feed: number;
|
|
1427
|
+
kill: number;
|
|
1428
|
+
}>>;
|
|
1429
|
+
brushPresets: readonly string[];
|
|
1430
|
+
};
|
|
1431
|
+
/**
|
|
1432
|
+
* Configures a layer's Gray-Scott reaction-diffusion live patterns (or clears them with
|
|
1433
|
+
* `enabled: false`). One undo step.
|
|
1434
|
+
*/
|
|
1435
|
+
setLivePatterns(layerId: string | undefined, update: LivePatternsInput & {
|
|
1436
|
+
enabled?: boolean;
|
|
1437
|
+
}): PaintLayerLivePatternsInfo;
|
|
1438
|
+
/**
|
|
1439
|
+
* Seeds Gray-Scott reaction-diffusion activator (`V`) discs into a layer's live-pattern field so
|
|
1440
|
+
* patterns grow where the layer holds wet water and freeze where it dries. One undo step.
|
|
1441
|
+
*/
|
|
1442
|
+
seedLivePatterns(options: {
|
|
1443
|
+
layerId?: string;
|
|
1444
|
+
points: ReadonlyArray<{
|
|
1445
|
+
x: number;
|
|
1446
|
+
y: number;
|
|
1447
|
+
strength?: number;
|
|
1448
|
+
}>;
|
|
1449
|
+
radius?: number;
|
|
1450
|
+
seed?: number;
|
|
1451
|
+
pattern?: LivePatternKind;
|
|
1452
|
+
feed?: number;
|
|
1453
|
+
kill?: number;
|
|
1454
|
+
scale?: number;
|
|
1455
|
+
contrast?: number;
|
|
1456
|
+
secondColor?: string | null;
|
|
1457
|
+
relief?: number;
|
|
1458
|
+
}): PaintLayerLivePatternsInfo & {
|
|
1459
|
+
seededCells: number;
|
|
1460
|
+
};
|
|
1409
1461
|
private sources;
|
|
1410
1462
|
/** The layers with the live stroke's surface in place. */
|
|
1411
1463
|
private currentLayers;
|
|
@@ -50,6 +50,7 @@ import { PaintWetLayers, type PaintWetOptions, type WetEngineInfo, type WetGpuMo
|
|
|
50
50
|
import { type WetParams, type WetTilt } from '../paint/wet/model.js';
|
|
51
51
|
import { type WetFlowSpec } from '../paint/wet/flow.js';
|
|
52
52
|
import { type WetBackendInfo } from '../paint/wet/world.js';
|
|
53
|
+
import { type LivePatternKind, type LivePatternStats, type LivePatternsInput } from '../paint/live-patterns.js';
|
|
53
54
|
import { type TimeLapse, type TimeLapseOptions } from './replay.js';
|
|
54
55
|
import { EffectsSlot } from '../effects/helpers.js';
|
|
55
56
|
import type { EffectDescription, EffectProvider, EffectValue } from '../effects/types.js';
|
|
@@ -121,6 +122,13 @@ export interface PaintWetStateInfo {
|
|
|
121
122
|
/** Engine B is shading the wet paint now. */
|
|
122
123
|
gpuActive: boolean;
|
|
123
124
|
}
|
|
125
|
+
/** One layer's Gray-Scott live-pattern state and wet coverage. */
|
|
126
|
+
export interface PaintLayerLivePatternsInfo extends LivePatternStats {
|
|
127
|
+
layerId: string;
|
|
128
|
+
wet: boolean;
|
|
129
|
+
wetCells: number;
|
|
130
|
+
wetBounds: RasterRect | null;
|
|
131
|
+
}
|
|
124
132
|
export interface PaintEditorState {
|
|
125
133
|
document: PaintDocumentState;
|
|
126
134
|
/** The active brush (possibly edited from its preset). */
|
|
@@ -1406,6 +1414,50 @@ export declare class PaintEditorController {
|
|
|
1406
1414
|
ty: number;
|
|
1407
1415
|
data: Uint8ClampedArray;
|
|
1408
1416
|
}>;
|
|
1417
|
+
private layerLivePatternsInfo;
|
|
1418
|
+
private checkLivePatternsInput;
|
|
1419
|
+
/**
|
|
1420
|
+
* Reads a layer's Gray-Scott reaction-diffusion live patterns (`layerId`, default the active
|
|
1421
|
+
* layer), plus all layers with wet paint or live patterns and the built-in Pearson presets.
|
|
1422
|
+
*/
|
|
1423
|
+
getLivePatterns(layerId?: string): PaintLayerLivePatternsInfo & {
|
|
1424
|
+
layers: PaintLayerLivePatternsInfo[];
|
|
1425
|
+
presets: Readonly<Record<LivePatternKind, {
|
|
1426
|
+
feed: number;
|
|
1427
|
+
kill: number;
|
|
1428
|
+
}>>;
|
|
1429
|
+
brushPresets: readonly string[];
|
|
1430
|
+
};
|
|
1431
|
+
/**
|
|
1432
|
+
* Configures a layer's Gray-Scott reaction-diffusion live patterns (or clears them with
|
|
1433
|
+
* `enabled: false`). One undo step.
|
|
1434
|
+
*/
|
|
1435
|
+
setLivePatterns(layerId: string | undefined, update: LivePatternsInput & {
|
|
1436
|
+
enabled?: boolean;
|
|
1437
|
+
}): PaintLayerLivePatternsInfo;
|
|
1438
|
+
/**
|
|
1439
|
+
* Seeds Gray-Scott reaction-diffusion activator (`V`) discs into a layer's live-pattern field so
|
|
1440
|
+
* patterns grow where the layer holds wet water and freeze where it dries. One undo step.
|
|
1441
|
+
*/
|
|
1442
|
+
seedLivePatterns(options: {
|
|
1443
|
+
layerId?: string;
|
|
1444
|
+
points: ReadonlyArray<{
|
|
1445
|
+
x: number;
|
|
1446
|
+
y: number;
|
|
1447
|
+
strength?: number;
|
|
1448
|
+
}>;
|
|
1449
|
+
radius?: number;
|
|
1450
|
+
seed?: number;
|
|
1451
|
+
pattern?: LivePatternKind;
|
|
1452
|
+
feed?: number;
|
|
1453
|
+
kill?: number;
|
|
1454
|
+
scale?: number;
|
|
1455
|
+
contrast?: number;
|
|
1456
|
+
secondColor?: string | null;
|
|
1457
|
+
relief?: number;
|
|
1458
|
+
}): PaintLayerLivePatternsInfo & {
|
|
1459
|
+
seededCells: number;
|
|
1460
|
+
};
|
|
1409
1461
|
private sources;
|
|
1410
1462
|
/** The layers with the live stroke's surface in place. */
|
|
1411
1463
|
private currentLayers;
|