@pixerate/editor 0.239.0 → 0.241.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/animation-editor/index.cjs +58 -58
  2. package/dist/animation-editor/index.js +3 -3
  3. package/dist/{brushstrokeRender-WB67GMUP.js → brushstrokeRender-MOYGEXOC.js} +2 -2
  4. package/dist/{brushstrokeRender-MPOM7BFW.cjs → brushstrokeRender-UKADOV5D.cjs} +5 -5
  5. package/dist/canvas/index.cjs +8 -8
  6. package/dist/canvas/index.js +1 -1
  7. package/dist/{chunk-NKTNLJUJ.cjs → chunk-5BR7LC24.cjs} +99 -11
  8. package/dist/{chunk-ZXNO3ZOX.cjs → chunk-7F4G74UQ.cjs} +35 -35
  9. package/dist/{chunk-AD7GA3TL.cjs → chunk-AFLMXITL.cjs} +23 -23
  10. package/dist/{chunk-PP6BXVRL.cjs → chunk-HGGJ36HR.cjs} +1 -1
  11. package/dist/{chunk-BBUE3UJL.cjs → chunk-HW72ABGR.cjs} +86 -86
  12. package/dist/{chunk-7YGBSFC6.js → chunk-ILM6GYAX.js} +1 -1
  13. package/dist/{chunk-THXFU3JB.cjs → chunk-KCMV2534.cjs} +2 -2
  14. package/dist/{chunk-3E36VDMJ.js → chunk-NE6OOKWJ.js} +1 -1
  15. package/dist/{chunk-RV5DKZHU.js → chunk-QP2B3MID.js} +1 -1
  16. package/dist/{chunk-UUBO6RB5.js → chunk-UDBDYZET.js} +1 -1
  17. package/dist/{chunk-PJYG6FCF.js → chunk-XBZK47LV.js} +98 -10
  18. package/dist/{chunk-XK4SST43.js → chunk-ZDPLZDTT.js} +1 -1
  19. package/dist/image-editor/index.cjs +775 -775
  20. package/dist/image-editor/index.js +4 -4
  21. package/dist/paint-editor/controller.d.cts +158 -1
  22. package/dist/paint-editor/controller.d.ts +158 -1
  23. package/dist/paint-editor/document.d.cts +7 -2
  24. package/dist/paint-editor/document.d.ts +7 -2
  25. package/dist/paint-editor/effect-paint.d.cts +60 -3
  26. package/dist/paint-editor/effect-paint.d.ts +60 -3
  27. package/dist/paint-editor/index.cjs +1246 -430
  28. package/dist/paint-editor/index.d.cts +1 -0
  29. package/dist/paint-editor/index.d.ts +1 -0
  30. package/dist/paint-editor/index.js +888 -72
  31. package/dist/paint-editor/live-strokes.d.cts +24 -0
  32. package/dist/paint-editor/live-strokes.d.ts +24 -0
  33. package/dist/paint-editor/stickers.d.cts +6 -0
  34. package/dist/paint-editor/stickers.d.ts +6 -0
  35. package/dist/paint-editor/thick.d.cts +4 -0
  36. package/dist/paint-editor/thick.d.ts +4 -0
  37. package/dist/paint-editor/ui.d.cts +24 -4
  38. package/dist/paint-editor/ui.d.ts +24 -4
  39. package/dist/paint-editor/wet.d.cts +8 -0
  40. package/dist/paint-editor/wet.d.ts +8 -0
  41. package/dist/vector/index.cjs +962 -962
  42. package/dist/vector/index.js +4 -4
  43. package/package.json +1 -1
  44. package/skills/pixerate-paint-editor/SKILL.md +38 -27
  45. package/skills/pixerate-paint-editor/references/effect-paint.md +25 -0
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Live stroke layers: a paint layer whose pixels are always drawn from its recorded strokes, so a
3
+ * stroke's brush, colour, paint, seed and points can be changed after it is painted
4
+ * (`PaintEditorController.updateStroke` and the rest). The document keeps the strokes
5
+ * (`liveStrokes`), and the layer's surface is a cache of them drawn bottom first.
6
+ *
7
+ * Only brushes whose result depends on the stroke itself can be redrawn exactly: dab, particle and
8
+ * bristle brushes, and the Mixer Brush, none of them picking up paint. Wet paint needs the
9
+ * simulation's history, thick paint has relief channels, stickers are their own objects, and
10
+ * smudges, blenders, pick-up brushes and erasers read the paint under them.
11
+ */
12
+ import type { PaintBrush, PaintBrushEngine } from './brushes.cjs';
13
+ import { type RecordedStroke } from './strokes.cjs';
14
+ /** The engines a live stroke layer takes. */
15
+ export declare const LIVE_STROKE_ENGINES: readonly PaintBrushEngine[];
16
+ /** Why a brush can't paint on a live stroke layer, or `null` when it can. */
17
+ export declare function liveStrokeRefusal(brush: PaintBrush): string | null;
18
+ /** A stroke's extent in document pixels: its points and symmetry copies, padded by the brush. */
19
+ export declare function liveStrokeBounds(stroke: RecordedStroke): {
20
+ x: number;
21
+ y: number;
22
+ width: number;
23
+ height: number;
24
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Live stroke layers: a paint layer whose pixels are always drawn from its recorded strokes, so a
3
+ * stroke's brush, colour, paint, seed and points can be changed after it is painted
4
+ * (`PaintEditorController.updateStroke` and the rest). The document keeps the strokes
5
+ * (`liveStrokes`), and the layer's surface is a cache of them drawn bottom first.
6
+ *
7
+ * Only brushes whose result depends on the stroke itself can be redrawn exactly: dab, particle and
8
+ * bristle brushes, and the Mixer Brush, none of them picking up paint. Wet paint needs the
9
+ * simulation's history, thick paint has relief channels, stickers are their own objects, and
10
+ * smudges, blenders, pick-up brushes and erasers read the paint under them.
11
+ */
12
+ import type { PaintBrush, PaintBrushEngine } from './brushes.js';
13
+ import { type RecordedStroke } from './strokes.js';
14
+ /** The engines a live stroke layer takes. */
15
+ export declare const LIVE_STROKE_ENGINES: readonly PaintBrushEngine[];
16
+ /** Why a brush can't paint on a live stroke layer, or `null` when it can. */
17
+ export declare function liveStrokeRefusal(brush: PaintBrush): string | null;
18
+ /** A stroke's extent in document pixels: its points and symmetry copies, padded by the brush. */
19
+ export declare function liveStrokeBounds(stroke: RecordedStroke): {
20
+ x: number;
21
+ y: number;
22
+ width: number;
23
+ height: number;
24
+ };
@@ -14,6 +14,7 @@ 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 EffectPaintPixels } from './effect-paint.cjs';
17
18
  export type StampKind = 'dot' | 'star' | 'heart' | 'leaf' | 'flower' | 'confetti' | 'splat' | 'sparkle' | 'ring';
