@pixerate/editor 0.271.0 → 0.272.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 (56) hide show
  1. package/dist/animation-editor/index.cjs +60 -60
  2. package/dist/animation-editor/index.js +4 -4
  3. package/dist/brushes/index.cjs +69 -66
  4. package/dist/brushes/index.js +6 -3
  5. package/dist/brushes/patch.d.cts +1 -1
  6. package/dist/brushes/patch.d.ts +1 -1
  7. package/dist/brushes/schema.d.cts +1 -0
  8. package/dist/brushes/schema.d.ts +1 -0
  9. package/dist/brushes/types.d.cts +8 -0
  10. package/dist/brushes/types.d.ts +8 -0
  11. package/dist/{brushstrokeRender-WR2N5HHY.cjs → brushstrokeRender-5YBCLFDQ.cjs} +15 -15
  12. package/dist/{brushstrokeRender-A727TTNQ.js → brushstrokeRender-DZGFU3J4.js} +3 -3
  13. package/dist/canvas/index.cjs +13 -13
  14. package/dist/canvas/index.js +1 -1
  15. package/dist/{chunk-YNFSH72F.js → chunk-2F3YDXCN.js} +1 -1
  16. package/dist/{chunk-QYXUE37Q.js → chunk-2XDNF73E.js} +1 -1
  17. package/dist/{chunk-3KNQ2W6X.cjs → chunk-3JKCREEU.cjs} +59 -53
  18. package/dist/{chunk-B5W677L7.js → chunk-5HP2VSAS.js} +1 -1
  19. package/dist/{chunk-BPJSI4NT.cjs → chunk-7W2EQQBP.cjs} +2 -2
  20. package/dist/{chunk-LETF75CA.js → chunk-CLB2I2FU.js} +1 -1
  21. package/dist/{chunk-BAZMCFVL.js → chunk-DZVRH63Y.js} +1 -1
  22. package/dist/{chunk-U2ASNGO6.cjs → chunk-FXVCB6YG.cjs} +35 -35
  23. package/dist/{chunk-EU2ZZA6L.cjs → chunk-GHGBIAWQ.cjs} +126 -39
  24. package/dist/{chunk-2WOGXEDX.cjs → chunk-M3RZOF3G.cjs} +1 -1
  25. package/dist/{chunk-GSTSZPSR.js → chunk-N3SKPQEH.js} +225 -18
  26. package/dist/{chunk-J5VQYK7T.cjs → chunk-N5IMDAHM.cjs} +251 -44
  27. package/dist/{chunk-ININNHLM.js → chunk-NAHJV3O6.js} +11 -5
  28. package/dist/{chunk-JJ2H25JG.cjs → chunk-SNAFFCAX.cjs} +200 -174
  29. package/dist/{chunk-M2ZVPU7L.cjs → chunk-TNLKFW7D.cjs} +23 -23
  30. package/dist/{chunk-KZI3YWKW.js → chunk-UXYCY3HP.js} +93 -6
  31. package/dist/{chunk-DDL3ZBHK.cjs → chunk-YJANF2BL.cjs} +86 -86
  32. package/dist/{chunk-TNHDCP4R.js → chunk-ZEI7ZEA4.js} +31 -5
  33. package/dist/image-editor/index.cjs +789 -789
  34. package/dist/image-editor/index.js +5 -5
  35. package/dist/paint/index.cjs +2 -2
  36. package/dist/paint/index.js +1 -1
  37. package/dist/paint/wet/world.d.cts +37 -1
  38. package/dist/paint/wet/world.d.ts +37 -1
  39. package/dist/paint-editor/brush-controls.d.cts +2 -0
  40. package/dist/paint-editor/brush-controls.d.ts +2 -0
  41. package/dist/paint-editor/brush-model.d.cts +14 -1
  42. package/dist/paint-editor/brush-model.d.ts +14 -1
  43. package/dist/paint-editor/index.cjs +343 -306
  44. package/dist/paint-editor/index.js +48 -11
  45. package/dist/paint-editor/ui.d.cts +1 -1
  46. package/dist/paint-editor/ui.d.ts +1 -1
  47. package/dist/paint-editor/wet.d.cts +8 -1
  48. package/dist/paint-editor/wet.d.ts +8 -1
  49. package/dist/vector/index.cjs +999 -999
  50. package/dist/vector/index.js +5 -5
  51. package/package.json +1 -1
  52. package/skills/pixerate-brushes/SKILL.md +1 -0
  53. package/skills/pixerate-paint-editor/SKILL.md +4 -11
  54. package/skills/pixerate-paint-editor/references/brush-facets.md +1 -0
  55. package/skills/pixerate-paint-editor/references/ghost.md +47 -0
  56. package/skills/pixerate-paint-watercolour/SKILL.md +1 -0
