@pixerate/editor 0.275.0 → 0.276.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/animation-editor/index.cjs +62 -62
  2. package/dist/animation-editor/index.js +6 -6
  3. package/dist/brushes/index.cjs +81 -70
  4. package/dist/brushes/index.js +17 -6
  5. package/dist/brushes/patch.d.cts +1 -1
  6. package/dist/brushes/patch.d.ts +1 -1
  7. package/dist/brushes/profiles.d.cts +2 -0
  8. package/dist/brushes/profiles.d.ts +2 -0
  9. package/dist/brushes/schema.d.cts +1 -0
  10. package/dist/brushes/schema.d.ts +1 -0
  11. package/dist/brushes/types.d.cts +22 -1
  12. package/dist/brushes/types.d.ts +22 -1
  13. package/dist/{brushstrokeRender-WGY4DZHF.js → brushstrokeRender-FK3ASUUJ.js} +5 -5
  14. package/dist/{brushstrokeRender-2RQL46WB.cjs → brushstrokeRender-I6MYFCOU.cjs} +21 -21
  15. package/dist/canvas/index.cjs +13 -13
  16. package/dist/canvas/index.js +1 -1
  17. package/dist/chart/contract.d.cts +3 -1
  18. package/dist/chart/contract.d.ts +3 -1
  19. package/dist/{chunk-Y2ISSVPH.js → chunk-4EM5NGCL.js} +167 -9
  20. package/dist/{chunk-Y354ETAE.cjs → chunk-5HR5CSLC.cjs} +49 -49
  21. package/dist/{chunk-LMG57L5A.js → chunk-CTHWXW5M.js} +121 -8
  22. package/dist/{chunk-43XJC3PP.js → chunk-CVBTJVRN.js} +1 -1
  23. package/dist/{chunk-RJGW3RQS.js → chunk-GHYJAMMS.js} +1 -1
  24. package/dist/{chunk-NIBFKXMD.cjs → chunk-IFWLZZCW.cjs} +619 -2
  25. package/dist/{chunk-G5TCMKX5.js → chunk-IJ6NSWKM.js} +2 -2
  26. package/dist/{chunk-C6VB7CPY.cjs → chunk-ISCAJBPQ.cjs} +1 -1
  27. package/dist/{chunk-W6JDUXP3.js → chunk-J23JOHPR.js} +1 -1
  28. package/dist/{chunk-IEEY5RJV.js → chunk-JNMNM3SL.js} +1 -1
  29. package/dist/{chunk-HVO6XCI4.js → chunk-JPB65KQ6.js} +1 -1
  30. package/dist/{chunk-ACTHSQOI.js → chunk-LDZOXESA.js} +618 -1
  31. package/dist/{chunk-DHC4E2DU.cjs → chunk-MITQGHN3.cjs} +121 -8
  32. package/dist/{chunk-STLTOISW.cjs → chunk-NPPMKMCU.cjs} +17 -17
  33. package/dist/{chunk-75SYKUOT.js → chunk-OS6OG7DN.js} +1 -1
  34. package/dist/{chunk-OLZXXAER.cjs → chunk-OY24XRYF.cjs} +408 -250
  35. package/dist/{chunk-6QNDGMK7.cjs → chunk-Q33V5PEF.cjs} +123 -42
  36. package/dist/{chunk-JDXWLCXF.cjs → chunk-QNNZA3V5.cjs} +2 -2
  37. package/dist/{chunk-T6KNJVBP.cjs → chunk-U26LUXCJ.cjs} +35 -35
  38. package/dist/{chunk-62MFUHSI.cjs → chunk-UQXULAMQ.cjs} +16 -16
  39. package/dist/{chunk-RAPNRK4R.cjs → chunk-X7XBEX3O.cjs} +88 -88
  40. package/dist/{chunk-MSWLJI4G.js → chunk-XMSH66VU.js} +2 -2
  41. package/dist/{chunk-ZM7IKQ4X.js → chunk-XVPQNX7O.js} +89 -8
  42. package/dist/{chunk-YYZC2EQO.cjs → chunk-ZIE6EJGR.cjs} +23 -23
  43. package/dist/image-editor/index.cjs +880 -852
  44. package/dist/image-editor/index.js +36 -8
  45. package/dist/paint/index.cjs +33 -5
  46. package/dist/paint/index.d.cts +1 -0
  47. package/dist/paint/index.d.ts +1 -0
  48. package/dist/paint/index.js +32 -4
  49. package/dist/paint/live-patterns.d.cts +149 -0
  50. package/dist/paint/live-patterns.d.ts +149 -0
  51. package/dist/paint/wet/world.d.cts +13 -0
  52. package/dist/paint/wet/world.d.ts +13 -0
  53. package/dist/paint-editor/brush-model.d.cts +7 -1
  54. package/dist/paint-editor/brush-model.d.ts +7 -1
  55. package/dist/paint-editor/controller.d.cts +52 -0
  56. package/dist/paint-editor/controller.d.ts +52 -0
  57. package/dist/paint-editor/index.cjs +850 -510
  58. package/dist/paint-editor/index.js +355 -15
  59. package/dist/paint-editor/ui.d.cts +5 -1
  60. package/dist/paint-editor/ui.d.ts +5 -1
  61. package/dist/paint-editor/wet-tools.d.cts +42 -0
  62. package/dist/paint-editor/wet-tools.d.ts +42 -0
  63. package/dist/paint-editor/wet.d.cts +22 -1
  64. package/dist/paint-editor/wet.d.ts +22 -1
  65. package/dist/vector/index.cjs +1002 -1002
  66. package/dist/vector/index.js +7 -7
  67. package/package.json +1 -1
  68. package/skills/pixerate-brushes/SKILL.md +1 -0
  69. package/skills/pixerate-paint-editor/SKILL.md +7 -1
  70. package/skills/pixerate-paint-editor/references/brush-facets.md +1 -0
  71. package/skills/pixerate-paint-editor/references/live-patterns.md +41 -0
  72. package/skills/pixerate-paint-watercolour/SKILL.md +8 -0