18
19
  export declare const STAMP_KINDS: readonly StampKind[];
19
20
  /** One sticker (document pixels). */
@@ -73,6 +74,11 @@ export interface StickerSprayInit {
73
74
  nextId: number;
74
75
  /** Gradient paint (resolved): each sticker takes its dab's colour (across the tip: by its offset). */
75
76
  paint?: PaintGradientSource | null;
77
+ /**
78
+ * Effect paint: each sticker takes the effect's colour at its centre (it keeps one colour, so it
79
+ * stays recolourable); none lands where the effect is transparent.
80
+ */
81
+ effect?: EffectPaintPixels | null;
76
82
  }
77
83
  /** A sticker-spray stroke: drops stickers along the path and draws them as it goes. */
78
84
  export declare class StickerSpray {
@@ -14,6 +14,7 @@ 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 EffectPaintPixels } from './effect-paint.js';
17
18
  export type StampKind = 'dot' | 'star' | 'heart' | 'leaf' | 'flower' | 'confetti' | 'splat' | 'sparkle' | 'ring';
18
19
  export declare const STAMP_KINDS: readonly StampKind[];
19
20
  /** One sticker (document pixels). */
@@ -73,6 +74,11 @@ export interface StickerSprayInit {
73
74
  nextId: number;
74
75
  /** Gradient paint (resolved): each sticker takes its dab's colour (across the tip: by its offset). */
75
76
  paint?: PaintGradientSource | null;
77
+ /**
78
+ * Effect paint: each sticker takes the effect's colour at its centre (it keeps one colour, so it
79
+ * stays recolourable); none lands where the effect is transparent.
80
+ */
81
+ effect?: EffectPaintPixels | null;
76
82
  }
77
83
  /** A sticker-spray stroke: drops stickers along the path and draws them as it goes. */
