@pixerate/editor 0.246.0 → 0.249.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/README.md +1 -0
- package/dist/animation-editor/index.cjs +64 -61
- package/dist/animation-editor/index.js +8 -5
- package/dist/{brushstrokeRender-ZDHMXJAE.cjs → brushstrokeRender-GCKK7V2I.cjs} +14 -11
- package/dist/{brushstrokeRender-AKUI3SEJ.js → brushstrokeRender-T3JZST44.js} +7 -4
- package/dist/canvas/index.cjs +8 -8
- package/dist/canvas/index.js +1 -1
- package/dist/{chunk-UVPD55UZ.cjs → chunk-2SMMZDMG.cjs} +35 -35
- package/dist/chunk-2VJAVXLI.js +192 -0
- package/dist/{chunk-OLNIPTB3.cjs → chunk-2VX55NFM.cjs} +1 -320
- package/dist/chunk-3K6HWEXZ.cjs +92 -0
- package/dist/{chunk-UOOK7HTX.js → chunk-3PPJRMIG.js} +1 -1
- package/dist/chunk-4D6KP5BV.js +92 -0
- package/dist/chunk-5RH3VXAK.js +269 -0
- package/dist/{chunk-LDPLEZ5T.js → chunk-6BIDVPED.js} +1 -1
- package/dist/{chunk-2ONK3ERD.cjs → chunk-75K3W4D6.cjs} +20 -20
- package/dist/chunk-BOHDJJ2O.cjs +192 -0
- package/dist/{chunk-2PBZBRP5.js → chunk-D5KGAO4Z.js} +10 -92
- package/dist/{chunk-DQWPMGH2.js → chunk-DOIU7VJG.js} +1 -1
- package/dist/{chunk-HB4ICNNA.cjs → chunk-DPYAO5U6.cjs} +42 -42
- package/dist/chunk-EJLRBS5Q.js +301 -0
- package/dist/{chunk-Q2UYUWAZ.cjs → chunk-H4AOUUBE.cjs} +679 -164
- package/dist/{chunk-PQ3H2AAN.cjs → chunk-I7NJPHWV.cjs} +122 -204
- package/dist/{chunk-FK5LTDOO.cjs → chunk-IOFVM3L3.cjs} +7 -7
- package/dist/{chunk-42TWUPNJ.js → chunk-IRSTHLQQ.js} +1 -320
- package/dist/{chunk-VDAWA546.js → chunk-J7T5QZ45.js} +614 -99
- package/dist/{chunk-VMROIWLL.cjs → chunk-KBYB7OWB.cjs} +3 -3
- package/dist/{chunk-5MFDD7SP.cjs → chunk-KYX7NZ5V.cjs} +1 -1
- package/dist/chunk-LJRCU3BJ.cjs +301 -0
- package/dist/{chunk-XTWXBQD4.cjs → chunk-LP2MCSBE.cjs} +593 -236
- package/dist/{chunk-A23PSOBB.js → chunk-O75V4ZS3.js} +1 -1
- package/dist/chunk-OTTT5N3K.js +322 -0
- package/dist/{chunk-N6WUB3Y5.js → chunk-PZP2SZIZ.js} +2 -2
- package/dist/{chunk-4PMCMWQS.js → chunk-UBRJOIR5.js} +367 -10
- package/dist/chunk-W5M3J7PV.cjs +322 -0
- package/dist/{chunk-4P6H35HU.js → chunk-WA44NKPF.js} +2 -2
- package/dist/{chunk-CEPKXLBS.cjs → chunk-WLJZZHUZ.cjs} +23 -23
- package/dist/{chunk-P3NIPIKS.js → chunk-WQCNC4DK.js} +1 -1
- package/dist/chunk-ZEYMKDYS.cjs +269 -0
- package/dist/image-editor/effect-tools.d.cts +37 -4
- package/dist/image-editor/effect-tools.d.ts +37 -4
- package/dist/image-editor/index.cjs +1340 -1828
- package/dist/image-editor/index.d.cts +1 -1
- package/dist/image-editor/index.d.ts +1 -1
- package/dist/image-editor/index.js +298 -786
- package/dist/paint/index.cjs +8 -5
- package/dist/paint/index.js +13 -10
- package/dist/paint-editor/controller.d.cts +71 -2
- package/dist/paint-editor/controller.d.ts +71 -2
- package/dist/paint-editor/index.cjs +901 -589
- package/dist/paint-editor/index.d.cts +3 -0
- package/dist/paint-editor/index.d.ts +3 -0
- package/dist/paint-editor/index.js +365 -53
- package/dist/paint-editor/procedural.d.cts +82 -5
- package/dist/paint-editor/procedural.d.ts +82 -5
- package/dist/paint-editor/sticker-art.d.cts +55 -0
- package/dist/paint-editor/sticker-art.d.ts +55 -0
- package/dist/paint-editor/stickers.d.cts +30 -17
- package/dist/paint-editor/stickers.d.ts +30 -17
- package/dist/paint-editor/stroke.d.cts +4 -0
- package/dist/paint-editor/stroke.d.ts +4 -0
- package/dist/paint-editor/tools.d.cts +1 -1
- package/dist/paint-editor/tools.d.ts +1 -1
- package/dist/paint-editor/ui.d.cts +25 -4
- package/dist/paint-editor/ui.d.ts +25 -4
- package/dist/{image-editor/layers/effects-ui.d.cts → raster/effects/ui.d.cts} +32 -5
- package/dist/{image-editor/layers/effects-ui.d.ts → raster/effects/ui.d.ts} +32 -5
- package/dist/raster/index.cjs +17 -3
- package/dist/raster/index.d.cts +1 -0
- package/dist/raster/index.d.ts +1 -0
- package/dist/raster/index.js +23 -9
- package/dist/stickers/browser.d.cts +48 -0
- package/dist/stickers/browser.d.ts +48 -0
- package/dist/stickers/combine.d.cts +10 -0
- package/dist/stickers/combine.d.ts +10 -0
- package/dist/stickers/conformance.d.cts +18 -0
- package/dist/stickers/conformance.d.ts +18 -0
- package/dist/stickers/editor.d.cts +14 -0
- package/dist/stickers/editor.d.ts +14 -0
- package/dist/stickers/errors.d.cts +6 -0
- package/dist/stickers/errors.d.ts +6 -0
- package/dist/stickers/fake.d.cts +16 -0
- package/dist/stickers/fake.d.ts +16 -0
- package/dist/stickers/helpers.d.cts +51 -0
- package/dist/stickers/helpers.d.ts +51 -0
- package/dist/stickers/index.cjs +331 -0
- package/dist/stickers/index.d.cts +16 -0
- package/dist/stickers/index.d.ts +16 -0
- package/dist/stickers/index.js +331 -0
- package/dist/stickers/stamps.d.cts +13 -0
- package/dist/stickers/stamps.d.ts +13 -0
- package/dist/stickers/tools.d.cts +25 -0
- package/dist/stickers/tools.d.ts +25 -0
- package/dist/stickers/types.d.cts +123 -0
- package/dist/stickers/types.d.ts +123 -0
- package/dist/vector/index.cjs +978 -975
- package/dist/vector/index.js +9 -6
- package/package.json +11 -1
- package/skills/README.md +1 -0
- package/skills/pixerate-paint-editor/SKILL.md +26 -32
- package/skills/pixerate-paint-editor/references/gradient-paint.md +23 -0
- package/skills/pixerate-paint-editor/references/layer-effects.md +28 -0
- package/skills/pixerate-paint-editor/references/light-paint.md +10 -2
- package/skills/pixerate-paint-editor/references/particle-brushes.md +66 -0
- package/skills/pixerate-stickers/SKILL.md +45 -0
|
@@ -6,8 +6,12 @@
|
|
|
6
6
|
* rules. `string`: strands of masses on springs, dragged behind the pen like hair or wet string;
|
|
7
7
|
* `spring`: each particle tied to the pen by a spring, overshooting and wobbling; `orbit`:
|
|
8
8
|
* particles circling the pen (spirograph curls); `flow`: particles thrown off the pen and carried
|
|
9
|
-
* by a swirling flow field until they fade
|
|
10
|
-
* `
|
|
9
|
+
* by a swirling flow field until they fade; `elastic`: strands whose masses keep a rest length,
|
|
10
|
+
* stretching when the pen is fast and snapping back; `fuzzy`: strings that wind, each strand
|
|
11
|
+
* waving out of step with the others. Each is drawn as `dot`s (round, or stamped with up to four
|
|
12
|
+
* textures), a continuous `line`, a `sequence` of beads spaced along its path, or a `ribbon`:
|
|
13
|
+
* the area between neighbouring particles' paths filled, with their paths as its edges. Any kind
|
|
14
|
+
* can wave: each particle's drawn place moves sideways on a sine along the pen's path.
|
|
11
15
|
* - **Bristle brushes** (`engine: 'bristle'`): a tuft of bristles, each its own thin line. Pressure
|
|
12
16
|
* splays the tuft, tilt flattens it, and bristles lag behind the tip by their stiffness, so they
|
|
13
17
|
* bend into curves at turns; each bristle carries its own paint and runs dry at its own pace, so
|
|
@@ -19,11 +23,12 @@
|
|
|
19
23
|
*/
|
|
20
24
|
import { CoverageMap } from '../paint/brush.cjs';
|
|
21
25
|
import { type PaintGradientSource } from '../paint/gradient-paint.cjs';
|
|
22
|
-
import type
|
|
26
|
+
import { type RasterRect } from '../raster/surface.cjs';
|
|
23
27
|
import type { PaintBrush } from './brushes.cjs';
|
|
24
28
|
import { type EffectPaintPixels } from './effect-paint.cjs';
|
|
25
29
|
import { PenDabWalker, PenSmoother, type PenDab, type PenPoint, type StrokeCopy } from './engine.cjs';
|
|
26
30
|
import { type PaperGrain } from './paper.cjs';
|
|
31
|
+
import { type StampKind } from './stickers.cjs';
|
|
27
32
|
export interface ProceduralStrokeOptions {
|
|
28
33
|
grain: PaperGrain | null;
|
|
29
34
|
paperDepth: number;
|
|
@@ -71,13 +76,36 @@ declare abstract class MarkStroke implements CoverageStroke {
|
|
|
71
76
|
protected abstract advance(copy: number, d: PenDab, rects: RasterRect[]): void;
|
|
72
77
|
/** Stamps one round mark of radius `r` at (x, y) with flow `alpha` towards `opacity`. */
|
|
73
78
|
protected mark(x: number, y: number, r: number, alpha: number, opacity: number, pressure: number, rects: RasterRect[]): void;
|
|
79
|
+
/**
|
|
80
|
+
* Stamps a textured mark: `kind` from the sticker stamps over a square of half-size `r`, turned
|
|
81
|
+
* `rotation` radians clockwise, with flow `alpha` towards `opacity`. Small marks are supersampled.
|
|
82
|
+
*/
|
|
83
|
+
protected stamp(x: number, y: number, r: number, kind: StampKind, rotation: number, seed: number, alpha: number, opacity: number, pressure: number, rects: RasterRect[]): void;
|
|
84
|
+
/** A scratch buffer of `n` values (reused; valid until the next mark). */
|
|
85
|
+
protected scratch(n: number): Float32Array;
|
|
86
|
+
/**
|
|
87
|
+
* Lays coverage `vals` over `rect` towards `opacity`: paper grain, then effect paint or the
|
|
88
|
+
* colour of a mark at (x, y) (gradient paint), into the stroke's coverage.
|
|
89
|
+
*/
|
|
90
|
+
protected lay(rect: RasterRect, vals: Float32Array, opacity: number, pressure: number, x: number, y: number, rects: RasterRect[]): void;
|
|
74
91
|
/** Marks along a segment, spaced by a fraction of the radius. */
|
|
75
92
|
protected segment(x0: number, y0: number, x1: number, y1: number, r: number, alpha: number, opacity: number, pressure: number, rects: RasterRect[]): void;
|
|
76
93
|
}
|
|
77
|
-
export type ParticleKind = 'string' | 'spring' | 'orbit' | 'flow';
|
|
94
|
+
export type ParticleKind = 'string' | 'spring' | 'orbit' | 'flow' | 'elastic' | 'fuzzy';
|
|
78
95
|
export declare const PARTICLE_KINDS: readonly ParticleKind[];
|
|
79
|
-
export type ParticleRender = 'dot' | 'line' | 'sequence';
|
|
96
|
+
export type ParticleRender = 'dot' | 'line' | 'sequence' | 'ribbon';
|
|
80
97
|
export declare const PARTICLE_RENDERS: readonly ParticleRender[];
|
|
98
|
+
/** Ribbon: which particles' paths are joined (`adjacent`: each to its neighbour; `first-last`: one band between the outermost two). */
|
|
99
|
+
export type RibbonPairs = 'adjacent' | 'first-last';
|
|
100
|
+
export declare const RIBBON_PAIRS: readonly RibbonPairs[];
|
|
101
|
+
/** Textured dots: the stamps in turn, or one picked at random (seeded) per dot. */
|
|
102
|
+
export type DotTextureOrder = 'sequence' | 'random';
|
|
103
|
+
export declare const DOT_TEXTURE_ORDERS: readonly DotTextureOrder[];
|
|
104
|
+
/** Textured dots: turned with the particle's motion, at random, or at the tip angle. */
|
|
105
|
+
export type DotRotation = 'follow' | 'random' | 'fixed';
|
|
106
|
+
export declare const DOT_ROTATIONS: readonly DotRotation[];
|
|
107
|
+
/** Textured dots: at most this many stamps. */
|
|
108
|
+
export declare const MAX_DOT_TEXTURES = 4;
|
|
81
109
|
/** Particle engine settings (each 0..1 unless noted). */
|
|
82
110
|
export interface ParticleSettings {
|
|
83
111
|
kind: ParticleKind;
|
|
@@ -100,17 +128,66 @@ export interface ParticleSettings {
|
|
|
100
128
|
life: number;
|
|
101
129
|
/** Sequence: spacing of the beads along each path. */
|
|
102
130
|
interval: number;
|
|
131
|
+
/** Ribbon: opacity of the fill between the paths, relative to their edges. */
|
|
132
|
+
ribbonFill: number;
|
|
133
|
+
/** Ribbon: which paths are joined. */
|
|
134
|
+
ribbonPairs: RibbonPairs;
|
|
135
|
+
/** Wave: how far each particle's drawn place swings sideways, as a fraction of the tip size (0: no wave). */
|
|
136
|
+
waveAmplitude: number;
|
|
137
|
+
/** Wave: wavelength in px of pen travel, 4..2000. */
|
|
138
|
+
waveLength: number;
|
|
139
|
+
/** Wave: how fast the waves run (0: they stand still on the path; 1: about four a second while the pen moves). */
|
|
140
|
+
waveSpeed: number;
|
|
141
|
+
/** Wave: how far out of step the particles' waves are (0: all in step; 1: random phases). */
|
|
142
|
+
wavePhaseJitter: number;
|
|
143
|
+
/** Dots and beads: up to four sticker stamps drawn instead of round marks (empty: round). */
|
|
144
|
+
dotTextures: StampKind[];
|
|
145
|
+
dotTextureOrder: DotTextureOrder;
|
|
146
|
+
dotRotation: DotRotation;
|
|
103
147
|
}
|
|
104
148
|
export declare const DEFAULT_PARTICLE: Readonly<ParticleSettings>;
|
|
105
149
|
export declare function normalizeParticle(raw?: Partial<ParticleSettings>, base?: ParticleSettings): ParticleSettings;
|
|
150
|
+
/**
|
|
151
|
+
* Adds the area polygon `pts` (x, y pairs, even-odd) covers in each pixel of `rect`, times `weight`, to `out`,
|
|
152
|
+
* exactly across each of `RIBBON_SUB` sub-rows per row. Points on an edge two polygons share
|
|
153
|
+
* count for exactly one of them, so polygons that tile a region add up to it with no seams.
|
|
154
|
+
*/
|
|
155
|
+
export declare function addPolygonArea(pts: readonly number[], rect: RasterRect, out: Float32Array, weight?: number): void;
|
|
106
156
|
/** A particle-brush stroke. */
|
|
107
157
|
export declare class ParticleStroke extends MarkStroke {
|
|
108
158
|
private readonly sets;
|
|
159
|
+
/** Ribbon pairs per copy: particles in their order around the pen (non-flow kinds). */
|
|
160
|
+
private readonly orders;
|
|
109
161
|
private readonly s;
|
|
110
162
|
private spawn;
|
|
163
|
+
/** Textured dots drawn so far, per copy (sequence order, random picks). */
|
|
164
|
+
private readonly dots;
|
|
165
|
+
/** Ribbon fill: the area each pixel has had so far this stroke (telescoped into the coverage). */
|
|
166
|
+
private readonly filled;
|
|
167
|
+
private pts;
|
|
111
168
|
constructor(brush: PaintBrush, options: ProceduralStrokeOptions);
|
|
169
|
+
/** Strand kinds: a chain of masses behind each particle. */
|
|
170
|
+
private get strands();
|
|
171
|
+
private newParticle;
|
|
112
172
|
private init;
|
|
173
|
+
/** The sideways wave of particle `p` at pen dab `d` (px along the normal to the pen's direction). */
|
|
174
|
+
private wave;
|
|
113
175
|
protected advance(copy: number, d: PenDab, rects: RasterRect[]): void;
|
|
176
|
+
/** A dot (or bead): round, or a textured stamp turned by the particle's motion (mx, my), at random or to the tip angle. */
|
|
177
|
+
private dot;
|
|
178
|
+
/**
|
|
179
|
+
* Ribbon fill for one step: the band between each pair of joined particles, from where they
|
|
180
|
+
* were drawn last step to where they are drawn now. Bands of one step, and of consecutive steps,
|
|
181
|
+
* share edges exactly, so the fill has no seams; it is telescoped into the coverage
|
|
182
|
+
* (`telescope`), so it does not build up at the joins.
|
|
183
|
+
*/
|
|
184
|
+
private ribbon;
|
|
185
|
+
/**
|
|
186
|
+
* Turns the area newly filled over `rect` into coverage to lay towards the fill's ceiling: the
|
|
187
|
+
* share of what was left unfilled, so after any number of bands (in any grouping) a pixel's
|
|
188
|
+
* coverage is the ceiling times the area filled there. False when nothing was added.
|
|
189
|
+
*/
|
|
190
|
+
private telescope;
|
|
114
191
|
}
|
|
115
192
|
/** Bristle engine settings (each 0..1 unless noted). */
|
|
116
193
|
export interface BristleSettings {
|
|
@@ -6,8 +6,12 @@
|
|
|
6
6
|
* rules. `string`: strands of masses on springs, dragged behind the pen like hair or wet string;
|
|
7
7
|
* `spring`: each particle tied to the pen by a spring, overshooting and wobbling; `orbit`:
|
|
8
8
|
* particles circling the pen (spirograph curls); `flow`: particles thrown off the pen and carried
|
|
9
|
-
* by a swirling flow field until they fade
|
|
10
|
-
* `
|
|
9
|
+
* by a swirling flow field until they fade; `elastic`: strands whose masses keep a rest length,
|
|
10
|
+
* stretching when the pen is fast and snapping back; `fuzzy`: strings that wind, each strand
|
|
11
|
+
* waving out of step with the others. Each is drawn as `dot`s (round, or stamped with up to four
|
|
12
|
+
* textures), a continuous `line`, a `sequence` of beads spaced along its path, or a `ribbon`:
|
|
13
|
+
* the area between neighbouring particles' paths filled, with their paths as its edges. Any kind
|
|
14
|
+
* can wave: each particle's drawn place moves sideways on a sine along the pen's path.
|
|
11
15
|
* - **Bristle brushes** (`engine: 'bristle'`): a tuft of bristles, each its own thin line. Pressure
|
|
12
16
|
* splays the tuft, tilt flattens it, and bristles lag behind the tip by their stiffness, so they
|
|
13
17
|
* bend into curves at turns; each bristle carries its own paint and runs dry at its own pace, so
|
|
@@ -19,11 +23,12 @@
|
|
|
19
23
|
*/
|
|
20
24
|
import { CoverageMap } from '../paint/brush.js';
|
|
21
25
|
import { type PaintGradientSource } from '../paint/gradient-paint.js';
|
|
22
|
-
import type
|
|
26
|
+
import { type RasterRect } from '../raster/surface.js';
|
|
23
27
|
import type { PaintBrush } from './brushes.js';
|
|
24
28
|
import { type EffectPaintPixels } from './effect-paint.js';
|
|
25
29
|
import { PenDabWalker, PenSmoother, type PenDab, type PenPoint, type StrokeCopy } from './engine.js';
|
|
26
30
|
import { type PaperGrain } from './paper.js';
|
|
31
|
+
import { type StampKind } from './stickers.js';
|
|
27
32
|
export interface ProceduralStrokeOptions {
|
|
28
33
|
grain: PaperGrain | null;
|
|
29
34
|
paperDepth: number;
|
|
@@ -71,13 +76,36 @@ declare abstract class MarkStroke implements CoverageStroke {
|
|
|
71
76
|
protected abstract advance(copy: number, d: PenDab, rects: RasterRect[]): void;
|
|
72
77
|
/** Stamps one round mark of radius `r` at (x, y) with flow `alpha` towards `opacity`. */
|
|
73
78
|
protected mark(x: number, y: number, r: number, alpha: number, opacity: number, pressure: number, rects: RasterRect[]): void;
|
|
79
|
+
/**
|
|
80
|
+
* Stamps a textured mark: `kind` from the sticker stamps over a square of half-size `r`, turned
|
|
81
|
+
* `rotation` radians clockwise, with flow `alpha` towards `opacity`. Small marks are supersampled.
|
|
82
|
+
*/
|
|
83
|
+
protected stamp(x: number, y: number, r: number, kind: StampKind, rotation: number, seed: number, alpha: number, opacity: number, pressure: number, rects: RasterRect[]): void;
|
|
84
|
+
/** A scratch buffer of `n` values (reused; valid until the next mark). */
|
|
85
|
+
protected scratch(n: number): Float32Array;
|
|
86
|
+
/**
|
|
87
|
+
* Lays coverage `vals` over `rect` towards `opacity`: paper grain, then effect paint or the
|
|
88
|
+
* colour of a mark at (x, y) (gradient paint), into the stroke's coverage.
|
|
89
|
+
*/
|
|
90
|
+
protected lay(rect: RasterRect, vals: Float32Array, opacity: number, pressure: number, x: number, y: number, rects: RasterRect[]): void;
|
|
74
91
|
/** Marks along a segment, spaced by a fraction of the radius. */
|
|
75
92
|
protected segment(x0: number, y0: number, x1: number, y1: number, r: number, alpha: number, opacity: number, pressure: number, rects: RasterRect[]): void;
|
|
76
93
|
}
|
|
77
|
-
export type ParticleKind = 'string' | 'spring' | 'orbit' | 'flow';
|
|
94
|
+
export type ParticleKind = 'string' | 'spring' | 'orbit' | 'flow' | 'elastic' | 'fuzzy';
|
|
78
95
|
export declare const PARTICLE_KINDS: readonly ParticleKind[];
|
|
79
|
-
export type ParticleRender = 'dot' | 'line' | 'sequence';
|
|
96
|
+
export type ParticleRender = 'dot' | 'line' | 'sequence' | 'ribbon';
|
|
80
97
|
export declare const PARTICLE_RENDERS: readonly ParticleRender[];
|
|
98
|
+
/** Ribbon: which particles' paths are joined (`adjacent`: each to its neighbour; `first-last`: one band between the outermost two). */
|
|
99
|
+
export type RibbonPairs = 'adjacent' | 'first-last';
|
|
100
|
+
export declare const RIBBON_PAIRS: readonly RibbonPairs[];
|
|
101
|
+
/** Textured dots: the stamps in turn, or one picked at random (seeded) per dot. */
|
|
102
|
+
export type DotTextureOrder = 'sequence' | 'random';
|
|
103
|
+
export declare const DOT_TEXTURE_ORDERS: readonly DotTextureOrder[];
|
|
104
|
+
/** Textured dots: turned with the particle's motion, at random, or at the tip angle. */
|
|
105
|
+
export type DotRotation = 'follow' | 'random' | 'fixed';
|
|
106
|
+
export declare const DOT_ROTATIONS: readonly DotRotation[];
|
|
107
|
+
/** Textured dots: at most this many stamps. */
|
|
108
|
+
export declare const MAX_DOT_TEXTURES = 4;
|
|
81
109
|
/** Particle engine settings (each 0..1 unless noted). */
|
|
82
110
|
export interface ParticleSettings {
|
|
83
111
|
kind: ParticleKind;
|
|
@@ -100,17 +128,66 @@ export interface ParticleSettings {
|
|
|
100
128
|
life: number;
|
|
101
129
|
/** Sequence: spacing of the beads along each path. */
|
|
102
130
|
interval: number;
|
|
131
|
+
/** Ribbon: opacity of the fill between the paths, relative to their edges. */
|
|
132
|
+
ribbonFill: number;
|
|
133
|
+
/** Ribbon: which paths are joined. */
|
|
134
|
+
ribbonPairs: RibbonPairs;
|
|
135
|
+
/** Wave: how far each particle's drawn place swings sideways, as a fraction of the tip size (0: no wave). */
|
|
136
|
+
waveAmplitude: number;
|
|
137
|
+
/** Wave: wavelength in px of pen travel, 4..2000. */
|
|
138
|
+
waveLength: number;
|
|
139
|
+
/** Wave: how fast the waves run (0: they stand still on the path; 1: about four a second while the pen moves). */
|
|
140
|
+
waveSpeed: number;
|
|
141
|
+
/** Wave: how far out of step the particles' waves are (0: all in step; 1: random phases). */
|
|
142
|
+
wavePhaseJitter: number;
|
|
143
|
+
/** Dots and beads: up to four sticker stamps drawn instead of round marks (empty: round). */
|
|
144
|
+
dotTextures: StampKind[];
|
|
145
|
+
dotTextureOrder: DotTextureOrder;
|
|
146
|
+
dotRotation: DotRotation;
|
|
103
147
|
}
|
|
104
148
|
export declare const DEFAULT_PARTICLE: Readonly<ParticleSettings>;
|
|
105
149
|
export declare function normalizeParticle(raw?: Partial<ParticleSettings>, base?: ParticleSettings): ParticleSettings;
|
|
150
|
+
/**
|
|
151
|
+
* Adds the area polygon `pts` (x, y pairs, even-odd) covers in each pixel of `rect`, times `weight`, to `out`,
|
|
152
|
+
* exactly across each of `RIBBON_SUB` sub-rows per row. Points on an edge two polygons share
|
|
153
|
+
* count for exactly one of them, so polygons that tile a region add up to it with no seams.
|
|
154
|
+
*/
|
|
155
|
+
export declare function addPolygonArea(pts: readonly number[], rect: RasterRect, out: Float32Array, weight?: number): void;
|
|
106
156
|
/** A particle-brush stroke. */
|
|
107
157
|
export declare class ParticleStroke extends MarkStroke {
|
|
108
158
|
private readonly sets;
|
|
159
|
+
/** Ribbon pairs per copy: particles in their order around the pen (non-flow kinds). */
|
|
160
|
+
private readonly orders;
|
|
109
161
|
private readonly s;
|
|
110
162
|
private spawn;
|
|
163
|
+
/** Textured dots drawn so far, per copy (sequence order, random picks). */
|
|
164
|
+
private readonly dots;
|
|
165
|
+
/** Ribbon fill: the area each pixel has had so far this stroke (telescoped into the coverage). */
|
|
166
|
+
private readonly filled;
|
|
167
|
+
private pts;
|
|
111
168
|
constructor(brush: PaintBrush, options: ProceduralStrokeOptions);
|
|
169
|
+
/** Strand kinds: a chain of masses behind each particle. */
|
|
170
|
+
private get strands();
|
|
171
|
+
private newParticle;
|
|
112
172
|
private init;
|
|
173
|
+
/** The sideways wave of particle `p` at pen dab `d` (px along the normal to the pen's direction). */
|
|
174
|
+
private wave;
|
|
113
175
|
protected advance(copy: number, d: PenDab, rects: RasterRect[]): void;
|
|
176
|
+
/** A dot (or bead): round, or a textured stamp turned by the particle's motion (mx, my), at random or to the tip angle. */
|
|
177
|
+
private dot;
|
|
178
|
+
/**
|
|
179
|
+
* Ribbon fill for one step: the band between each pair of joined particles, from where they
|
|
180
|
+
* were drawn last step to where they are drawn now. Bands of one step, and of consecutive steps,
|
|
181
|
+
* share edges exactly, so the fill has no seams; it is telescoped into the coverage
|
|
182
|
+
* (`telescope`), so it does not build up at the joins.
|
|
183
|
+
*/
|
|
184
|
+
private ribbon;
|
|
185
|
+
/**
|
|
186
|
+
* Turns the area newly filled over `rect` into coverage to lay towards the fill's ceiling: the
|
|
187
|
+
* share of what was left unfilled, so after any number of bands (in any grouping) a pixel's
|
|
188
|
+
* coverage is the ceiling times the area filled there. False when nothing was added.
|
|
189
|
+
*/
|
|
190
|
+
private telescope;
|
|
114
191
|
}
|
|
115
192
|
/** Bristle engine settings (each 0..1 unless noted). */
|
|
116
193
|
export interface BristleSettings {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Art for stickers from a sticker provider (anything but the editor's own procedural stamps): the
|
|
3
|
+
* spray brush draws while a stroke is in progress, so it can't wait for a provider. Each sticker
|
|
4
|
+
* is loaded once, rasterised to RGBA and kept here; drawing reads it synchronously.
|
|
5
|
+
*
|
|
6
|
+
* PNG art (`data:` URLs) is decoded here, in any environment. SVG and `https:` images need a
|
|
7
|
+
* rasteriser: the browser's (`createImageBitmap` and `OffscreenCanvas`) by default, or the
|
|
8
|
+
* host's (`PaintEditorOptions.rasterizeSticker`).
|
|
9
|
+
*/
|
|
10
|
+
import type { StickerAsset, StickerProvider, StickerRef } from '../stickers/types.cjs';
|
|
11
|
+
/** Rasterised sticker art (straight RGBA) and whether to recolour it. */
|
|
12
|
+
export interface StickerArt {
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
data: Uint8ClampedArray;
|
|
16
|
+
/** Flat art: drawn in the sticker's colour, keeping its alpha. */
|
|
17
|
+
tintable: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** The art for a ref, when it has loaded. */
|
|
20
|
+
export type StickerArtLookup = (ref: StickerRef) => StickerArt | undefined;
|
|
21
|
+
/** Turns a sticker asset into RGBA at about `size` px on its longest side. */
|
|
22
|
+
export type StickerRasterizer = (asset: StickerAsset, size: number) => Promise<{
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
data: Uint8ClampedArray;
|
|
26
|
+
}>;
|
|
27
|
+
/** Longest side sticker art is kept at (px); larger stickers are drawn from it, smoothly scaled. */
|
|
28
|
+
export declare const STICKER_ART_SIZE = 256;
|
|
29
|
+
/**
|
|
30
|
+
* Decodes PNG data URLs anywhere; draws SVG and other images with the browser's
|
|
31
|
+
* `createImageBitmap` and `OffscreenCanvas` when present, and otherwise refuses, naming the option
|
|
32
|
+
* that adds a rasteriser.
|
|
33
|
+
*/
|
|
34
|
+
export declare const defaultStickerRasterizer: StickerRasterizer;
|
|
35
|
+
/** Loaded sticker art by ref, with the state of each load. */
|
|
36
|
+
export declare class StickerArtCache {
|
|
37
|
+
private readonly entries;
|
|
38
|
+
/** The art for `ref` when it has loaded (editor stamps never need any). */
|
|
39
|
+
get: StickerArtLookup;
|
|
40
|
+
/** `ready`, `loading`, `failed` (with the reason) or `none` (never asked for). Editor stamps are always `ready`. */
|
|
41
|
+
status(ref: StickerRef): {
|
|
42
|
+
status: 'ready' | 'loading' | 'failed' | 'none';
|
|
43
|
+
error?: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Loads and rasterises `ref` from `provider` once (later calls share the load). Unknown refs
|
|
47
|
+
* reject with the closest known ones; failures are kept so they are reported, and retried on
|
|
48
|
+
* the next call.
|
|
49
|
+
*/
|
|
50
|
+
ensure(provider: StickerProvider, ref: StickerRef, rasterize: StickerRasterizer): Promise<StickerArt | null>;
|
|
51
|
+
/** Forgets every load (a new provider). */
|
|
52
|
+
clear(): void;
|
|
53
|
+
}
|
|
54
|
+
/** Bilinear RGBA sample of `art` at (x, y) in its pixels (straight alpha, colour weighted by alpha). */
|
|
55
|
+
export declare function sampleArt(art: StickerArt, x: number, y: number, out: number[]): number[];
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Art for stickers from a sticker provider (anything but the editor's own procedural stamps): the
|
|
3
|
+
* spray brush draws while a stroke is in progress, so it can't wait for a provider. Each sticker
|
|
4
|
+
* is loaded once, rasterised to RGBA and kept here; drawing reads it synchronously.
|
|
5
|
+
*
|
|
6
|
+
* PNG art (`data:` URLs) is decoded here, in any environment. SVG and `https:` images need a
|
|
7
|
+
* rasteriser: the browser's (`createImageBitmap` and `OffscreenCanvas`) by default, or the
|
|
8
|
+
* host's (`PaintEditorOptions.rasterizeSticker`).
|
|
9
|
+
*/
|
|
10
|
+
import type { StickerAsset, StickerProvider, StickerRef } from '../stickers/types.js';
|
|
11
|
+
/** Rasterised sticker art (straight RGBA) and whether to recolour it. */
|
|
12
|
+
export interface StickerArt {
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
data: Uint8ClampedArray;
|
|
16
|
+
/** Flat art: drawn in the sticker's colour, keeping its alpha. */
|
|
17
|
+
tintable: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** The art for a ref, when it has loaded. */
|
|
20
|
+
export type StickerArtLookup = (ref: StickerRef) => StickerArt | undefined;
|
|
21
|
+
/** Turns a sticker asset into RGBA at about `size` px on its longest side. */
|
|
22
|
+
export type StickerRasterizer = (asset: StickerAsset, size: number) => Promise<{
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
data: Uint8ClampedArray;
|
|
26
|
+
}>;
|
|
27
|
+
/** Longest side sticker art is kept at (px); larger stickers are drawn from it, smoothly scaled. */
|
|
28
|
+
export declare const STICKER_ART_SIZE = 256;
|
|
29
|
+
/**
|
|
30
|
+
* Decodes PNG data URLs anywhere; draws SVG and other images with the browser's
|
|
31
|
+
* `createImageBitmap` and `OffscreenCanvas` when present, and otherwise refuses, naming the option
|
|
32
|
+
* that adds a rasteriser.
|
|
33
|
+
*/
|
|
34
|
+
export declare const defaultStickerRasterizer: StickerRasterizer;
|
|
35
|
+
/** Loaded sticker art by ref, with the state of each load. */
|
|
36
|
+
export declare class StickerArtCache {
|
|
37
|
+
private readonly entries;
|
|
38
|
+
/** The art for `ref` when it has loaded (editor stamps never need any). */
|
|
39
|
+
get: StickerArtLookup;
|
|
40
|
+
/** `ready`, `loading`, `failed` (with the reason) or `none` (never asked for). Editor stamps are always `ready`. */
|
|
41
|
+
status(ref: StickerRef): {
|
|
42
|
+
status: 'ready' | 'loading' | 'failed' | 'none';
|
|
43
|
+
error?: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Loads and rasterises `ref` from `provider` once (later calls share the load). Unknown refs
|
|
47
|
+
* reject with the closest known ones; failures are kept so they are reported, and retried on
|
|
48
|
+
* the next call.
|
|
49
|
+
*/
|
|
50
|
+
ensure(provider: StickerProvider, ref: StickerRef, rasterize: StickerRasterizer): Promise<StickerArt | null>;
|
|
51
|
+
/** Forgets every load (a new provider). */
|
|
52
|
+
clear(): void;
|
|
53
|
+
}
|
|
54
|
+
/** Bilinear RGBA sample of `art` at (x, y) in its pixels (straight alpha, colour weighted by alpha). */
|
|
55
|
+
export declare function sampleArt(art: StickerArt, x: number, y: number, out: number[]): number[];
|
|
@@ -14,13 +14,18 @@ import { TileMedium, type PaintTileTarget } from '../paint/exchange.cjs';
|
|
|
14
14
|
import { type PaintGradientSource } from '../paint/gradient-paint.cjs';
|
|
15
15
|
import type { PaintBrush } from './brushes.cjs';
|
|
16
16
|
import { type PenPoint, type StrokeCopy } from './engine.cjs';
|
|
17
|
+
import { type StampKind } from '../stickers/stamps.cjs';
|
|
18
|
+
import type { StickerRef } from '../stickers/types.cjs';
|
|
19
|
+
import { type StickerArtLookup } from './sticker-art.cjs';
|
|
20
|
+
export { STAMP_KINDS, stampCoverage, type StampKind } from '../stickers/stamps.cjs';
|
|
17
21
|
import { type EffectPaintPixels } from './effect-paint.cjs';
|
|
18
|
-
export type StampKind = 'dot' | 'star' | 'heart' | 'leaf' | 'flower' | 'confetti' | 'splat' | 'sparkle' | 'ring';
|
|
19
|
-
export declare const STAMP_KINDS: readonly StampKind[];
|
|
20
22
|
/** One sticker (document pixels). */
|
|
21
23
|
export interface Sticker {
|
|
22
24
|
id: string;
|
|
23
|
-
|
|
25
|
+
/** What it shows: a sticker ref (`provider:id`), e.g. `editor:star` or a host library's sticker. */
|
|
26
|
+
ref: StickerRef;
|
|
27
|
+
/** The editor stamp, when `ref` is one (`editor:star` → `star`); kept for documents and code that read it. */
|
|
28
|
+
stamp?: StampKind;
|
|
24
29
|
x: number;
|
|
25
30
|
y: number;
|
|
26
31
|
/** Diameter in pixels. */
|
|
@@ -36,8 +41,11 @@ export interface Sticker {
|
|
|
36
41
|
}
|
|
37
42
|
/** Sticker spray settings (each 0..1 unless noted). */
|
|
38
43
|
export interface StickerSettings {
|
|
39
|
-
/**
|
|
40
|
-
|
|
44
|
+
/**
|
|
45
|
+
* The stickers to spray (one picked at random per sticker): refs `provider:id`. A bare editor
|
|
46
|
+
* stamp (`"star"`) is read as `editor:star`.
|
|
47
|
+
*/
|
|
48
|
+
stamps: StickerRef[];
|
|
41
49
|
/** How closely stickers follow each other: about `density × 4` per tip diameter of travel (0.25 ≈ one per diameter). */
|
|
42
50
|
density: number;
|
|
43
51
|
/** Random size change. */
|
|
@@ -49,20 +57,21 @@ export interface StickerSettings {
|
|
|
49
57
|
/** Random colour change (hue and lightness). */
|
|
50
58
|
colorJitter: number;
|
|
51
59
|
}
|
|
60
|
+
/** At most this many stickers in a sticker brush. */
|
|
61
|
+
export declare const MAX_STICKER_STAMPS = 16;
|
|
52
62
|
export declare const DEFAULT_STICKER: Readonly<StickerSettings>;
|
|
53
63
|
export declare function normalizeStickerSettings(raw?: Partial<StickerSettings>, base?: StickerSettings): StickerSettings;
|
|
54
|
-
/**
|
|
55
|
-
* Coverage of a stamp at a point (u, v) of its unit square (−1..1, y down), 0..1, before shading.
|
|
56
|
-
* `t` is the sticker's seed for shapes with random parts (splat, confetti).
|
|
57
|
-
*/
|
|
58
|
-
export declare function stampCoverage(kind: StampKind, u: number, v: number, t: number): number;
|
|
59
64
|
/** The pixel rectangle a sticker covers. */
|
|
60
65
|
export declare function stickerRect(s: Sticker): RasterRect;
|
|
66
|
+
/** The editor stamp a sticker shows, or `null` for a provider's sticker. */
|
|
67
|
+
export declare function stickerStamp(s: Pick<Sticker, 'ref' | 'stamp'>): StampKind | null;
|
|
61
68
|
/**
|
|
62
|
-
* Draws one sticker through a `TileMedium` (straight source-over)
|
|
63
|
-
* little from the top left and given a fine seeded texture, in its colour and opacity.
|
|
69
|
+
* Draws one sticker through a `TileMedium` (straight source-over). An editor stamp: its coverage,
|
|
70
|
+
* lit a little from the top left and given a fine seeded texture, in its colour and opacity. A
|
|
71
|
+
* provider's sticker: its loaded art (`art`), fitted into the sticker's size and turned, in its
|
|
72
|
+
* own colours or, when tintable, in the sticker's colour; nothing until the art has loaded.
|
|
64
73
|
*/
|
|
65
|
-
export declare function drawSticker(medium: TileMedium, s: Sticker): RasterRect;
|
|
74
|
+
export declare function drawSticker(medium: TileMedium, s: Sticker, art?: StickerArtLookup): RasterRect;
|
|
66
75
|
export interface StickerSprayInit {
|
|
67
76
|
brush: PaintBrush;
|
|
68
77
|
target: PaintTileTarget;
|
|
@@ -79,12 +88,16 @@ export interface StickerSprayInit {
|
|
|
79
88
|
* stays recolourable); none lands where the effect is transparent.
|
|
80
89
|
*/
|
|
81
90
|
effect?: EffectPaintPixels | null;
|
|
91
|
+
/** Loaded art for provider stickers; stickers without art yet are skipped (see `skipped`). */
|
|
92
|
+
art?: StickerArtLookup;
|
|
82
93
|
}
|
|
83
94
|
/** A sticker-spray stroke: drops stickers along the path and draws them as it goes. */
|
|
84
95
|
export declare class StickerSpray {
|
|
85
96
|
readonly init: StickerSprayInit;
|
|
86
97
|
dabCount: number;
|
|
87
98
|
readonly stickers: Sticker[];
|
|
99
|
+
/** Refs the spray picked but could not draw because their art had not loaded. */
|
|
100
|
+
readonly skipped: Set<string>;
|
|
88
101
|
private readonly smoother;
|
|
89
102
|
private readonly walkers;
|
|
90
103
|
private readonly copies;
|
|
@@ -101,7 +114,7 @@ export declare class StickerSpray {
|
|
|
101
114
|
private colorAt;
|
|
102
115
|
}
|
|
103
116
|
/** A sticker list rendered over a transparent layer, through a tile target. */
|
|
104
|
-
export declare function renderStickers(stickers: readonly Sticker[], target: PaintTileTarget): void;
|
|
117
|
+
export declare function renderStickers(stickers: readonly Sticker[], target: PaintTileTarget, art?: StickerArtLookup): void;
|
|
105
118
|
/** Checks and rounds a sticker change; throws a sentence naming the bad field. */
|
|
106
119
|
export declare function normalizeStickerUpdate(u: Partial<Omit<Sticker, 'id'>>): Partial<Omit<Sticker, 'id'>>;
|
|
107
120
|
/**
|
|
@@ -110,6 +123,6 @@ export declare function normalizeStickerUpdate(u: Partial<Omit<Sticker, 'id'>>):
|
|
|
110
123
|
* drawn again, from the stickers that reach them; the rest are kept. The pixels are the same as a
|
|
111
124
|
* full redraw, since a tile depends only on the stickers over it.
|
|
112
125
|
*/
|
|
113
|
-
export declare function stickerSurface(stickers: readonly Sticker[], base?: TiledSurface, dirty?: readonly RasterRect[]): TiledSurface;
|
|
114
|
-
/** The top-most sticker under a point (document pixels), by its stamp's shape, or `null`. */
|
|
115
|
-
export declare function stickerAt(stickers: readonly Sticker[], x: number, y: number): Sticker | null;
|
|
126
|
+
export declare function stickerSurface(stickers: readonly Sticker[], base?: TiledSurface, dirty?: readonly RasterRect[], art?: StickerArtLookup): TiledSurface;
|
|
127
|
+
/** The top-most sticker under a point (document pixels), by its stamp's shape (or its art's alpha), or `null`. */
|
|
128
|
+
export declare function stickerAt(stickers: readonly Sticker[], x: number, y: number, art?: StickerArtLookup): Sticker | null;
|
|
@@ -14,13 +14,18 @@ import { TileMedium, type PaintTileTarget } from '../paint/exchange.js';
|
|
|
14
14
|
import { type PaintGradientSource } from '../paint/gradient-paint.js';
|
|
15
15
|
import type { PaintBrush } from './brushes.js';
|
|
16
16
|
import { type PenPoint, type StrokeCopy } from './engine.js';
|
|
17
|
+
import { type StampKind } from '../stickers/stamps.js';
|
|
18
|
+
import type { StickerRef } from '../stickers/types.js';
|
|
19
|
+
import { type StickerArtLookup } from './sticker-art.js';
|
|
20
|
+
export { STAMP_KINDS, stampCoverage, type StampKind } from '../stickers/stamps.js';
|
|
17
21
|
import { type EffectPaintPixels } from './effect-paint.js';
|
|
18
|
-
export type StampKind = 'dot' | 'star' | 'heart' | 'leaf' | 'flower' | 'confetti' | 'splat' | 'sparkle' | 'ring';
|
|
19
|
-
export declare const STAMP_KINDS: readonly StampKind[];
|
|
20
22
|
/** One sticker (document pixels). */
|
|
21
23
|
export interface Sticker {
|
|
22
24
|
id: string;
|
|
23
|
-
|
|
25
|
+
/** What it shows: a sticker ref (`provider:id`), e.g. `editor:star` or a host library's sticker. */
|
|
26
|
+
ref: StickerRef;
|
|
27
|
+
/** The editor stamp, when `ref` is one (`editor:star` → `star`); kept for documents and code that read it. */
|
|
28
|
+
stamp?: StampKind;
|
|
24
29
|
x: number;
|
|
25
30
|
y: number;
|
|
26
31
|
/** Diameter in pixels. */
|
|
@@ -36,8 +41,11 @@ export interface Sticker {
|
|
|
36
41
|
}
|
|
37
42
|
/** Sticker spray settings (each 0..1 unless noted). */
|
|
38
43
|
export interface StickerSettings {
|
|
39
|
-
/**
|
|
40
|
-
|
|
44
|
+
/**
|
|
45
|
+
* The stickers to spray (one picked at random per sticker): refs `provider:id`. A bare editor
|
|
46
|
+
* stamp (`"star"`) is read as `editor:star`.
|
|
47
|
+
*/
|
|
48
|
+
stamps: StickerRef[];
|
|
41
49
|
/** How closely stickers follow each other: about `density × 4` per tip diameter of travel (0.25 ≈ one per diameter). */
|
|
42
50
|
density: number;
|
|
43
51
|
/** Random size change. */
|
|
@@ -49,20 +57,21 @@ export interface StickerSettings {
|
|
|
49
57
|
/** Random colour change (hue and lightness). */
|
|
50
58
|
colorJitter: number;
|
|
51
59
|
}
|
|
60
|
+
/** At most this many stickers in a sticker brush. */
|
|
61
|
+
export declare const MAX_STICKER_STAMPS = 16;
|
|
52
62
|
export declare const DEFAULT_STICKER: Readonly<StickerSettings>;
|
|
53
63
|
export declare function normalizeStickerSettings(raw?: Partial<StickerSettings>, base?: StickerSettings): StickerSettings;
|
|
54
|
-
/**
|
|
55
|
-
* Coverage of a stamp at a point (u, v) of its unit square (−1..1, y down), 0..1, before shading.
|
|
56
|
-
* `t` is the sticker's seed for shapes with random parts (splat, confetti).
|
|
57
|
-
*/
|
|
58
|
-
export declare function stampCoverage(kind: StampKind, u: number, v: number, t: number): number;
|
|
59
64
|
/** The pixel rectangle a sticker covers. */
|
|
60
65
|
export declare function stickerRect(s: Sticker): RasterRect;
|
|
66
|
+
/** The editor stamp a sticker shows, or `null` for a provider's sticker. */
|
|
67
|
+
export declare function stickerStamp(s: Pick<Sticker, 'ref' | 'stamp'>): StampKind | null;
|
|
61
68
|
/**
|
|
62
|
-
* Draws one sticker through a `TileMedium` (straight source-over)
|
|
63
|
-
* little from the top left and given a fine seeded texture, in its colour and opacity.
|
|
69
|
+
* Draws one sticker through a `TileMedium` (straight source-over). An editor stamp: its coverage,
|
|
70
|
+
* lit a little from the top left and given a fine seeded texture, in its colour and opacity. A
|
|
71
|
+
* provider's sticker: its loaded art (`art`), fitted into the sticker's size and turned, in its
|
|
72
|
+
* own colours or, when tintable, in the sticker's colour; nothing until the art has loaded.
|
|
64
73
|
*/
|
|
65
|
-
export declare function drawSticker(medium: TileMedium, s: Sticker): RasterRect;
|
|
74
|
+
export declare function drawSticker(medium: TileMedium, s: Sticker, art?: StickerArtLookup): RasterRect;
|
|
66
75
|
export interface StickerSprayInit {
|
|
67
76
|
brush: PaintBrush;
|
|
68
77
|
target: PaintTileTarget;
|
|
@@ -79,12 +88,16 @@ export interface StickerSprayInit {
|
|
|
79
88
|
* stays recolourable); none lands where the effect is transparent.
|
|
80
89
|
*/
|
|
81
90
|
effect?: EffectPaintPixels | null;
|
|
91
|
+
/** Loaded art for provider stickers; stickers without art yet are skipped (see `skipped`). */
|
|
92
|
+
art?: StickerArtLookup;
|
|
82
93
|
}
|
|
83
94
|
/** A sticker-spray stroke: drops stickers along the path and draws them as it goes. */
|
|
84
95
|
export declare class StickerSpray {
|
|
85
96
|
readonly init: StickerSprayInit;
|
|
86
97
|
dabCount: number;
|
|
87
98
|
readonly stickers: Sticker[];
|
|
99
|
+
/** Refs the spray picked but could not draw because their art had not loaded. */
|
|
100
|
+
readonly skipped: Set<string>;
|
|
88
101
|
private readonly smoother;
|
|
89
102
|
private readonly walkers;
|
|
90
103
|
private readonly copies;
|
|
@@ -101,7 +114,7 @@ export declare class StickerSpray {
|
|
|
101
114
|
private colorAt;
|
|
102
115
|
}
|
|
103
116
|
/** A sticker list rendered over a transparent layer, through a tile target. */
|
|
104
|
-
export declare function renderStickers(stickers: readonly Sticker[], target: PaintTileTarget): void;
|
|
117
|
+
export declare function renderStickers(stickers: readonly Sticker[], target: PaintTileTarget, art?: StickerArtLookup): void;
|
|
105
118
|
/** Checks and rounds a sticker change; throws a sentence naming the bad field. */
|
|
106
119
|
export declare function normalizeStickerUpdate(u: Partial<Omit<Sticker, 'id'>>): Partial<Omit<Sticker, 'id'>>;
|
|
107
120
|
/**
|
|
@@ -110,6 +123,6 @@ export declare function normalizeStickerUpdate(u: Partial<Omit<Sticker, 'id'>>):
|
|
|
110
123
|
* drawn again, from the stickers that reach them; the rest are kept. The pixels are the same as a
|
|
111
124
|
* full redraw, since a tile depends only on the stickers over it.
|
|
112
125
|
*/
|
|
113
|
-
export declare function stickerSurface(stickers: readonly Sticker[], base?: TiledSurface, dirty?: readonly RasterRect[]): TiledSurface;
|
|
114
|
-
/** The top-most sticker under a point (document pixels), by its stamp's shape, or `null`. */
|
|
115
|
-
export declare function stickerAt(stickers: readonly Sticker[], x: number, y: number): Sticker | null;
|
|
126
|
+
export declare function stickerSurface(stickers: readonly Sticker[], base?: TiledSurface, dirty?: readonly RasterRect[], art?: StickerArtLookup): TiledSurface;
|
|
127
|
+
/** The top-most sticker under a point (document pixels), by its stamp's shape (or its art's alpha), or `null`. */
|
|
128
|
+
export declare function stickerAt(stickers: readonly Sticker[], x: number, y: number, art?: StickerArtLookup): Sticker | null;
|
|
@@ -20,6 +20,7 @@ import type { Affine } from './strokes.cjs';
|
|
|
20
20
|
import type { WetStrokeDriver } from './wet.cjs';
|
|
21
21
|
import { type ThickChannels } from './thick.cjs';
|
|
22
22
|
import { type Sticker } from './stickers.cjs';
|
|
23
|
+
import type { StickerArtLookup } from './sticker-art.cjs';
|
|
23
24
|
export interface StrokeSessionHost {
|
|
24
25
|
/** Shows the layer's live surface (no history); `rects` are where it changed. */
|
|
25
26
|
update(layerId: string, surface: TiledSurface, rects: RasterRect[]): void;
|
|
@@ -74,6 +75,7 @@ export interface StrokeSessionInit {
|
|
|
74
75
|
/** Sticker brushes: the next sticker number on the layer. */
|
|
75
76
|
sticker?: {
|
|
76
77
|
nextId: number;
|
|
78
|
+
art?: StickerArtLookup;
|
|
77
79
|
};
|
|
78
80
|
/** Gradient paint (resolved: concrete colours), or `null` for the one colour. Recorded with the stroke. */
|
|
79
81
|
paint?: PaintGradientSource | null;
|
|
@@ -104,6 +106,8 @@ export interface PaintStrokeResult {
|
|
|
104
106
|
mixerLoad?: MixerLoad;
|
|
105
107
|
/** Wet brushes: the paint is wet (it keeps moving until it dries; see dry_paint / advance_wet_paint). */
|
|
106
108
|
wet?: boolean;
|
|
109
|
+
/** Sticker brushes: refs the spray picked but skipped because their art had not loaded yet. */
|
|
110
|
+
skippedStickers?: string[];
|
|
107
111
|
}
|
|
108
112
|
export declare class PaintStrokeSession {
|
|
109
113
|
private readonly host;
|
|
@@ -20,6 +20,7 @@ import type { Affine } from './strokes.js';
|
|
|
20
20
|
import type { WetStrokeDriver } from './wet.js';
|
|
21
21
|
import { type ThickChannels } from './thick.js';
|
|
22
22
|
import { type Sticker } from './stickers.js';
|
|
23
|
+
import type { StickerArtLookup } from './sticker-art.js';
|
|
23
24
|
export interface StrokeSessionHost {
|
|
24
25
|
/** Shows the layer's live surface (no history); `rects` are where it changed. */
|
|
25
26
|
update(layerId: string, surface: TiledSurface, rects: RasterRect[]): void;
|
|
@@ -74,6 +75,7 @@ export interface StrokeSessionInit {
|
|
|
74
75
|
/** Sticker brushes: the next sticker number on the layer. */
|
|
75
76
|
sticker?: {
|
|
76
77
|
nextId: number;
|
|
78
|
+
art?: StickerArtLookup;
|
|
77
79
|
};
|
|
78
80
|
/** Gradient paint (resolved: concrete colours), or `null` for the one colour. Recorded with the stroke. */
|
|
79
81
|
paint?: PaintGradientSource | null;
|
|
@@ -104,6 +106,8 @@ export interface PaintStrokeResult {
|
|
|
104
106
|
mixerLoad?: MixerLoad;
|
|
105
107
|
/** Wet brushes: the paint is wet (it keeps moving until it dries; see dry_paint / advance_wet_paint). */
|
|
106
108
|
wet?: boolean;
|
|
109
|
+
/** Sticker brushes: refs the spray picked but skipped because their art had not loaded yet. */
|
|
110
|
+
skippedStickers?: string[];
|
|
107
111
|
}
|
|
108
112
|
export declare class PaintStrokeSession {
|
|
109
113
|
private readonly host;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { AgentToolProvider } from '../tools/registry.cjs';
|
|
8
8
|
import { type PaintOrigin } from './hosted.cjs';
|
|
9
|
-
import type
|
|
9
|
+
import { type PaintEditorController } from './controller.cjs';
|
|
10
10
|
import type { PaintDirector } from './presence.cjs';
|
|
11
11
|
import type { PresenceActorInfo } from '../animation/presence.cjs';
|
|
12
12
|
export interface PaintEditorToolProviderOptions {
|