@@ -35,7 +35,7 @@ import {
35
35
  traceField,
36
36
  traceVectorImage,
37
37
  vectorTraceContours
38
- } from "../chunk-75SYKUOT.js";
38
+ } from "../chunk-OS6OG7DN.js";
39
39
  import {
40
40
  rasterizeCoverage
41
41
  } from "../chunk-ADMRNWR7.js";
@@ -66,7 +66,7 @@ import {
66
66
  reverseMorphContour,
67
67
  subpathToMorphContour,
68
68
  turnMorphContour
69
- } from "../chunk-43XJC3PP.js";
69
+ } from "../chunk-CVBTJVRN.js";
70
70
  import {
71
71
  DEFAULT_VECTOR_FONT,
72
72
  IDENTITY_MATRIX,
@@ -556,10 +556,10 @@ import {
556
556
  withVectorStrokes,
557
557
  withVectorTargetPaint,
558
558
  zigzagPaths
559
- } from "../chunk-Y2ISSVPH.js";
559
+ } from "../chunk-4EM5NGCL.js";
560
560
  import {
561
561
  snapshotBrushLibrary
562
- } from "../chunk-ZM7IKQ4X.js";
562
+ } from "../chunk-XVPQNX7O.js";
563
563
  import "../chunk-JL6YH5WD.js";
564
564
  import {
565
565
  createProvenance
@@ -597,11 +597,11 @@ import {
597
597
  resolveEffectValues
598
598
  } from "../chunk-MV7CYFMJ.js";
599
599
  import "../chunk-V2ZCJRDM.js";
600
- import "../chunk-LMG57L5A.js";
601
- import "../chunk-W6JDUXP3.js";
600
+ import "../chunk-CTHWXW5M.js";
601
+ import "../chunk-J23JOHPR.js";
602
602
  import {
603
603
  GRAIN_PATTERNS
604
- } from "../chunk-ACTHSQOI.js";
604
+ } from "../chunk-LDZOXESA.js";
605
605
  import "../chunk-4D6KP5BV.js";
606
606
  import "../chunk-ODBT55Q7.js";
607
607
  import "../chunk-IRSTHLQQ.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor",
3
- "version": "0.275.0",
3
+ "version": "0.276.0",
4
4
  "description": "UI-agnostic rich text and media editing core library",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -25,6 +25,7 @@ built-in presets (read-only) and the user's brushes, shared by every editor that
25
25
  | Iridescence | Structural thin-film interference (`thickness` 100..1000 nm, `pressureToThickness` 0..1, `ior` 1.2..2.0) whose hue shifts with light and view tilt (`scarab-lacquer`, `soap-film`, `pearl-glaze`). |