78
84
  export declare class StickerSpray {
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import { type MixerLoad, type PaintTileTarget, type RgbTriple } from '../paint/exchange.cjs';
17
17
  import { type PaintGradientSource } from '../paint/gradient-paint.cjs';
18
+ import { type EffectPaintPixels } from './effect-paint.cjs';
18
19
  import { TiledSurface, type RasterRect } from '../raster/surface.cjs';
19
20
  import type { PaintBrush } from './brushes.cjs';
20
21
  import { type PenPoint, type StrokeCopy } from './engine.cjs';
@@ -63,6 +64,8 @@ export interface ThickStrokeInit {
63
64
  copies: readonly StrokeCopy[];
64
65
  /** Gradient paint (resolved): the colour varies along the impasto. */
65
66
  paint?: PaintGradientSource | null;
67
+ /** Effect paint: each pixel's colour is the effect's there (its alpha scales the coverage); the relief is unchanged. */
68
+ effect?: EffectPaintPixels | null;
66
69
  }
67
70
  /** One impasto stroke: colour through the exchange, height and material into live channel tiles. */
68
71
  export declare class ThickStrokeDriver {
@@ -74,6 +77,7 @@ export declare class ThickStrokeDriver {
74
77
  private readonly height;
75
78
  private readonly material;
76
79
  private readonly paint;
80
+ private readonly centre;
77
81
  private tip;
78
82
  private lastRaw;
79
83
  private lastFed;
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import { type MixerLoad, type PaintTileTarget, type RgbTriple } from '../paint/exchange.js';
17
17
  import { type PaintGradientSource } from '../paint/gradient-paint.js';
18
+ import { type EffectPaintPixels } from './effect-paint.js';
18
19
  import { TiledSurface, type RasterRect } from '../raster/surface.js';
19
20
  import type { PaintBrush } from './brushes.js';
20
21
  import { type PenPoint, type StrokeCopy } from './engine.js';
@@ -63,6 +64,8 @@ export interface ThickStrokeInit {
63
64
  copies: readonly StrokeCopy[];
64
65
  /** Gradient paint (resolved): the colour varies along the impasto. */
65
66
  paint?: PaintGradientSource | null;
67
+ /** Effect paint: each pixel's colour is the effect's there (its alpha scales the coverage); the relief is unchanged. */
68
+ effect?: EffectPaintPixels | null;
66
69
  }
67
70
  /** One impasto stroke: colour through the exchange, height and material into live channel tiles. */
68
71
  export declare class ThickStrokeDriver {
@@ -74,6 +77,7 @@ export declare class ThickStrokeDriver {
74
77
  private readonly height;
75
78
  private readonly material;
76
79
  private readonly paint;
80
+ private readonly centre;
77
81
  private tip;
78
82
  private lastRaw;
79
83
  private lastFed;
@@ -34,7 +34,7 @@ export interface PaintPointerEvent extends PointerSample {
34
34
  getCoalescedEvents?(): PaintPointerEvent[];
35
35
  getPredictedEvents?(): PaintPointerEvent[];
36
36
  }
37
- export type PaintTool = 'brush' | 'eyedropper' | 'pan' | 'rotate' | 'sticker';
37
+ export type PaintTool = 'brush' | 'eyedropper' | 'pan' | 'rotate' | 'sticker' | 'stroke';
38
38
  export declare const PAINT_TOOLS: ReadonlyArray<{
39
39
  id: PaintTool;
40
40
  label: string;
@@ -63,6 +63,17 @@ export declare class PaintGesture {
63
63
  private pen;
64
64
  /** Pointer down; returns true when the gesture took the pointer (capture it). */
65
65
  down(e: PaintPointerEvent): boolean;
66
+ /**
67
+ * The Select stroke tool, on a stroke layer: pressing a stroke picks it and dragging moves it
68
+ * (one undo step at the drop); pressing where no stroke painted clears the pick.
69
+ */
70
+ private strokeDown;
71
+ /** While a stroke is dragged: how far it has moved (document pixels), to draw its outline there. */
72
+ get strokeDrag(): {
73
+ id: string;
74
+ dx: number;
75
+ dy: number;
76
+ } | null;
66
77
  /**
67
78
  * The Stickers tool: pressing a sticker picks it and dragging moves it (one undo step at the
68
79
  * drop); pressing anywhere else places the active brush's first stamp there, at its tip size and
@@ -107,9 +118,16 @@ export declare class PaintCanvasPresenter {
107
118
  /** Draws what changed into `ctx` (a canvas the size of the document); returns the tiles drawn. */
108
119
  render(ctx: Paint2DContext): number;
109
120
  }
110
- export type GuideOverlayKind = 'symmetry' | 'perspective' | 'snap' | 'stencil' | 'sticker';
111
- /** Lines to draw over the canvas for the guides and the picked sticker, in document pixels, with a style key. */
112
- export declare function guideOverlay(controller: PaintEditorController): Array<{
121
+ export type GuideOverlayKind = 'symmetry' | 'perspective' | 'snap' | 'stencil' | 'sticker' | 'stroke';
122
+ /**
123
+ * Lines to draw over the canvas for the guides, the picked sticker and the picked stroke of a stroke layer (moved by
124
+ * `drag` while it is dragged), in document pixels, with a style key.
125
+ */
126
+ export declare function guideOverlay(controller: PaintEditorController, drag?: {
127
+ id: string;
128
+ dx: number;
129
+ dy: number;
130
+ } | null): Array<{
113
131
  from: Point2;
114
132
  to: Point2;
115
133
  kind: GuideOverlayKind;
@@ -238,6 +256,8 @@ export declare const STAMP_LABELS: Readonly<Record<StampKind, string>>;
238
256
  /** Toggles one stamp in a sticker brush's set (never leaving it empty). */
239
257
  export declare function toggleStamp(stamps: readonly StampKind[], stamp: StampKind): StampKind[];
240
258
  /** The sticker panel's sliders for the selected sticker. */
259
+ /** The brush sliders of a picked stroke on a stroke layer (paths into its brush; see `updateStroke`). */
260
+ export declare const STROKE_SLIDERS: readonly SliderControl[];
241
261
  export declare const STICKER_SLIDERS: readonly SliderControl[];
242
262
  /** Stencils a toolbar can lay with one click, centred on the canvas. */
243
263
  export declare function quickStencil(kind: 'ruler' | 'circle' | 'ellipse-mask' | 'edge-mask', canvas: {
@@ -34,7 +34,7 @@ export interface PaintPointerEvent extends PointerSample {
34
34
  getCoalescedEvents?(): PaintPointerEvent[];
35
35
  getPredictedEvents?(): PaintPointerEvent[];
36
36
  }
37
- export type PaintTool = 'brush' | 'eyedropper' | 'pan' | 'rotate' | 'sticker';
37
+ export type PaintTool = 'brush' | 'eyedropper' | 'pan' | 'rotate' | 'sticker' | 'stroke';
38
38
  export declare const PAINT_TOOLS: ReadonlyArray<{
39
39
  id: PaintTool;
40
40
  label: string;
@@ -63,6 +63,17 @@ export declare class PaintGesture {
63
63
  private pen;
64
64
  /** Pointer down; returns true when the gesture took the pointer (capture it). */
65
65
  down(e: PaintPointerEvent): boolean;
66
+ /**
67
+ * The Select stroke tool, on a stroke layer: pressing a stroke picks it and dragging moves it
68
+ * (one undo step at the drop); pressing where no stroke painted clears the pick.
69
+ */
70
+ private strokeDown;
71
+ /** While a stroke is dragged: how far it has moved (document pixels), to draw its outline there. */
72
+ get strokeDrag(): {
73
+ id: string;
74
+ dx: number;
75
+ dy: number;
76
+ } | null;
66
77
  /**
67
78
  * The Stickers tool: pressing a sticker picks it and dragging moves it (one undo step at the
68
79
  * drop); pressing anywhere else places the active brush's first stamp there, at its tip size and
@@ -107,9 +118,16 @@ export declare class PaintCanvasPresenter {
107
118
  /** Draws what changed into `ctx` (a canvas the size of the document); returns the tiles drawn. */
108
119
  render(ctx: Paint2DContext): number;
109
120
  }
110
- export type GuideOverlayKind = 'symmetry' | 'perspective' | 'snap' | 'stencil' | 'sticker';
111
- /** Lines to draw over the canvas for the guides and the picked sticker, in document pixels, with a style key. */
112
- export declare function guideOverlay(controller: PaintEditorController): Array<{
121
+ export type GuideOverlayKind = 'symmetry' | 'perspective' | 'snap' | 'stencil' | 'sticker' | 'stroke';
122
+ /**
123
+ * Lines to draw over the canvas for the guides, the picked sticker and the picked stroke of a stroke layer (moved by
124
+ * `drag` while it is dragged), in document pixels, with a style key.
125
+ */
126
+ export declare function guideOverlay(controller: PaintEditorController, drag?: {
127
+ id: string;
128
+ dx: number;
129
+ dy: number;
130
+ } | null): Array<{
113
131
  from: Point2;
114
132
  to: Point2;
115
133
  kind: GuideOverlayKind;
@@ -238,6 +256,8 @@ export declare const STAMP_LABELS: Readonly<Record<StampKind, string>>;
238
256
  /** Toggles one stamp in a sticker brush's set (never leaving it empty). */
239
257
  export declare function toggleStamp(stamps: readonly StampKind[], stamp: StampKind): StampKind[];
240
258
  /** The sticker panel's sliders for the selected sticker. */
259
+ /** The brush sliders of a picked stroke on a stroke layer (paths into its brush; see `updateStroke`). */
260
+ export declare const STROKE_SLIDERS: readonly SliderControl[];
241
261
  export declare const STICKER_SLIDERS: readonly SliderControl[];
242
262
  /** Stencils a toolbar can lay with one click, centred on the canvas. */
243
263
  export declare function quickStencil(kind: 'ruler' | 'circle' | 'ellipse-mask' | 'edge-mask', canvas: {
@@ -24,6 +24,7 @@
24
24
  import { type MixerLoad, type RgbTriple } from '../paint/exchange.cjs';
25
25
  import { type WetFlowSpec } from '../paint/wet/flow.cjs';
26
26
  import { type PaintGradientSource } from '../paint/gradient-paint.cjs';
27
+ import { type EffectPaintPixels } from './effect-paint.cjs';
27
28
  import { type WetParams, type WetTilt } from '../paint/wet/model.cjs';
28
29
  import { type WetGpuProvider } from '../paint/wet/gpu.cjs';
29
30
  import { WetWorld, type WetBackendInfo, type WetPaperInput, type WetSnapshot, type WetWorldOptions } from '../paint/wet/world.cjs';
@@ -53,6 +54,12 @@ export interface WetStrokeInit {
53
54
  } | null;
54
55
  /** Gradient paint (resolved): each dab's pigment comes from it. */
55
56
  paint?: PaintGradientSource | null;
57
+ /**
58
+ * Effect paint: each pixel's pigment is the effect's colour there (its alpha scales the
59
+ * coverage), shifted by the paint the brush picks up. It then flows, blooms and granulates with
60
+ * the water like any pigment.
61
+ */
62
+ effect?: EffectPaintPixels | null;
56
63
  }
57
64
  /**
58
65
  * One wet-brush stroke: pen samples → dabs → wet tool edits. Points are applied only while the
@@ -75,6 +82,7 @@ export declare class WetStrokeDriver {
75
82
  private tip;
76
83
  private cov;
77
84
  private readonly paint;
85
+ private readonly centre;
78
86
  private readonly depth;
79
87
  constructor(init: WetStrokeInit);
80
88
  private readonly sampler;
@@ -24,6 +24,7 @@
24
24
  import { type MixerLoad, type RgbTriple } from '../paint/exchange.js';
25
25
  import { type WetFlowSpec } from '../paint/wet/flow.js';
26
26
  import { type PaintGradientSource } from '../paint/gradient-paint.js';
27
+ import { type EffectPaintPixels } from './effect-paint.js';
27
28
  import { type WetParams, type WetTilt } from '../paint/wet/model.js';
28
29
  import { type WetGpuProvider } from '../paint/wet/gpu.js';
29
30
  import { WetWorld, type WetBackendInfo, type WetPaperInput, type WetSnapshot, type WetWorldOptions } from '../paint/wet/world.js';
@@ -53,6 +54,12 @@ export interface WetStrokeInit {
53
54
  } | null;
54
55
  /** Gradient paint (resolved): each dab's pigment comes from it. */
55
56
  paint?: PaintGradientSource | null;
57
+ /**
58
+ * Effect paint: each pixel's pigment is the effect's colour there (its alpha scales the
59
+ * coverage), shifted by the paint the brush picks up. It then flows, blooms and granulates with
60
+ * the water like any pigment.
61
+ */
62
+ effect?: EffectPaintPixels | null;
56
63
  }
57
64
  /**
58
65
  * One wet-brush stroke: pen samples → dabs → wet tool edits. Points are applied only while the
@@ -75,6 +82,7 @@ export declare class WetStrokeDriver {
75
82
  private tip;
76
83
  private cov;
77
84
  private readonly paint;
85
+ private readonly centre;
78
86
  private readonly depth;
79
87
  constructor(init: WetStrokeInit);
80
88
  private readonly sampler;