@@ -8,7 +8,7 @@ import {
8
8
  listPresets,
9
9
  normalizeBrushSpec,
10
10
  resolveBrush
11
- } from "./chunk-KZI3YWKW.js";
11
+ } from "./chunk-UXYCY3HP.js";
12
12
  import {
13
13
  editorStampOf,
14
14
  stampCoverage
@@ -61,6 +61,7 @@ import {
61
61
  DEFAULT_FLOW,
62
62
  DEFAULT_WET_PARAMS,
63
63
  FLAT,
64
+ FREE_INTERVAL,
64
65
  PIGMENT_UNIT,
65
66
  WET_TILE,
66
67
  WetMedium,
@@ -73,7 +74,7 @@ import {
73
74
  normalizeTilt,
74
75
  normalizeWetParams,
75
76
  pigmentOf
76
- } from "./chunk-GSTSZPSR.js";
77
+ } from "./chunk-N3SKPQEH.js";
77
78
  import {
78
79
  BrushstrokeCache,
79
80
  brushstrokeDataUrl,
@@ -3729,12 +3730,17 @@ var WetStrokeDriver = class {
3729
3730
  const spacing = Math.max(0.02, brush.tip.spacing);
3730
3731
  const perDab = Math.min(1, spacing * 1.2);
3731
3732
  const thin = wet.thinner;
3733
+ const body = wet.body * (1 - thin);
3732
3734
  this.medium = new WetMedium(init.world, init.laneId, {
3733
3735
  water: STROKE_WATER * Math.min(1, wet.water * (1 + thin)) * perDab,
3734
3736
  mass: STROKE_MASS * wet.pigment * (1 - 0.6 * thin) * perDab,
3735
- body: wet.body * (1 - thin),
3737
+ body,
3736
3738
  light: 0
3737
3739
  });
3740
+ if (wet.tool === "paint" && brush.ghost && wet.pigment > 0) {
3741
+ const one = pigmentOf(init.color, body);
3742
+ init.world.startGhost(init.laneId, [one[0], one[1], one[2], one[3]], brush.ghost.linger, init.speed ?? 120);
3743
+ }
3738
3744
  this.lightBase = wet.tool === "paint" ? STROKE_LIGHT * brush.light.amount * (1 - 0.6 * thin) * perDab : 0;
3739
3745
  const rates = exchangeRates(brush.behavior.pickup, brush.behavior.mix, wet.load, brush.behavior.mixing);
3740
3746
  this.states = copies.map((c, i) => ({
@@ -3863,6 +3869,22 @@ var WetStrokeDriver = class {
3863
3869
  if (!(k > 0)) return;
3864
3870
  switch (wet.tool) {
3865
3871
  case "paint": {
3872
+ if (brush.ghost) {
3873
+ const smear = brush.ghost.smear;
3874
+ if (wet.pigment > 0) {
3875
+ this.medium.options.light = this.medium.options.mass;
3876
+ this.medium.deposit(rect, cov, k, this.init.color, null);
3877
+ } else {
3878
+ this.medium.options.light = 0;
3879
+ world.paint(laneId, rect, cov, this.medium.options.water * k * (wet.water > 0 ? 1 : 0), null);
3880
+ }
3881
+ if (smear > 0) {
3882
+ const rw = Math.max(wet.rewet, 0.6) * smear;
3883
+ if (rw > 0) world.rewet(laneId, rect, cov, rw * k * 0.5, this.init.paperColor, true);
3884
+ if (st.last) world.drag(laneId, rect, tip, d.x - st.last.x, d.y - st.last.y, smear * k);
3885
+ }
3886
+ break;
3887
+ }
3866
3888
  const ex = st.exchange;
3867
3889
  this.medium.options.light = this.lightBase * (brush.light.pressure ? d.pressure : 1);
3868
3890
  let flow = 1;
@@ -4093,7 +4115,7 @@ var PaintWetLayers = class {
4093
4115
  if (!w.hasLane(layerId)) {
4094
4116
  const base = this.host.layerSurface(layerId) ?? new TiledSurface(4, /* @__PURE__ */ new Map(), 0);
4095
4117
  const s = this.settingsOf(layerId, medium);
4096
- w.ensureLane(layerId, { params: s.params, base, light: this.host.layerLight(layerId) });
4118
+ w.ensureLane(layerId, { params: s.params, base, light: this.host.layerLight(layerId), ghost: s.ghost });
4097
4119
  const { width, height } = this.host.canvas();
4098
4120
  if (s.flow.kind !== "none") w.setFlow(layerId, flowField(s.flow, width, height), s.flow.strength);
4099
4121
  }
@@ -4127,6 +4149,7 @@ var PaintWetLayers = class {
4127
4149
  info(layerId) {
4128
4150
  const s = this.settingsOf(layerId);
4129
4151
  const st = this.world?.hasLane(layerId) ? this.world.stats(layerId) : null;
4152
+ const g = this.world?.hasLane(layerId) ? this.world.getGhost(layerId) : s.ghost ?? null;
4130
4153
  return {
4131
4154
  layerId,
4132
4155
  wet: Boolean(st && st.wetCells > 0),
@@ -4134,7 +4157,8 @@ var PaintWetLayers = class {
4134
4157
  wetBounds: st?.wetBounds ?? null,
4135
4158
  activeTiles: st?.activeTiles ?? 0,
4136
4159
  params: { ...s.params },
4137
- flow: { ...s.flow }
4160
+ flow: { ...s.flow },
4161
+ ...g ? { ghost: { remaining: Math.round(g.remaining * FREE_INTERVAL / this.speed * 100) / 100 } } : {}
4138
4162
  };
4139
4163
  }
4140
4164
  backend() {
@@ -4191,6 +4215,8 @@ var PaintWetLayers = class {
4191
4215
  const base = w.getBase(id);
4192
4216
  const light = w.isLit(id) ? w.getLight(id) : null;
4193
4217
  w.removeLane(id);
4218
+ const s = this.settings.get(id);
4219
+ if (s?.ghost) delete s.ghost;
4194
4220
  if (light && this.host.layerLight(id) !== light) this.host.updateLights(/* @__PURE__ */ new Map([[id, light]]));
4195
4221
  this.host.updateSurfaces(/* @__PURE__ */ new Map([[id, base]]), []);
4196
4222
  }