26
26
  | Ghost | On wet paint (`behaviour.surface: "wet"`): `linger` (0.5..60 s before the brush's own colour fades away) and `smear` (0..1, how much it lifts and drags the paint it crosses). Presets `ghost-wash`, `ghost-gouache`, `ghost-oil` and `invisible-ink`. |
27
27
  | Motion | Animation after painting (live effect paint, particle `waveSpeed`). |
28
+ | Live patterns | `livePatterns`: Gray-Scott reaction-diffusion patterns (`pattern`: `spots`, `stripes`, `coral`, `maze`, `worms`, `feed`, `kill`, `scale`, `contrast`, `secondColor`, `relief`) that grow in wet paint (`behaviour.surface: 'wet'`) and freeze when it dries. Built-in presets: `turing-wash`, `coral-ink`. |
28
29
  | Colour | A `default` colour, a `palette` of up to 16, `own` (always its own colour). Each is a hex or `rgba()` colour, a light / dark pair `{ light, dark }`, a gradient or effect paint. A gradient default is always painted; a solid or light / dark default becomes the editor's colour when the brush is chosen (unless the user locked theirs), resolved for the colour scheme. Canvas strokes and vector brushstrokes take it too, when they are given no colour. Canvas and vector have the same lock (`canvas.setColorLocked`, `vector.setColorLocked`), and a canvas colour taken from a light / dark default follows the scheme like the paint editor's; vector strokes already made keep theirs. |
29
30
 
30
31
  How media map to facets: a **pencil** or **charcoal** is `dry` with high `grain` and tilt;
@@ -118,6 +118,9 @@ Which facet sets which engine setting: [references/brush-facets.md](references/b
118
118
  ## Wet media
119
119
 
120
120
  Watercolour, gouache and wet oil run on a fluid simulation: lay washes light to dark, let them flow (`advance_wet_paint`), dry them (`dry_paint`) before glazing. Nothing moves for an agent until you advance or dry it, and saving dries the paint. Load `pixerate-paint-watercolour`, and read [references/wet-media.md](references/wet-media.md) for the engine and the wet tools. **Ghost paint and invisible ink** (`ghost` facet: `ghost-wash`, `ghost-gouache`, `ghost-oil`, `invisible-ink`) mix and flow while wet, then fade without leaving their own colour, leaving only a smear in the paint they touched: read [references/ghost.md](references/ghost.md).
121
+ **Live patterns** (Gray-Scott reaction-diffusion spots, stripes, coral, maze and worms that grow
122
+ in wet paint and freeze when it dries; presets `turing-wash`, `coral-ink`):
123
+ [references/live-patterns.md](references/live-patterns.md).
121
124
 
122
125
  ## Oils, thick paint and smart inks
123
126
 
@@ -247,7 +250,7 @@ Listing, saving, sharing and previewing brushes are the brush library's tools (`
247
250
  | Tool | Use |
248
251
  | --- | --- |
249
252
  | `get_brush` | Read a brush as facets (`brush`), or the active brush as edited (no `id`), with the `engine` and `category` it paints with, `builtin` (an unchanged preset) and `strokePaint` (what its next stroke paints). Read before changing a brush you did not build. |
250
- | `set_brush` | Choose the active brush (`id`, from `list_brush_presets`) and / or lay facets over it: `tip`, `marks`, `dynamics`, `behaviour`, `light`, `iridescence`, `ghost`, `mutation`, `motion`, `colour` (objects merge, lists replace; marks of another kind replace the marks), `unset` facets to drop. Editor state, not saved: `create_brush` stores a brush. Returns `brush` (facets), `engine` and `problems` (values clamped). The old flat fields (`particle`, `impasto`, `behavior`…) are refused. |
253
+ | `set_brush` | Choose the active brush (`id`, from `list_brush_presets`) and / or lay facets over it: `tip`, `marks`, `dynamics`, `behaviour`, `light`, `iridescence`, `ghost`, `mutation`, `motion`, `colour`, `livePatterns` (objects merge, lists replace; marks of another kind replace the marks), `unset` facets to drop. Editor state, not saved: `create_brush` stores a brush. Returns `brush` (facets), `engine` and `problems` (values clamped). The old flat fields (`particle`, `impasto`, `behavior`…) are refused. |
251
254
 
252
255
  ### Colour
253
256
 
@@ -311,6 +314,9 @@ Listing, saving, sharing and previewing brushes are the brush library's tools (`
311
314
  | `set_water_overlay` | Show where the water is (`visible`), view only. |
312
315
  | `set_wet_engine` | Let Engine B (WebGPU in browsers, Metal in the Swift editors) shade large washes (`gpu` "auto", the default) or force the CPU (`gpu` "off"); `minTiles` sets the wet area at which the GPU takes over. Never changes the result, only how it is drawn; editor setting, not saved, not an undo step. Returns `engine` (`state`: off, not-started, starting, unavailable, standby, active, failed; `reason`, `adapter`). |
313
316
  | `set_instant_dry` | `on`: every wet stroke dries as it ends (same undo step); off (default) wet paint keeps moving. Returns `instantDry`. |
317
+ | `get_live_patterns` | Read live reaction-diffusion pattern fields on one layer (`layerId`) or every layer, plus the Pearson `presets` (`spots`, `stripes`, `coral`, `maze`, `worms`) and built-in `brushPresets` (`turing-wash`, `coral-ink`). Returns `layers` (`active`, `settings`, `activeTiles`, `patternCells`, `wetPatternCells`, `maxV`, `meanV`, `bounds`). Changes nothing. |
318
+ | `set_live_patterns` | Configure a layer's Gray-Scott reaction-diffusion settings (`layerId`, `pattern`, `feed`, `kill`, `scale`, `contrast`, `secondColor`, `relief`). One undo step. Returns `layerId`, `settings`, `stats` and `stillWet`. |
319
+ | `seed_live_patterns` | Seed Gray-Scott reagent V at `points` (`[{x, y}]` in document px) with `radius` and `seed` on a layer (`layerId`, default active), optionally updating pattern settings (`pattern`, `feed`, `kill`, `scale`, `contrast`, `secondColor`, `relief`). Follow with `advance_wet_paint` to grow the pattern while wet, then `dry_paint` to freeze it. One undo step. Returns `layerId`, `seeded`, `radius`, `seed`, `settings`, `stats`, `stillWet`. |
314
320
 
315
321
  ### Thick paint, light and smart inks
316
322
 
@@ -20,6 +20,7 @@ more; this is where each one went.
20
20
  | Bristles | `tip.shape` `bristle` and `tip.bristle` |
21
21
  | A brush's own gradient (paint) | `colour.default` (a gradient); `unset: ['colour']` drops it |
22
22
  | Light | `light` (`amount`, `pressure`) |
23
+ | Live reaction-diffusion patterns in wet paint | `livePatterns` (`pattern`: `spots` / `stripes` / `coral` / `maze` / `worms`, `feed`, `kill`, `scale`, `contrast`, `secondColor`, `relief`); `unset: ['livePatterns']` drops it |
23
24
  | UV-fluorescent ink (glows under `set_uv_light`, optional invisible ink) | `fluorescence` (`amount` 0..1, `invisible`); `unset: ['fluorescence']` drops it |
24
25
  | Thermochromic ink (shifts toward `hotColor` where `paint_heat` warms the canvas) | `thermochromic` (`hotColor` `#rrggbb`, `threshold` 0.05..0.95); `unset: ['thermochromic']` drops it |
25
26
  | Thin-film iridescence | `iridescence` (`thickness` 100..1000 nm, `pressureToThickness` 0..1, `ior` 1.2..2.0); `unset: ['iridescence']` drops it |
@@ -0,0 +1,41 @@
1
+ # Live patterns in wet paint
2
+
3
+ Live patterns are Gray-Scott reaction-diffusion patterns (`spots`, `stripes`, `coral`, `maze`, `worms`) that grow inside wet paint while water is present and **freeze when the paint dries**.
4
+
5
+ ## How it works
6
+
7
+ 1. **Seeding**:
8
+ - Paint with a wet brush carrying the `livePatterns` facet (built-in presets `turing-wash` and `coral-ink`, or `set_brush` / `paint_stroke` `brush: { livePatterns: { pattern: "spots", ... } }`), or
9
+ - Call `seed_live_patterns` on a wet layer (`points`, `radius`, `seed`, and optional pattern settings).
10
+ 2. **Growth**:
11
+ - Every `advance_wet_paint` step runs reaction-diffusion substeps on the layer's pattern field `(U, V)` at half tile resolution (`128 × 128` per `256 × 256` tile).
12
+ - Reaction-diffusion only runs where the wet world still holds water (`rho + sw > DRY_EPS`). Where the paint is dry, the rate is zero, so the pattern freezes in place.
13
+ 3. **Shading, relief and drying**:
14
+ - On screen and when baking (`dry_paint` or natural evaporation), reagent `V` blends the paint colour toward `secondColor` (or modulates pigment contrast when `secondColor` is `null`).
15
+ - When `relief > 0`, reagent `V` also writes thick height (`get_relief`), so pattern ridges catch the editor's light (`set_lighting`).
16
+ - Calling `dry_paint` bakes the pattern into the layer's pixels and freezes it permanently.
17
+
18
+ ## Pattern presets and tuning
19
+
20
+ | Pattern | Pearson `(feed, kill)` | Look |
21
+ | --- | --- | --- |
22
+ | `spots` | `(0.035, 0.065)` | Mitosis spots and cell clusters (`turing-wash`) |
23
+ | `stripes` | `(0.030, 0.062)` | Parallel and branching Turing stripes |
24
+ | `coral` | `(0.0545, 0.062)` | Branching coral dendrites (`coral-ink`) |
25
+ | `maze` | `(0.029, 0.057)` | Dense labyrinthine ridges |
26
+ | `worms` | `(0.058, 0.065)` | Vermiculate worm tracks |
27
+
28
+ Settings on `livePatterns`, `set_live_patterns` and `seed_live_patterns`:
29
+ - `pattern`: `'spots' | 'stripes' | 'coral' | 'maze' | 'worms'`
30
+ - `feed` (`0.005..0.1`), `kill` (`0.01..0.1`): explicit Gray-Scott feed and kill rates (setting `pattern` without `feed` / `kill` resets them to that preset's Pearson constants)
31
+ - `scale` (`0.25..4`, default `1`): diffusion scale for wider or finer features
32
+ - `contrast` (`0..2`, default `1`): strength of the pattern in the wet pigment
33
+ - `secondColor` (`#rrggbb` or `null`): second colour mixed where `V` concentrates; `null` darkens and lightens the wet pigment itself
34
+ - `relief` (`0..1`, default `0`): embosses `V` into the layer's height map so ridges catch the light
35
+
36
+ ## Workflow: let it grow, then dry
37
+
38
+ 1. Paint a wet wash with `turing-wash` or `coral-ink` (or lay a wash with `watercolor-wash` and call `seed_live_patterns`).
39
+ 2. Call `advance_wet_paint` (`steps` 30..120 or `seconds` 0.5..2) to let the pattern spread and branch inside the wet area.
40
+ 3. Check progress with `get_live_patterns` (`patternCells`, `wetPatternCells`, `maxV`, `meanV`) or `render_preview`.
41
+ 4. Call `dry_paint` once the pattern reaches the look you want so it freezes and bakes into the layer.
@@ -63,6 +63,12 @@ light that flows and dries with its pigment: paint it on dark paper, let it flow
63
63
  `backlight` on any paper) before painting: strong transparent glazes glow, gouache and solid ink
64
64
  block the light. See `references/light-paint.md` in `pixerate-paint-editor`.
65
65
 
66
+ **Live reaction-diffusion patterns (let it grow, then dry).** Paint with `turing-wash` or
67
+ `coral-ink` (or seed any wet wash with `seed_live_patterns` and tune with `set_live_patterns`),
68
+ then call `advance_wet_paint` to let Gray-Scott spots, stripes, coral, maze or worms grow where the
69
+ layer holds water. Call `dry_paint` to freeze the pattern in place (`get_live_patterns` checks its
70
+ coverage). See `references/live-patterns.md` in `pixerate-paint-editor`.
71
+
66
72
  ## Decision table
67
73
 
68
74
  | Want | Approach |
@@ -77,6 +83,7 @@ block the light. See `references/light-paint.md` in `pixerate-paint-editor`.
77
83
  | Cauliflower blooms | Add water into a drying wash; `bloom` up |
78
84
  | A glowing (neon) wash | Dark paper (`set_paper` `color`), `glow-wash` or `light.amount` on a wet brush; flow, dry, `get_light` |
79
85
  | Stained glass, a lightbox | `set_paper` `stained-glass` (or `backlight`); strong glazes for panes, opaque black lines above |
86
+ | Organic spots, coral dendrites or Turing stripes in a wash | Paint with `turing-wash` or `coral-ink` (or `seed_live_patterns` into a wet wash), `advance_wet_paint` to let it grow, then `dry_paint` to freeze it |
80
87
  | Disturb or smear a wash without adding colour | `ghost-wash`, `ghost-gouache` or `invisible-ink` (`ghost` `linger`, `smear`) on the same layer; see `references/ghost.md` |
81
88
 
82
89
  ## Recipes
@@ -111,6 +118,7 @@ warm colour near the horizon → `advance_wet_paint` → `blot` a few clouds →
111
118
  - `paint_stroke`: washes, shapes and details, and the wet tools (water, dryer, blot)
112
119
  - `wet_paper`, `advance_wet_paint`, `dry_paint`, `get_wet_paint`: wet-in-wet, flow, drying and checking
113
120
  - `set_wet_settings`, `set_canvas_tilt`, `set_flow_map`: tune and steer the water
121
+ - `get_live_patterns`, `set_live_patterns`, `seed_live_patterns`: grow and tune reaction-diffusion patterns in wet washes
114
122
  - `get_light`: check a glowing wash's light once it dries
115
123
  - `undo_paint`: take back a step
116
124
  - `export_image`: deliver