@pixerate/editor 0.273.0 → 0.275.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 +60 -60
- package/dist/animation-editor/index.js +4 -4
- package/dist/brushes/index.cjs +102 -74
- package/dist/brushes/index.js +34 -6
- package/dist/brushes/patch.d.cts +1 -1
- package/dist/brushes/patch.d.ts +1 -1
- package/dist/brushes/preview.d.cts +3 -0
- package/dist/brushes/preview.d.ts +3 -0
- package/dist/brushes/profiles.d.cts +2 -0
- package/dist/brushes/profiles.d.ts +2 -0
- package/dist/brushes/schema.d.cts +4 -0
- package/dist/brushes/schema.d.ts +4 -0
- package/dist/brushes/types.d.cts +47 -0
- package/dist/brushes/types.d.ts +47 -0
- package/dist/{brushstrokeRender-5YBCLFDQ.cjs → brushstrokeRender-2RQL46WB.cjs} +15 -15
- package/dist/{brushstrokeRender-DZGFU3J4.js → brushstrokeRender-WGY4DZHF.js} +3 -3
- package/dist/canvas/index.cjs +13 -13
- package/dist/canvas/index.js +1 -1
- package/dist/{chunk-2XDNF73E.js → chunk-43XJC3PP.js} +1 -1
- package/dist/{chunk-GHGBIAWQ.cjs → chunk-6QNDGMK7.cjs} +263 -45
- package/dist/{chunk-2F3YDXCN.js → chunk-75SYKUOT.js} +1 -1
- package/dist/{chunk-M3RZOF3G.cjs → chunk-C6VB7CPY.cjs} +1 -1
- package/dist/{chunk-N5IMDAHM.cjs → chunk-DHC4E2DU.cjs} +89 -37
- package/dist/{chunk-NAHJV3O6.js → chunk-G5TCMKX5.js} +28 -11
- package/dist/{chunk-DZVRH63Y.js → chunk-IEEY5RJV.js} +1 -1
- package/dist/{chunk-7W2EQQBP.cjs → chunk-JDXWLCXF.cjs} +6 -6
- package/dist/{chunk-N3SKPQEH.js → chunk-LMG57L5A.js} +62 -10
- package/dist/{chunk-5HP2VSAS.js → chunk-MSWLJI4G.js} +1 -1
- package/dist/{chunk-SNAFFCAX.cjs → chunk-OLZXXAER.cjs} +221 -196
- package/dist/{chunk-YJANF2BL.cjs → chunk-RAPNRK4R.cjs} +86 -86
- package/dist/{chunk-CLB2I2FU.js → chunk-RJGW3RQS.js} +2 -2
- package/dist/{chunk-FXVCB6YG.cjs → chunk-T6KNJVBP.cjs} +35 -35
- package/dist/{chunk-ZEI7ZEA4.js → chunk-Y2ISSVPH.js} +34 -9
- package/dist/{chunk-3JKCREEU.cjs → chunk-Y354ETAE.cjs} +76 -59
- package/dist/{chunk-TNLKFW7D.cjs → chunk-YYZC2EQO.cjs} +23 -23
- package/dist/{chunk-UXYCY3HP.js → chunk-ZM7IKQ4X.js} +239 -21
- package/dist/image-editor/index.cjs +789 -789
- package/dist/image-editor/index.js +5 -5
- package/dist/paint/index.cjs +2 -2
- package/dist/paint/index.js +1 -1
- package/dist/paint/wet/world.d.cts +15 -2
- package/dist/paint/wet/world.d.ts +15 -2
- package/dist/paint-editor/brush-controls.d.cts +7 -0
- package/dist/paint-editor/brush-controls.d.ts +7 -0
- package/dist/paint-editor/brush-model.d.cts +59 -1
- package/dist/paint-editor/brush-model.d.ts +59 -1
- package/dist/paint-editor/collaboration.d.cts +6 -1
- package/dist/paint-editor/collaboration.d.ts +6 -1
- package/dist/paint-editor/controller.d.cts +199 -1
- package/dist/paint-editor/controller.d.ts +199 -1
- package/dist/paint-editor/dab-stroke.d.cts +3 -0
- package/dist/paint-editor/dab-stroke.d.ts +3 -0
- package/dist/paint-editor/document.d.cts +13 -3
- package/dist/paint-editor/document.d.ts +13 -3
- package/dist/paint-editor/engine.d.cts +3 -0
- package/dist/paint-editor/engine.d.ts +3 -0
- package/dist/paint-editor/evolution-tools.d.cts +48 -0
- package/dist/paint-editor/evolution-tools.d.ts +48 -0
- package/dist/paint-editor/evolution.d.cts +175 -0
- package/dist/paint-editor/evolution.d.ts +175 -0
- package/dist/paint-editor/heat.d.cts +156 -0
- package/dist/paint-editor/heat.d.ts +156 -0
- package/dist/paint-editor/index.cjs +4905 -1525
- package/dist/paint-editor/index.d.cts +5 -0
- package/dist/paint-editor/index.d.ts +5 -0
- package/dist/paint-editor/index.js +10952 -7572
- package/dist/paint-editor/mutation-tools.d.cts +13 -0
- package/dist/paint-editor/mutation-tools.d.ts +13 -0
- package/dist/paint-editor/mutation.d.cts +67 -0
- package/dist/paint-editor/mutation.d.ts +67 -0
- package/dist/paint-editor/presence.d.cts +7 -1
- package/dist/paint-editor/presence.d.ts +7 -1
- package/dist/paint-editor/procedural.d.cts +3 -0
- package/dist/paint-editor/procedural.d.ts +3 -0
- package/dist/paint-editor/stroke.d.cts +32 -2
- package/dist/paint-editor/stroke.d.ts +32 -2
- package/dist/paint-editor/thick.d.cts +48 -7
- package/dist/paint-editor/thick.d.ts +48 -7
- package/dist/paint-editor/ui.d.cts +36 -1
- package/dist/paint-editor/ui.d.ts +36 -1
- package/dist/paint-editor/wet.d.cts +8 -1
- package/dist/paint-editor/wet.d.ts +8 -1
- package/dist/vector/index.cjs +999 -999
- package/dist/vector/index.js +5 -5
- package/package.json +1 -1
- package/skills/README.md +1 -0
- package/skills/pixerate-brushes/SKILL.md +3 -0
- package/skills/pixerate-paint-editor/SKILL.md +36 -53
- package/skills/pixerate-paint-editor/references/brush-facets.md +3 -0
- package/skills/pixerate-paint-editor/references/mutation.md +25 -0
- package/skills/pixerate-paint-editor/references/oils.md +8 -1
- package/skills/pixerate-paint-editor/references/smart-inks.md +51 -0
- package/skills/pixerate-paint-mutation/SKILL.md +76 -0
- package/skills/pixerate-paint-mutation/evals/decline-unanswered.json +58 -0
- package/skills/pixerate-paint-mutation/evals/dry-ink-answer.json +74 -0
- package/skills/pixerate-paint-mutation/evals/wet-wash-answer.json +76 -0
- package/skills/pixerate-paint-oil-impasto/SKILL.md +2 -1
|
@@ -55,7 +55,13 @@ import { EffectsSlot } from '../effects/helpers.cjs';
|
|
|
55
55
|
import type { EffectDescription, EffectProvider, EffectValue } from '../effects/types.cjs';
|
|
56
56
|
import { type PaintEffectPaint } from './effect-paint.cjs';
|
|
57
57
|
import { type PaintEffectPlace, type PaintEffectSource, type PaintPaperEffect, type PaperEffectBlend } from './effects.cjs';
|
|
58
|
-
import { type PaintLighting } from './thick.cjs';
|
|
58
|
+
import { type PaintLighting, type PaintViewTilt } from './thick.cjs';
|
|
59
|
+
import { type HeatSample, type HeatStats, type UvLightSettings } from './heat.cjs';
|
|
60
|
+
import { type PaintMutationAnswerInput, type PaintMutationAnswerResult, type PaintMutationInfo, type PaintMutationReadResult, type PaintMutationRequestListener } from './mutation.cjs';
|
|
61
|
+
import type { PaintDirector } from './presence.cjs';
|
|
62
|
+
import type { PresenceActorInfo } from '../animation/presence.cjs';
|
|
63
|
+
import { type PaintProposals } from './collaboration.cjs';
|
|
64
|
+
import { type BreedStrokesResult, type ProposalGenomeResult, type StrokeMutationRates } from './evolution.cjs';
|
|
59
65
|
export declare class PaintEditorError extends Error {
|
|
60
66
|
constructor(message: string);
|
|
61
67
|
}
|
|
@@ -144,6 +150,8 @@ export interface PaintEditorState {
|
|
|
144
150
|
/** What the Mixer Brush carries between strokes. */
|
|
145
151
|
mixerLoad: MixerLoad;
|
|
146
152
|
view: PaintView;
|
|
153
|
+
/** View tilt for thin-film iridescence and specular highlights (-1..1, default {x: 0, y: 0}; editor state, not saved with the document). */
|
|
154
|
+
viewTilt: PaintViewTilt;
|
|
147
155
|
hand: Hand;
|
|
148
156
|
/** Live effect paint: whether strokes on stroke layers play their effect, the frame rate cap and the time (ms) the view shows. Editor state. */
|
|
149
157
|
effectPlayback: {
|
|
@@ -171,6 +179,14 @@ export interface PaintEditorState {
|
|
|
171
179
|
stroking: boolean;
|
|
172
180
|
/** Wet media. */
|
|
173
181
|
wet: PaintWetStateInfo;
|
|
182
|
+
/** The UV / blacklight view setting (saved with the document, not undo steps). */
|
|
183
|
+
uvLight: UvLightSettings;
|
|
184
|
+
/** The coarse heat field's temperature summary. */
|
|
185
|
+
heat: HeatStats;
|
|
186
|
+
/** Pending and active mutation exchanges (editor state, not saved with the document). */
|
|
187
|
+
mutations: readonly PaintMutationInfo[];
|
|
188
|
+
/** Whether an agent is listening for mutation requests (`onMutationRequest` or `setMutationAgentConnected`). */
|
|
189
|
+
hasMutationAgent: boolean;
|
|
174
190
|
/** Increments on every change. */
|
|
175
191
|
version: number;
|
|
176
192
|
}
|
|
@@ -206,6 +222,8 @@ export interface PaintLayerInfo {
|
|
|
206
222
|
liveStrokes?: number;
|
|
207
223
|
/** How many live layer effects (glows, shadows, strokes…) it has, when any (`getLayerEffects`). */
|
|
208
224
|
effects?: number;
|
|
225
|
+
/** A temporary layer created for a dry mutation stroke (fades away once claimed or merges down if unanswered). */
|
|
226
|
+
temporary?: boolean;
|
|
209
227
|
}
|
|
210
228
|
/** A live stroke as it is painted (`onStrokeSample`), for agents that paint along with the user. */
|
|
211
229
|
export interface PaintStrokeSample {
|
|
@@ -517,9 +535,17 @@ export declare class PaintEditorController {
|
|
|
517
535
|
private readonly wetOptions;
|
|
518
536
|
/** Where the light comes from for thick paint (saved with the document, not undo steps). */
|
|
519
537
|
private lighting;
|
|
538
|
+
/** Where the viewer looks from for thin-film iridescence and specular highlights (editor state, not saved with the document). */
|
|
539
|
+
private viewTilt;
|
|
520
540
|
private readonly litCaches;
|
|
521
541
|
/** The live impasto stroke's channels. */
|
|
522
542
|
private liveThick;
|
|
543
|
+
/** The UV / blacklight setting (saved with the document, not undo steps). */
|
|
544
|
+
private uvLight;
|
|
545
|
+
private readonly uvCaches;
|
|
546
|
+
private readonly thermoCaches;
|
|
547
|
+
private liveFluor;
|
|
548
|
+
private liveThermo;
|
|
523
549
|
/** Set while an operation that changes wet paint runs: the simulation before it (for undo). */
|
|
524
550
|
private wetOp;
|
|
525
551
|
/** The effects provider slot (see `setEffectsProvider`). */
|
|
@@ -534,6 +560,15 @@ export declare class PaintEditorController {
|
|
|
534
560
|
private readonly rasterizeSticker;
|
|
535
561
|
private readonly effectsRenderer;
|
|
536
562
|
private paperEffectNodeCache;
|
|
563
|
+
private mutations;
|
|
564
|
+
private nextMutationId;
|
|
565
|
+
private readonly mutationListeners;
|
|
566
|
+
private mutationAgentConnected;
|
|
567
|
+
private mutationDirector;
|
|
568
|
+
private readonly heldEvaporation;
|
|
569
|
+
private readonly tempLayerTargets;
|
|
570
|
+
private answeringMutation;
|
|
571
|
+
private lastMutationTick;
|
|
537
572
|
constructor(options?: PaintEditorOptions);
|
|
538
573
|
subscribe(listener: () => void): () => void;
|
|
539
574
|
/**
|
|
@@ -1157,12 +1192,81 @@ export declare class PaintEditorController {
|
|
|
1157
1192
|
layerId: string;
|
|
1158
1193
|
cleared: boolean;
|
|
1159
1194
|
};
|
|
1195
|
+
private fluorWithout;
|
|
1196
|
+
private thermoWithout;
|
|
1197
|
+
/** The UV / blacklight view setting. */
|
|
1198
|
+
getUvLight(): UvLightSettings;
|
|
1199
|
+
/** Layers that carry UV-fluorescent ink. */
|
|
1200
|
+
fluorescentLayerIds(): string[];
|
|
1201
|
+
/** Layers that carry thermochromic ink. */
|
|
1202
|
+
thermochromicLayerIds(): string[];
|
|
1203
|
+
/**
|
|
1204
|
+
* Switches or tunes the virtual UV / blacklight (`on`, `strength` 0..2, `ambient` 0..1). When
|
|
1205
|
+
* `on` is true, the composite dims to `ambient` and fluorescent ink (`brush.fluorescence`) glows
|
|
1206
|
+
* in its stroke colour with a Linear Dodge halo. Saved with the document, not an undo step.
|
|
1207
|
+
*/
|
|
1208
|
+
setUvLight(update: Partial<UvLightSettings>): UvLightSettings;
|
|
1209
|
+
/**
|
|
1210
|
+
* Reads the document's heat field: its temperature summary (`peak`, `mean`, `hotCells`) and,
|
|
1211
|
+
* when `points` are given (document pixels), the bilinearly sampled temperature (0..1) at each.
|
|
1212
|
+
*/
|
|
1213
|
+
getHeat(points?: readonly {
|
|
1214
|
+
x: number;
|
|
1215
|
+
y: number;
|
|
1216
|
+
}[]): HeatStats & {
|
|
1217
|
+
samples: HeatSample[];
|
|
1218
|
+
thermochromicLayerIds: string[];
|
|
1219
|
+
};
|
|
1220
|
+
/**
|
|
1221
|
+
* Warms (or with `temperature` 0 cools) the canvas heat field along `points` (document pixels)
|
|
1222
|
+
* with a soft brush of `radius` px (default 28) towards `temperature` 0..1 (default 1). Where
|
|
1223
|
+
* temperature reaches `HEAT_DRY_THRESHOLD` (0.5), any wet paint on those tiles dries at once.
|
|
1224
|
+
* One undo step.
|
|
1225
|
+
*/
|
|
1226
|
+
paintHeat(options: {
|
|
1227
|
+
points: readonly {
|
|
1228
|
+
x: number;
|
|
1229
|
+
y: number;
|
|
1230
|
+
}[];
|
|
1231
|
+
radius?: number;
|
|
1232
|
+
temperature?: number;
|
|
1233
|
+
}): HeatStats & {
|
|
1234
|
+
bounds: RasterRect | null;
|
|
1235
|
+
dried: Array<{
|
|
1236
|
+
layerId: string;
|
|
1237
|
+
bounds: RasterRect | null;
|
|
1238
|
+
}>;
|
|
1239
|
+
};
|
|
1240
|
+
/**
|
|
1241
|
+
* Advances the heat field by `steps` simulation steps (1..200, default 10): heat diffuses into
|
|
1242
|
+
* neighbouring cells and cools towards 0 by Newtonian cooling. Newly heated tiles above the dry
|
|
1243
|
+
* threshold dry any wet paint on them. Not an undo step (time passing never is).
|
|
1244
|
+
*/
|
|
1245
|
+
advanceHeat(stepsOrOptions?: number | {
|
|
1246
|
+
steps?: number;
|
|
1247
|
+
}): HeatStats & {
|
|
1248
|
+
steps: number;
|
|
1249
|
+
dried: Array<{
|
|
1250
|
+
layerId: string;
|
|
1251
|
+
bounds: RasterRect | null;
|
|
1252
|
+
}>;
|
|
1253
|
+
};
|
|
1254
|
+
/** Cools the whole canvas heat field to 0 at once (one undo step when anything was warm). */
|
|
1255
|
+
clearHeat(): {
|
|
1256
|
+
cleared: boolean;
|
|
1257
|
+
};
|
|
1258
|
+
/** Dries any wet paint on tiles where `field` is at or above `HEAT_DRY_THRESHOLD`. */
|
|
1259
|
+
private dryWetFromHeat;
|
|
1160
1260
|
/** The document's `thick` without these layers (as a spread: `{}` when unchanged). */
|
|
1161
1261
|
private thickWithout;
|
|
1162
1262
|
/** Where the light comes from for thick paint and metallic paper. */
|
|
1163
1263
|
getLighting(): PaintLighting;
|
|
1164
1264
|
/** Moves the light (thick paint and metallic paper are relit; nothing is repainted). Saved with the document, not an undo step. */
|
|
1165
1265
|
setLighting(update: Partial<PaintLighting>): PaintLighting;
|
|
1266
|
+
/** Where the viewer looks from for thin-film iridescence and specular highlights (-1..1; editor state, not saved with the document). */
|
|
1267
|
+
getViewTilt(): PaintViewTilt;
|
|
1268
|
+
/** Tilts the view vector for thin-film iridescence and specular highlights (-1..1; editor state, not saved with the document, not an undo step). */
|
|
1269
|
+
setViewTilt(update: Partial<PaintViewTilt>): PaintViewTilt;
|
|
1166
1270
|
/** A layer's relief: where it is, its highest point (0..255) and its tiles; `null` when it has none. */
|
|
1167
1271
|
reliefOf(layerId?: string): {
|
|
1168
1272
|
layerId: string;
|
|
@@ -1313,6 +1417,14 @@ export declare class PaintEditorController {
|
|
|
1313
1417
|
private tracingNode;
|
|
1314
1418
|
/** The layers with every wet layer dried where it is (what saving and exporting see). */
|
|
1315
1419
|
private driedLayers;
|
|
1420
|
+
/** The layers with thermochromic paint shifted toward its hot colour where the canvas is warm. */
|
|
1421
|
+
private thermoLayers;
|
|
1422
|
+
/**
|
|
1423
|
+
* Under the UV blacklight: every pixel layer's daylight paint dims to `uvLight.ambient`, any
|
|
1424
|
+
* fluorescent ink (`doc.fluor[id]`) glows in its own colour, and each fluorescent layer casts a
|
|
1425
|
+
* Linear Dodge (`::uv`) spill layer directly above it.
|
|
1426
|
+
*/
|
|
1427
|
+
private uvLayers;
|
|
1316
1428
|
/** The layers with thick paint lit (each thick layer's pixels replaced by its lit tiles). */
|
|
1317
1429
|
private litLayers;
|
|
1318
1430
|
/**
|
|
@@ -1690,8 +1802,94 @@ export declare class PaintEditorController {
|
|
|
1690
1802
|
removeMixingPad(id: string): SavedMixingPadInfo;
|
|
1691
1803
|
private mixingPadJSON;
|
|
1692
1804
|
private readMixingPad;
|
|
1805
|
+
/**
|
|
1806
|
+
* Hears each mutation once it has settled (`settle` seconds after the user's last mutation
|
|
1807
|
+
* stroke). Registering a listener marks an agent as connected (`state.hasMutationAgent`).
|
|
1808
|
+
*/
|
|
1809
|
+
onMutationRequest(listener: PaintMutationRequestListener): () => void;
|
|
1810
|
+
/** Marks whether a mutation-answering agent is connected (for hosts that wake agents via tools). */
|
|
1811
|
+
setMutationAgentConnected(connected: boolean): void;
|
|
1812
|
+
/** Attaches a `PaintDirector` so `answerMutation` and `readMutation` animate the agent's cursor. */
|
|
1813
|
+
setMutationDirector(director: PaintDirector | null): void;
|
|
1814
|
+
/** Lists pending mutations (or all mutations when `includeAll` is true). */
|
|
1815
|
+
listMutations(options?: {
|
|
1816
|
+
includeAll?: boolean;
|
|
1817
|
+
}): PaintMutationInfo[];
|
|
1818
|
+
/** One mutation by id (`undefined` when unknown). */
|
|
1819
|
+
getMutation(id: string): PaintMutationInfo | undefined;
|
|
1820
|
+
/**
|
|
1821
|
+
* Claims a mutation (`id`) and starts its fade. Returns the strokes (points, colour, brush), a
|
|
1822
|
+
* PNG of the area around them (`cropPng`), and a preview of the whole painting (`canvasPng`) so
|
|
1823
|
+
* the agent can choose where to answer. Refused if already claimed, answered or declined.
|
|
1824
|
+
*/
|
|
1825
|
+
readMutation(id: string, options?: {
|
|
1826
|
+
actor?: string;
|
|
1827
|
+
padding?: number;
|
|
1828
|
+
maxSide?: number;
|
|
1829
|
+
}): PaintMutationReadResult;
|
|
1830
|
+
/**
|
|
1831
|
+
* Paints the agent's answer to a claimed mutation (`id`). When a `PaintDirector` is attached (or
|
|
1832
|
+
* passed in `options`), the agent's cursor is seen painting live; all strokes commit as one undo
|
|
1833
|
+
* step with origin `agent:<id>`. A second answer to the same id is refused.
|
|
1834
|
+
*/
|
|
1835
|
+
answerMutation(id: string, input: PaintMutationAnswerInput, options?: {
|
|
1836
|
+
director?: PaintDirector;
|
|
1837
|
+
actor?: PresenceActorInfo;
|
|
1838
|
+
}): Promise<PaintMutationAnswerResult>;
|
|
1839
|
+
/**
|
|
1840
|
+
* Gives up on a mutation (`id`) without answering. The user's paint stays as ordinary paint (wet
|
|
1841
|
+
* strokes stay in the wet layer, and dry temporary layers merge down into their target layer).
|
|
1842
|
+
*/
|
|
1843
|
+
declineMutation(id: string, reason?: string): PaintMutationInfo;
|
|
1844
|
+
/**
|
|
1845
|
+
* Advances mutation timers (`settle`, `patience`, and dry temporary-layer `fade`) by `seconds`
|
|
1846
|
+
* of simulated time. Called automatically from `tickMutations` and `advanceWet`.
|
|
1847
|
+
*/
|
|
1848
|
+
advanceMutations(seconds: number): void;
|
|
1849
|
+
/** Steps mutation timers with the wall clock (`performance.now()`, in ms). */
|
|
1850
|
+
tickMutations(now: number): void;
|
|
1851
|
+
private toMutationInfo;
|
|
1852
|
+
private recordMutationStroke;
|
|
1853
|
+
private holdMutationEvaporation;
|
|
1854
|
+
private releaseMutationEvaporation;
|
|
1855
|
+
private finishWetMutationsOnDry;
|
|
1856
|
+
private expireMutation;
|
|
1857
|
+
private keepMutationPaint;
|
|
1858
|
+
private mergeTempLayerIntoTarget;
|
|
1859
|
+
private removeTempMutationLayer;
|
|
1860
|
+
private reconcileMutationsAfterUndo;
|
|
1861
|
+
private resetMutations;
|
|
1693
1862
|
/** A layer's tile surface (live while stroking), for thumbnails. */
|
|
1694
1863
|
layerSurface(id: string): TiledSurface | null;
|
|
1864
|
+
private proposalsStore;
|
|
1865
|
+
/** The pending paint proposals store attached to this editor (created on demand). */
|
|
1866
|
+
get proposals(): PaintProposals;
|
|
1867
|
+
/** Attaches an external `PaintProposals` store so tools and panels share it. */
|
|
1868
|
+
attachProposals(store: PaintProposals): void;
|
|
1869
|
+
/**
|
|
1870
|
+
* Breeds `count` (`2..12`, default `4`) mutated variants from `1..16` recorded strokes as
|
|
1871
|
+
* pending paint proposals, generated one after another through `previewPaint`.
|
|
1872
|
+
*/
|
|
1873
|
+
breedStrokes(options: {
|
|
1874
|
+
strokeIds: readonly string[];
|
|
1875
|
+
count?: number;
|
|
1876
|
+
mutation?: StrokeMutationRates;
|
|
1877
|
+
seed?: number;
|
|
1878
|
+
origin?: string;
|
|
1879
|
+
}): BreedStrokesResult;
|
|
1880
|
+
/**
|
|
1881
|
+
* Breeds `count` (`2..12`, default `4`) variants from `1` pending proposal (mutation) or `2`
|
|
1882
|
+
* pending proposals (crossover + mutation), generated one after another through `previewPaint`.
|
|
1883
|
+
*/
|
|
1884
|
+
breedProposal(options: {
|
|
1885
|
+
proposalIds: readonly string[];
|
|
1886
|
+
count?: number;
|
|
1887
|
+
mutation?: StrokeMutationRates;
|
|
1888
|
+
seed?: number;
|
|
1889
|
+
origin?: string;
|
|
1890
|
+
}): BreedStrokesResult;
|
|
1891
|
+
/** Returns the full stroke genome records (`RecordedStrokeJSON[]`) of a pending paint proposal. */
|
|
1892
|
+
getProposalGenome(proposalId: string): ProposalGenomeResult;
|
|
1695
1893
|
}
|
|
1696
1894
|
export type { Tile };
|
|
1697
1895
|
/** Largest tracing or reference image side, in pixels. */
|
|
@@ -55,7 +55,13 @@ import { EffectsSlot } from '../effects/helpers.js';
|
|
|
55
55
|
import type { EffectDescription, EffectProvider, EffectValue } from '../effects/types.js';
|
|
56
56
|
import { type PaintEffectPaint } from './effect-paint.js';
|
|
57
57
|
import { type PaintEffectPlace, type PaintEffectSource, type PaintPaperEffect, type PaperEffectBlend } from './effects.js';
|
|
58
|
-
import { type PaintLighting } from './thick.js';
|
|
58
|
+
import { type PaintLighting, type PaintViewTilt } from './thick.js';
|
|
59
|
+
import { type HeatSample, type HeatStats, type UvLightSettings } from './heat.js';
|
|
60
|
+
import { type PaintMutationAnswerInput, type PaintMutationAnswerResult, type PaintMutationInfo, type PaintMutationReadResult, type PaintMutationRequestListener } from './mutation.js';
|
|
61
|
+
import type { PaintDirector } from './presence.js';
|
|
62
|
+
import type { PresenceActorInfo } from '../animation/presence.js';
|
|
63
|
+
import { type PaintProposals } from './collaboration.js';
|
|
64
|
+
import { type BreedStrokesResult, type ProposalGenomeResult, type StrokeMutationRates } from './evolution.js';
|
|
59
65
|
export declare class PaintEditorError extends Error {
|
|
60
66
|
constructor(message: string);
|
|
61
67
|
}
|
|
@@ -144,6 +150,8 @@ export interface PaintEditorState {
|
|
|
144
150
|
/** What the Mixer Brush carries between strokes. */
|
|
145
151
|
mixerLoad: MixerLoad;
|
|
146
152
|
view: PaintView;
|
|
153
|
+
/** View tilt for thin-film iridescence and specular highlights (-1..1, default {x: 0, y: 0}; editor state, not saved with the document). */
|
|
154
|
+
viewTilt: PaintViewTilt;
|
|
147
155
|
hand: Hand;
|
|
148
156
|
/** Live effect paint: whether strokes on stroke layers play their effect, the frame rate cap and the time (ms) the view shows. Editor state. */
|
|
149
157
|
effectPlayback: {
|
|
@@ -171,6 +179,14 @@ export interface PaintEditorState {
|
|
|
171
179
|
stroking: boolean;
|
|
172
180
|
/** Wet media. */
|
|
173
181
|
wet: PaintWetStateInfo;
|
|
182
|
+
/** The UV / blacklight view setting (saved with the document, not undo steps). */
|
|
183
|
+
uvLight: UvLightSettings;
|
|
184
|
+
/** The coarse heat field's temperature summary. */
|
|
185
|
+
heat: HeatStats;
|
|
186
|
+
/** Pending and active mutation exchanges (editor state, not saved with the document). */
|
|
187
|
+
mutations: readonly PaintMutationInfo[];
|
|
188
|
+
/** Whether an agent is listening for mutation requests (`onMutationRequest` or `setMutationAgentConnected`). */
|
|
189
|
+
hasMutationAgent: boolean;
|
|
174
190
|
/** Increments on every change. */
|
|
175
191
|
version: number;
|
|
176
192
|
}
|
|
@@ -206,6 +222,8 @@ export interface PaintLayerInfo {
|
|
|
206
222
|
liveStrokes?: number;
|
|
207
223
|
/** How many live layer effects (glows, shadows, strokes…) it has, when any (`getLayerEffects`). */
|
|
208
224
|
effects?: number;
|
|
225
|
+
/** A temporary layer created for a dry mutation stroke (fades away once claimed or merges down if unanswered). */
|
|
226
|
+
temporary?: boolean;
|
|
209
227
|
}
|
|
210
228
|
/** A live stroke as it is painted (`onStrokeSample`), for agents that paint along with the user. */
|
|
211
229
|
export interface PaintStrokeSample {
|
|
@@ -517,9 +535,17 @@ export declare class PaintEditorController {
|
|
|
517
535
|
private readonly wetOptions;
|
|
518
536
|
/** Where the light comes from for thick paint (saved with the document, not undo steps). */
|
|
519
537
|
private lighting;
|
|
538
|
+
/** Where the viewer looks from for thin-film iridescence and specular highlights (editor state, not saved with the document). */
|
|
539
|
+
private viewTilt;
|
|
520
540
|
private readonly litCaches;
|
|
521
541
|
/** The live impasto stroke's channels. */
|
|
522
542
|
private liveThick;
|
|
543
|
+
/** The UV / blacklight setting (saved with the document, not undo steps). */
|
|
544
|
+
private uvLight;
|
|
545
|
+
private readonly uvCaches;
|
|
546
|
+
private readonly thermoCaches;
|
|
547
|
+
private liveFluor;
|
|
548
|
+
private liveThermo;
|
|
523
549
|
/** Set while an operation that changes wet paint runs: the simulation before it (for undo). */
|
|
524
550
|
private wetOp;
|
|
525
551
|
/** The effects provider slot (see `setEffectsProvider`). */
|
|
@@ -534,6 +560,15 @@ export declare class PaintEditorController {
|
|
|
534
560
|
private readonly rasterizeSticker;
|
|
535
561
|
private readonly effectsRenderer;
|
|
536
562
|
private paperEffectNodeCache;
|
|
563
|
+
private mutations;
|
|
564
|
+
private nextMutationId;
|
|
565
|
+
private readonly mutationListeners;
|
|
566
|
+
private mutationAgentConnected;
|
|
567
|
+
private mutationDirector;
|
|
568
|
+
private readonly heldEvaporation;
|
|
569
|
+
private readonly tempLayerTargets;
|
|
570
|
+
private answeringMutation;
|
|
571
|
+
private lastMutationTick;
|
|
537
572
|
constructor(options?: PaintEditorOptions);
|
|
538
573
|
subscribe(listener: () => void): () => void;
|
|
539
574
|
/**
|
|
@@ -1157,12 +1192,81 @@ export declare class PaintEditorController {
|
|
|
1157
1192
|
layerId: string;
|
|
1158
1193
|
cleared: boolean;
|
|
1159
1194
|
};
|
|
1195
|
+
private fluorWithout;
|
|
1196
|
+
private thermoWithout;
|
|
1197
|
+
/** The UV / blacklight view setting. */
|
|
1198
|
+
getUvLight(): UvLightSettings;
|
|
1199
|
+
/** Layers that carry UV-fluorescent ink. */
|
|
1200
|
+
fluorescentLayerIds(): string[];
|
|
1201
|
+
/** Layers that carry thermochromic ink. */
|
|
1202
|
+
thermochromicLayerIds(): string[];
|
|
1203
|
+
/**
|
|
1204
|
+
* Switches or tunes the virtual UV / blacklight (`on`, `strength` 0..2, `ambient` 0..1). When
|
|
1205
|
+
* `on` is true, the composite dims to `ambient` and fluorescent ink (`brush.fluorescence`) glows
|
|
1206
|
+
* in its stroke colour with a Linear Dodge halo. Saved with the document, not an undo step.
|
|
1207
|
+
*/
|
|
1208
|
+
setUvLight(update: Partial<UvLightSettings>): UvLightSettings;
|
|
1209
|
+
/**
|
|
1210
|
+
* Reads the document's heat field: its temperature summary (`peak`, `mean`, `hotCells`) and,
|
|
1211
|
+
* when `points` are given (document pixels), the bilinearly sampled temperature (0..1) at each.
|
|
1212
|
+
*/
|
|
1213
|
+
getHeat(points?: readonly {
|
|
1214
|
+
x: number;
|
|
1215
|
+
y: number;
|
|
1216
|
+
}[]): HeatStats & {
|
|
1217
|
+
samples: HeatSample[];
|
|
1218
|
+
thermochromicLayerIds: string[];
|
|
1219
|
+
};
|
|
1220
|
+
/**
|
|
1221
|
+
* Warms (or with `temperature` 0 cools) the canvas heat field along `points` (document pixels)
|
|
1222
|
+
* with a soft brush of `radius` px (default 28) towards `temperature` 0..1 (default 1). Where
|
|
1223
|
+
* temperature reaches `HEAT_DRY_THRESHOLD` (0.5), any wet paint on those tiles dries at once.
|
|
1224
|
+
* One undo step.
|
|
1225
|
+
*/
|
|
1226
|
+
paintHeat(options: {
|
|
1227
|
+
points: readonly {
|
|
1228
|
+
x: number;
|
|
1229
|
+
y: number;
|
|
1230
|
+
}[];
|
|
1231
|
+
radius?: number;
|
|
1232
|
+
temperature?: number;
|
|
1233
|
+
}): HeatStats & {
|
|
1234
|
+
bounds: RasterRect | null;
|
|
1235
|
+
dried: Array<{
|
|
1236
|
+
layerId: string;
|
|
1237
|
+
bounds: RasterRect | null;
|
|
1238
|
+
}>;
|
|
1239
|
+
};
|
|
1240
|
+
/**
|
|
1241
|
+
* Advances the heat field by `steps` simulation steps (1..200, default 10): heat diffuses into
|
|
1242
|
+
* neighbouring cells and cools towards 0 by Newtonian cooling. Newly heated tiles above the dry
|
|
1243
|
+
* threshold dry any wet paint on them. Not an undo step (time passing never is).
|
|
1244
|
+
*/
|
|
1245
|
+
advanceHeat(stepsOrOptions?: number | {
|
|
1246
|
+
steps?: number;
|
|
1247
|
+
}): HeatStats & {
|
|
1248
|
+
steps: number;
|
|
1249
|
+
dried: Array<{
|
|
1250
|
+
layerId: string;
|
|
1251
|
+
bounds: RasterRect | null;
|
|
1252
|
+
}>;
|
|
1253
|
+
};
|
|
1254
|
+
/** Cools the whole canvas heat field to 0 at once (one undo step when anything was warm). */
|
|
1255
|
+
clearHeat(): {
|
|
1256
|
+
cleared: boolean;
|
|
1257
|
+
};
|
|
1258
|
+
/** Dries any wet paint on tiles where `field` is at or above `HEAT_DRY_THRESHOLD`. */
|
|
1259
|
+
private dryWetFromHeat;
|
|
1160
1260
|
/** The document's `thick` without these layers (as a spread: `{}` when unchanged). */
|
|
1161
1261
|
private thickWithout;
|
|
1162
1262
|
/** Where the light comes from for thick paint and metallic paper. */
|
|
1163
1263
|
getLighting(): PaintLighting;
|
|
1164
1264
|
/** Moves the light (thick paint and metallic paper are relit; nothing is repainted). Saved with the document, not an undo step. */
|
|
1165
1265
|
setLighting(update: Partial<PaintLighting>): PaintLighting;
|
|
1266
|
+
/** Where the viewer looks from for thin-film iridescence and specular highlights (-1..1; editor state, not saved with the document). */
|
|
1267
|
+
getViewTilt(): PaintViewTilt;
|
|
1268
|
+
/** Tilts the view vector for thin-film iridescence and specular highlights (-1..1; editor state, not saved with the document, not an undo step). */
|
|
1269
|
+
setViewTilt(update: Partial<PaintViewTilt>): PaintViewTilt;
|
|
1166
1270
|
/** A layer's relief: where it is, its highest point (0..255) and its tiles; `null` when it has none. */
|
|
1167
1271
|
reliefOf(layerId?: string): {
|
|
1168
1272
|
layerId: string;
|
|
@@ -1313,6 +1417,14 @@ export declare class PaintEditorController {
|
|
|
1313
1417
|
private tracingNode;
|
|
1314
1418
|
/** The layers with every wet layer dried where it is (what saving and exporting see). */
|
|
1315
1419
|
private driedLayers;
|
|
1420
|
+
/** The layers with thermochromic paint shifted toward its hot colour where the canvas is warm. */
|
|
1421
|
+
private thermoLayers;
|
|
1422
|
+
/**
|
|
1423
|
+
* Under the UV blacklight: every pixel layer's daylight paint dims to `uvLight.ambient`, any
|
|
1424
|
+
* fluorescent ink (`doc.fluor[id]`) glows in its own colour, and each fluorescent layer casts a
|
|
1425
|
+
* Linear Dodge (`::uv`) spill layer directly above it.
|
|
1426
|
+
*/
|
|
1427
|
+
private uvLayers;
|
|
1316
1428
|
/** The layers with thick paint lit (each thick layer's pixels replaced by its lit tiles). */
|
|
1317
1429
|
private litLayers;
|
|
1318
1430
|
/**
|
|
@@ -1690,8 +1802,94 @@ export declare class PaintEditorController {
|
|
|
1690
1802
|
removeMixingPad(id: string): SavedMixingPadInfo;
|
|
1691
1803
|
private mixingPadJSON;
|
|
1692
1804
|
private readMixingPad;
|
|
1805
|
+
/**
|
|
1806
|
+
* Hears each mutation once it has settled (`settle` seconds after the user's last mutation
|
|
1807
|
+
* stroke). Registering a listener marks an agent as connected (`state.hasMutationAgent`).
|
|
1808
|
+
*/
|
|
1809
|
+
onMutationRequest(listener: PaintMutationRequestListener): () => void;
|
|
1810
|
+
/** Marks whether a mutation-answering agent is connected (for hosts that wake agents via tools). */
|
|
1811
|
+
setMutationAgentConnected(connected: boolean): void;
|
|
1812
|
+
/** Attaches a `PaintDirector` so `answerMutation` and `readMutation` animate the agent's cursor. */
|
|
1813
|
+
setMutationDirector(director: PaintDirector | null): void;
|
|
1814
|
+
/** Lists pending mutations (or all mutations when `includeAll` is true). */
|
|
1815
|
+
listMutations(options?: {
|
|
1816
|
+
includeAll?: boolean;
|
|
1817
|
+
}): PaintMutationInfo[];
|
|
1818
|
+
/** One mutation by id (`undefined` when unknown). */
|
|
1819
|
+
getMutation(id: string): PaintMutationInfo | undefined;
|
|
1820
|
+
/**
|
|
1821
|
+
* Claims a mutation (`id`) and starts its fade. Returns the strokes (points, colour, brush), a
|
|
1822
|
+
* PNG of the area around them (`cropPng`), and a preview of the whole painting (`canvasPng`) so
|
|
1823
|
+
* the agent can choose where to answer. Refused if already claimed, answered or declined.
|
|
1824
|
+
*/
|
|
1825
|
+
readMutation(id: string, options?: {
|
|
1826
|
+
actor?: string;
|
|
1827
|
+
padding?: number;
|
|
1828
|
+
maxSide?: number;
|
|
1829
|
+
}): PaintMutationReadResult;
|
|
1830
|
+
/**
|
|
1831
|
+
* Paints the agent's answer to a claimed mutation (`id`). When a `PaintDirector` is attached (or
|
|
1832
|
+
* passed in `options`), the agent's cursor is seen painting live; all strokes commit as one undo
|
|
1833
|
+
* step with origin `agent:<id>`. A second answer to the same id is refused.
|
|
1834
|
+
*/
|
|
1835
|
+
answerMutation(id: string, input: PaintMutationAnswerInput, options?: {
|
|
1836
|
+
director?: PaintDirector;
|
|
1837
|
+
actor?: PresenceActorInfo;
|
|
1838
|
+
}): Promise<PaintMutationAnswerResult>;
|
|
1839
|
+
/**
|
|
1840
|
+
* Gives up on a mutation (`id`) without answering. The user's paint stays as ordinary paint (wet
|
|
1841
|
+
* strokes stay in the wet layer, and dry temporary layers merge down into their target layer).
|
|
1842
|
+
*/
|
|
1843
|
+
declineMutation(id: string, reason?: string): PaintMutationInfo;
|
|
1844
|
+
/**
|
|
1845
|
+
* Advances mutation timers (`settle`, `patience`, and dry temporary-layer `fade`) by `seconds`
|
|
1846
|
+
* of simulated time. Called automatically from `tickMutations` and `advanceWet`.
|
|
1847
|
+
*/
|
|
1848
|
+
advanceMutations(seconds: number): void;
|
|
1849
|
+
/** Steps mutation timers with the wall clock (`performance.now()`, in ms). */
|
|
1850
|
+
tickMutations(now: number): void;
|
|
1851
|
+
private toMutationInfo;
|
|
1852
|
+
private recordMutationStroke;
|
|
1853
|
+
private holdMutationEvaporation;
|
|
1854
|
+
private releaseMutationEvaporation;
|
|
1855
|
+
private finishWetMutationsOnDry;
|
|
1856
|
+
private expireMutation;
|
|
1857
|
+
private keepMutationPaint;
|
|
1858
|
+
private mergeTempLayerIntoTarget;
|
|
1859
|
+
private removeTempMutationLayer;
|
|
1860
|
+
private reconcileMutationsAfterUndo;
|
|
1861
|
+
private resetMutations;
|
|
1693
1862
|
/** A layer's tile surface (live while stroking), for thumbnails. */
|
|
1694
1863
|
layerSurface(id: string): TiledSurface | null;
|
|
1864
|
+
private proposalsStore;
|
|
1865
|
+
/** The pending paint proposals store attached to this editor (created on demand). */
|
|
1866
|
+
get proposals(): PaintProposals;
|
|
1867
|
+
/** Attaches an external `PaintProposals` store so tools and panels share it. */
|
|
1868
|
+
attachProposals(store: PaintProposals): void;
|
|
1869
|
+
/**
|
|
1870
|
+
* Breeds `count` (`2..12`, default `4`) mutated variants from `1..16` recorded strokes as
|
|
1871
|
+
* pending paint proposals, generated one after another through `previewPaint`.
|
|
1872
|
+
*/
|
|
1873
|
+
breedStrokes(options: {
|
|
1874
|
+
strokeIds: readonly string[];
|
|
1875
|
+
count?: number;
|
|
1876
|
+
mutation?: StrokeMutationRates;
|
|
1877
|
+
seed?: number;
|
|
1878
|
+
origin?: string;
|
|
1879
|
+
}): BreedStrokesResult;
|
|
1880
|
+
/**
|
|
1881
|
+
* Breeds `count` (`2..12`, default `4`) variants from `1` pending proposal (mutation) or `2`
|
|
1882
|
+
* pending proposals (crossover + mutation), generated one after another through `previewPaint`.
|
|
1883
|
+
*/
|
|
1884
|
+
breedProposal(options: {
|
|
1885
|
+
proposalIds: readonly string[];
|
|
1886
|
+
count?: number;
|
|
1887
|
+
mutation?: StrokeMutationRates;
|
|
1888
|
+
seed?: number;
|
|
1889
|
+
origin?: string;
|
|
1890
|
+
}): BreedStrokesResult;
|
|
1891
|
+
/** Returns the full stroke genome records (`RecordedStrokeJSON[]`) of a pending paint proposal. */
|
|
1892
|
+
getProposalGenome(proposalId: string): ProposalGenomeResult;
|
|
1695
1893
|
}
|
|
1696
1894
|
export type { Tile };
|
|
1697
1895
|
/** Largest tracing or reference image side, in pixels. */
|
|
@@ -22,6 +22,7 @@ import type { MultiColorSettings, PaintBrush } from './brushes.cjs';
|
|
|
22
22
|
import { type EffectPaintPixels } from './effect-paint.cjs';
|
|
23
23
|
import { type PenPoint, type StrokeCopy } from './engine.cjs';
|
|
24
24
|
import { type PaperGrain } from './paper.cjs';
|
|
25
|
+
import type { FilmBuffer } from './thick.cjs';
|
|
25
26
|
import type { StickerArtLookup } from './sticker-art.cjs';
|
|
26
27
|
export interface PaintDabStrokeOptions {
|
|
27
28
|
/** Where the stroke reads and writes pixels. */
|
|
@@ -42,6 +43,8 @@ export interface PaintDabStrokeOptions {
|
|
|
42
43
|
effect?: EffectPaintPixels | null;
|
|
43
44
|
/** Loaded sticker art, for a stamp tip of a sticker from the sticker library (`brush.stamp`). */
|
|
44
45
|
stampArt?: StickerArtLookup;
|
|
46
|
+
/** Thin-film iridescence channel for dab / mixer brushes with `iridescence`. */
|
|
47
|
+
film?: FilmBuffer | null;
|
|
45
48
|
}
|
|
46
49
|
/** Colours of a multi-colour brush, resolved against the paint and secondary colours. */
|
|
47
50
|
export declare function multiColorPalette(mc: MultiColorSettings, color: RgbTriple, secondary: RgbTriple): RgbTriple[];
|
|
@@ -22,6 +22,7 @@ import type { MultiColorSettings, PaintBrush } from './brushes.js';
|
|
|
22
22
|
import { type EffectPaintPixels } from './effect-paint.js';
|
|
23
23
|
import { type PenPoint, type StrokeCopy } from './engine.js';
|
|
24
24
|
import { type PaperGrain } from './paper.js';
|
|
25
|
+
import type { FilmBuffer } from './thick.js';
|
|
25
26
|
import type { StickerArtLookup } from './sticker-art.js';
|
|
26
27
|
export interface PaintDabStrokeOptions {
|
|
27
28
|
/** Where the stroke reads and writes pixels. */
|
|
@@ -42,6 +43,8 @@ export interface PaintDabStrokeOptions {
|
|
|
42
43
|
effect?: EffectPaintPixels | null;
|
|
43
44
|
/** Loaded sticker art, for a stamp tip of a sticker from the sticker library (`brush.stamp`). */
|
|
44
45
|
stampArt?: StickerArtLookup;
|
|
46
|
+
/** Thin-film iridescence channel for dab / mixer brushes with `iridescence`. */
|
|
47
|
+
film?: FilmBuffer | null;
|
|
45
48
|
}
|
|
46
49
|
/** Colours of a multi-colour brush, resolved against the paint and secondary colours. */
|
|
47
50
|
export declare function multiColorPalette(mc: MultiColorSettings, color: RgbTriple, secondary: RgbTriple): RgbTriple[];
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Saved documents are JSON plus PNG assets, through the image editor's layer serializer (so the
|
|
8
8
|
* same layer tree loads in both editors), with the paper as plain settings.
|
|
9
9
|
*/
|
|
10
|
-
import type { RasterGroupLayer,
|
|
10
|
+
import type { RasterGroupLayer, RasterPixelLayer } from '../raster/layers.cjs';
|
|
11
11
|
import { type TiledSurface } from '../raster/surface.cjs';
|
|
12
12
|
import { type PaperSettings } from './paper.cjs';
|
|
13
13
|
import type { RecordedStroke } from './strokes.cjs';
|
|
@@ -15,10 +15,14 @@ import type { WetEvent } from './wet.cjs';
|
|
|
15
15
|
import type { ThickChannels } from './thick.cjs';
|
|
16
16
|
import type { Sticker } from './stickers.cjs';
|
|
17
17
|
import type { PaintEffectSource, PaintPaperEffect } from './effects.cjs';
|
|
18
|
-
|
|
18
|
+
import type { HeatField } from './heat.cjs';
|
|
19
|
+
export type PaintPixelLayer = RasterPixelLayer & {
|
|
20
|
+
/** A temporary layer for a dry mutation stroke (fades on claim, merges down on timeout or save). */
|
|
21
|
+
temporary?: boolean;
|
|
22
|
+
};
|
|
19
23
|
export type PaintGroupLayer = RasterGroupLayer<PaintLayer>;
|
|
20
24
|
/** A layer of the paint editor: the shared stack's pixel layers and groups. */
|
|
21
|
-
export type PaintLayer =
|
|
25
|
+
export type PaintLayer = PaintPixelLayer | PaintGroupLayer;
|
|
22
26
|
/** Canvas size limits (pixels per side). */
|
|
23
27
|
export declare const MIN_CANVAS_SIDE = 1;
|
|
24
28
|
export declare const MAX_CANVAS_SIDE = 16384;
|
|
@@ -51,6 +55,12 @@ export interface PaintDocumentState {
|
|
|
51
55
|
liveStrokes?: Readonly<Record<string, RecordedStroke[]>>;
|
|
52
56
|
/** Light paint: each layer's light channel, 0..255 per pixel in layer space (layers without light are missing). See `light.ts`. */
|
|
53
57
|
light?: Readonly<Record<string, TiledSurface>>;
|
|
58
|
+
/** UV-fluorescent ink: each layer's 4-channel RGBA fluorescence surface in layer space (layers without fluorescence are missing). See `heat.ts`. */
|
|
59
|
+
fluor?: Readonly<Record<string, TiledSurface>>;
|
|
60
|
+
/** Thermochromic ink: each layer's 4-channel RGBA thermochromic surface (`[hotR, hotG, hotB, thresholdByte]`) in layer space. See `heat.ts`. */
|
|
61
|
+
thermo?: Readonly<Record<string, TiledSurface>>;
|
|
62
|
+
/** Coarse document-level heat field (1/4 resolution) for thermochromic ink and wet-paint drying. See `heat.ts`. */
|
|
63
|
+
heat?: HeatField;
|
|
54
64
|
/** Thick paint: each layer's height and material channels (layers without relief are missing). */
|
|
55
65
|
thick?: Readonly<Record<string, ThickChannels>>;
|
|
56
66
|
/** Effect layers: the provider effect each one is drawn from (layers that are gone are ignored). */
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Saved documents are JSON plus PNG assets, through the image editor's layer serializer (so the
|
|
8
8
|
* same layer tree loads in both editors), with the paper as plain settings.
|
|
9
9
|
*/
|
|
10
|
-
import type { RasterGroupLayer,
|
|
10
|
+
import type { RasterGroupLayer, RasterPixelLayer } from '../raster/layers.js';
|
|
11
11
|
import { type TiledSurface } from '../raster/surface.js';
|
|
12
12
|
import { type PaperSettings } from './paper.js';
|
|
13
13
|
import type { RecordedStroke } from './strokes.js';
|
|
@@ -15,10 +15,14 @@ import type { WetEvent } from './wet.js';
|
|
|
15
15
|
import type { ThickChannels } from './thick.js';
|
|
16
16
|
import type { Sticker } from './stickers.js';
|
|
17
17
|
import type { PaintEffectSource, PaintPaperEffect } from './effects.js';
|
|
18
|
-
|
|
18
|
+
import type { HeatField } from './heat.js';
|
|
19
|
+
export type PaintPixelLayer = RasterPixelLayer & {
|
|
20
|
+
/** A temporary layer for a dry mutation stroke (fades on claim, merges down on timeout or save). */
|
|
21
|
+
temporary?: boolean;
|
|
22
|
+
};
|
|
19
23
|
export type PaintGroupLayer = RasterGroupLayer<PaintLayer>;
|
|
20
24
|
/** A layer of the paint editor: the shared stack's pixel layers and groups. */
|
|
21
|
-
export type PaintLayer =
|
|
25
|
+
export type PaintLayer = PaintPixelLayer | PaintGroupLayer;
|
|
22
26
|
/** Canvas size limits (pixels per side). */
|
|
23
27
|
export declare const MIN_CANVAS_SIDE = 1;
|
|
24
28
|
export declare const MAX_CANVAS_SIDE = 16384;
|
|
@@ -51,6 +55,12 @@ export interface PaintDocumentState {
|
|
|
51
55
|
liveStrokes?: Readonly<Record<string, RecordedStroke[]>>;
|
|
52
56
|
/** Light paint: each layer's light channel, 0..255 per pixel in layer space (layers without light are missing). See `light.ts`. */
|
|
53
57
|
light?: Readonly<Record<string, TiledSurface>>;
|
|
58
|
+
/** UV-fluorescent ink: each layer's 4-channel RGBA fluorescence surface in layer space (layers without fluorescence are missing). See `heat.ts`. */
|
|
59
|
+
fluor?: Readonly<Record<string, TiledSurface>>;
|
|
60
|
+
/** Thermochromic ink: each layer's 4-channel RGBA thermochromic surface (`[hotR, hotG, hotB, thresholdByte]`) in layer space. See `heat.ts`. */
|
|
61
|
+
thermo?: Readonly<Record<string, TiledSurface>>;
|
|
62
|
+
/** Coarse document-level heat field (1/4 resolution) for thermochromic ink and wet-paint drying. See `heat.ts`. */
|
|
63
|
+
heat?: HeatField;
|
|
54
64
|
/** Thick paint: each layer's height and material channels (layers without relief are missing). */
|
|
55
65
|
thick?: Readonly<Record<string, ThickChannels>>;
|
|
56
66
|
/** Effect layers: the provider effect each one is drawn from (layers that are gone are ignored). */
|