@pixerate/editor 0.274.0 → 0.275.1
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/chart/contract.d.cts +3 -1
- package/dist/chart/contract.d.ts +3 -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/controller.d.cts +168 -1
- package/dist/paint-editor/controller.d.ts +168 -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/heat.d.cts +156 -0
- package/dist/paint-editor/heat.d.ts +156 -0
- package/dist/paint-editor/index.cjs +3386 -855
- package/dist/paint-editor/index.d.cts +3 -0
- package/dist/paint-editor/index.d.ts +3 -0
- package/dist/paint-editor/index.js +2731 -200
- 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 +34 -1
- package/dist/paint-editor/ui.d.ts +34 -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/pixerate-brushes/SKILL.md +1 -0
- package/skills/pixerate-paint-editor/SKILL.md +7 -1
- package/skills/pixerate-paint-editor/references/brush-facets.md +1 -0
- package/skills/pixerate-paint-editor/references/live-patterns.md +41 -0
- package/skills/pixerate-paint-watercolour/SKILL.md +8 -0
|
@@ -55,7 +55,11 @@ 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';
|
|
59
63
|
import { type PaintProposals } from './collaboration.cjs';
|
|
60
64
|
import { type BreedStrokesResult, type ProposalGenomeResult, type StrokeMutationRates } from './evolution.cjs';
|
|
61
65
|
export declare class PaintEditorError extends Error {
|
|
@@ -146,6 +150,8 @@ export interface PaintEditorState {
|
|
|
146
150
|
/** What the Mixer Brush carries between strokes. */
|
|
147
151
|
mixerLoad: MixerLoad;
|
|
148
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;
|
|
149
155
|
hand: Hand;
|
|
150
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. */
|
|
151
157
|
effectPlayback: {
|
|
@@ -173,6 +179,14 @@ export interface PaintEditorState {
|
|
|
173
179
|
stroking: boolean;
|
|
174
180
|
/** Wet media. */
|
|
175
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;
|
|
176
190
|
/** Increments on every change. */
|
|
177
191
|
version: number;
|
|
178
192
|
}
|
|
@@ -208,6 +222,8 @@ export interface PaintLayerInfo {
|
|
|
208
222
|
liveStrokes?: number;
|
|
209
223
|
/** How many live layer effects (glows, shadows, strokes…) it has, when any (`getLayerEffects`). */
|
|
210
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;
|
|
211
227
|
}
|
|
212
228
|
/** A live stroke as it is painted (`onStrokeSample`), for agents that paint along with the user. */
|
|
213
229
|
export interface PaintStrokeSample {
|
|
@@ -519,9 +535,17 @@ export declare class PaintEditorController {
|
|
|
519
535
|
private readonly wetOptions;
|
|
520
536
|
/** Where the light comes from for thick paint (saved with the document, not undo steps). */
|
|
521
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;
|
|
522
540
|
private readonly litCaches;
|
|
523
541
|
/** The live impasto stroke's channels. */
|
|
524
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;
|
|
525
549
|
/** Set while an operation that changes wet paint runs: the simulation before it (for undo). */
|
|
526
550
|
private wetOp;
|
|
527
551
|
/** The effects provider slot (see `setEffectsProvider`). */
|
|
@@ -536,6 +560,15 @@ export declare class PaintEditorController {
|
|
|
536
560
|
private readonly rasterizeSticker;
|
|
537
561
|
private readonly effectsRenderer;
|
|
538
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;
|
|
539
572
|
constructor(options?: PaintEditorOptions);
|
|
540
573
|
subscribe(listener: () => void): () => void;
|
|
541
574
|
/**
|
|
@@ -1159,12 +1192,81 @@ export declare class PaintEditorController {
|
|
|
1159
1192
|
layerId: string;
|
|
1160
1193
|
cleared: boolean;
|
|
1161
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;
|
|
1162
1260
|
/** The document's `thick` without these layers (as a spread: `{}` when unchanged). */
|
|
1163
1261
|
private thickWithout;
|
|
1164
1262
|
/** Where the light comes from for thick paint and metallic paper. */
|
|
1165
1263
|
getLighting(): PaintLighting;
|
|
1166
1264
|
/** Moves the light (thick paint and metallic paper are relit; nothing is repainted). Saved with the document, not an undo step. */
|
|
1167
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;
|
|
1168
1270
|
/** A layer's relief: where it is, its highest point (0..255) and its tiles; `null` when it has none. */
|
|
1169
1271
|
reliefOf(layerId?: string): {
|
|
1170
1272
|
layerId: string;
|
|
@@ -1315,6 +1417,14 @@ export declare class PaintEditorController {
|
|
|
1315
1417
|
private tracingNode;
|
|
1316
1418
|
/** The layers with every wet layer dried where it is (what saving and exporting see). */
|
|
1317
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;
|
|
1318
1428
|
/** The layers with thick paint lit (each thick layer's pixels replaced by its lit tiles). */
|
|
1319
1429
|
private litLayers;
|
|
1320
1430
|
/**
|
|
@@ -1692,6 +1802,63 @@ export declare class PaintEditorController {
|
|
|
1692
1802
|
removeMixingPad(id: string): SavedMixingPadInfo;
|
|
1693
1803
|
private mixingPadJSON;
|
|
1694
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;
|
|
1695
1862
|
/** A layer's tile surface (live while stroking), for thumbnails. */
|
|
1696
1863
|
layerSurface(id: string): TiledSurface | null;
|
|
1697
1864
|
private proposalsStore;
|
|
@@ -55,7 +55,11 @@ 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';
|
|
59
63
|
import { type PaintProposals } from './collaboration.js';
|
|
60
64
|
import { type BreedStrokesResult, type ProposalGenomeResult, type StrokeMutationRates } from './evolution.js';
|
|
61
65
|
export declare class PaintEditorError extends Error {
|
|
@@ -146,6 +150,8 @@ export interface PaintEditorState {
|
|
|
146
150
|
/** What the Mixer Brush carries between strokes. */
|
|
147
151
|
mixerLoad: MixerLoad;
|
|
148
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;
|
|
149
155
|
hand: Hand;
|
|
150
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. */
|
|
151
157
|
effectPlayback: {
|
|
@@ -173,6 +179,14 @@ export interface PaintEditorState {
|
|
|
173
179
|
stroking: boolean;
|
|
174
180
|
/** Wet media. */
|
|
175
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;
|
|
176
190
|
/** Increments on every change. */
|
|
177
191
|
version: number;
|
|
178
192
|
}
|
|
@@ -208,6 +222,8 @@ export interface PaintLayerInfo {
|
|
|
208
222
|
liveStrokes?: number;
|
|
209
223
|
/** How many live layer effects (glows, shadows, strokes…) it has, when any (`getLayerEffects`). */
|
|
210
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;
|
|
211
227
|
}
|
|
212
228
|
/** A live stroke as it is painted (`onStrokeSample`), for agents that paint along with the user. */
|
|
213
229
|
export interface PaintStrokeSample {
|
|
@@ -519,9 +535,17 @@ export declare class PaintEditorController {
|
|
|
519
535
|
private readonly wetOptions;
|
|
520
536
|
/** Where the light comes from for thick paint (saved with the document, not undo steps). */
|
|
521
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;
|
|
522
540
|
private readonly litCaches;
|
|
523
541
|
/** The live impasto stroke's channels. */
|
|
524
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;
|
|
525
549
|
/** Set while an operation that changes wet paint runs: the simulation before it (for undo). */
|
|
526
550
|
private wetOp;
|
|
527
551
|
/** The effects provider slot (see `setEffectsProvider`). */
|
|
@@ -536,6 +560,15 @@ export declare class PaintEditorController {
|
|
|
536
560
|
private readonly rasterizeSticker;
|
|
537
561
|
private readonly effectsRenderer;
|
|
538
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;
|
|
539
572
|
constructor(options?: PaintEditorOptions);
|
|
540
573
|
subscribe(listener: () => void): () => void;
|
|
541
574
|
/**
|
|
@@ -1159,12 +1192,81 @@ export declare class PaintEditorController {
|
|
|
1159
1192
|
layerId: string;
|
|
1160
1193
|
cleared: boolean;
|
|
1161
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;
|
|
1162
1260
|
/** The document's `thick` without these layers (as a spread: `{}` when unchanged). */
|
|
1163
1261
|
private thickWithout;
|
|
1164
1262
|
/** Where the light comes from for thick paint and metallic paper. */
|
|
1165
1263
|
getLighting(): PaintLighting;
|
|
1166
1264
|
/** Moves the light (thick paint and metallic paper are relit; nothing is repainted). Saved with the document, not an undo step. */
|
|
1167
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;
|
|
1168
1270
|
/** A layer's relief: where it is, its highest point (0..255) and its tiles; `null` when it has none. */
|
|
1169
1271
|
reliefOf(layerId?: string): {
|
|
1170
1272
|
layerId: string;
|
|
@@ -1315,6 +1417,14 @@ export declare class PaintEditorController {
|
|
|
1315
1417
|
private tracingNode;
|
|
1316
1418
|
/** The layers with every wet layer dried where it is (what saving and exporting see). */
|
|
1317
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;
|
|
1318
1428
|
/** The layers with thick paint lit (each thick layer's pixels replaced by its lit tiles). */
|
|
1319
1429
|
private litLayers;
|
|
1320
1430
|
/**
|
|
@@ -1692,6 +1802,63 @@ export declare class PaintEditorController {
|
|
|
1692
1802
|
removeMixingPad(id: string): SavedMixingPadInfo;
|
|
1693
1803
|
private mixingPadJSON;
|
|
1694
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;
|
|
1695
1862
|
/** A layer's tile surface (live while stroking), for thumbnails. */
|
|
1696
1863
|
layerSurface(id: string): TiledSurface | null;
|
|
1697
1864
|
private proposalsStore;
|
|
@@ -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). */
|
|
@@ -20,6 +20,7 @@ import type { PaintBrush } from './brushes.cjs';
|
|
|
20
20
|
import { type EffectPaintPixels } from './effect-paint.cjs';
|
|
21
21
|
import type { StickerArtLookup } from './sticker-art.cjs';
|
|
22
22
|
import { type PaperGrain } from './paper.cjs';
|
|
23
|
+
import type { FilmBuffer } from './thick.cjs';
|
|
23
24
|
/** One pen sample in document pixels. Every channel but x and y is optional. */
|
|
24
25
|
export interface PenPoint {
|
|
25
26
|
x: number;
|
|
@@ -136,6 +137,8 @@ export interface DryStrokeOptions {
|
|
|
136
137
|
* tip grain (`brush.tipGrain.source`); without it such a tip paints round, and the grain is left out.
|
|
137
138
|
*/
|
|
138
139
|
stampArt?: StickerArtLookup;
|
|
140
|
+
/** Thin-film iridescence channel for dry brushes with `iridescence` (or eraser). */
|
|
141
|
+
film?: FilmBuffer | null;
|
|
139
142
|
}
|
|
140
143
|
/**
|
|
141
144
|
* One dab-engine stroke (dab and eraser brushes): smoothing, the dab walk of every copy, grain and
|
|
@@ -20,6 +20,7 @@ import type { PaintBrush } from './brushes.js';
|
|
|
20
20
|
import { type EffectPaintPixels } from './effect-paint.js';
|
|
21
21
|
import type { StickerArtLookup } from './sticker-art.js';
|
|
22
22
|
import { type PaperGrain } from './paper.js';
|
|
23
|
+
import type { FilmBuffer } from './thick.js';
|
|
23
24
|
/** One pen sample in document pixels. Every channel but x and y is optional. */
|
|
24
25
|
export interface PenPoint {
|
|
25
26
|
x: number;
|
|
@@ -136,6 +137,8 @@ export interface DryStrokeOptions {
|
|
|
136
137
|
* tip grain (`brush.tipGrain.source`); without it such a tip paints round, and the grain is left out.
|
|
137
138
|
*/
|
|
138
139
|
stampArt?: StickerArtLookup;
|
|
140
|
+
/** Thin-film iridescence channel for dry brushes with `iridescence` (or eraser). */
|
|
141
|
+
film?: FilmBuffer | null;
|
|
139
142
|
}
|
|
140
143
|
/**
|
|
141
144
|
* One dab-engine stroke (dab and eraser brushes): smoothing, the dab walk of every copy, grain and
|