@pixerate/editor 0.267.0 → 0.268.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/dist/animation-editor/index.cjs +62 -62
- package/dist/animation-editor/index.js +6 -6
- package/dist/brushes/index.cjs +198 -72
- package/dist/brushes/index.d.cts +4 -3
- package/dist/brushes/index.d.ts +4 -3
- package/dist/brushes/index.js +136 -10
- package/dist/brushes/library.d.cts +27 -1
- package/dist/brushes/library.d.ts +27 -1
- package/dist/brushes/profiles.d.cts +4 -0
- package/dist/brushes/profiles.d.ts +4 -0
- package/dist/brushes/schema.d.cts +4 -0
- package/dist/brushes/schema.d.ts +4 -0
- package/dist/brushes/sources.d.cts +114 -0
- package/dist/brushes/sources.d.ts +114 -0
- package/dist/brushes/types.d.cts +37 -5
- package/dist/brushes/types.d.ts +37 -5
- package/dist/brushes/ui.d.cts +40 -4
- package/dist/brushes/ui.d.ts +40 -4
- package/dist/{brushstrokeRender-NLFPEBGI.js → brushstrokeRender-A727TTNQ.js} +6 -6
- package/dist/{brushstrokeRender-L7JYRR2R.cjs → brushstrokeRender-WR2N5HHY.cjs} +22 -22
- package/dist/canvas/index.cjs +13 -13
- package/dist/canvas/index.js +1 -1
- package/dist/{chunk-J2TNIZ55.cjs → chunk-2WOGXEDX.cjs} +1 -1
- package/dist/{chunk-JGWVZPT6.js → chunk-3XDSNIGF.js} +72 -5
- package/dist/{chunk-EXB2EGBE.cjs → chunk-62MFUHSI.cjs} +16 -16
- package/dist/{chunk-FGJHJIMN.js → chunk-74ODPZLX.js} +10 -10
- package/dist/{chunk-GCVFEPJG.js → chunk-ACTHSQOI.js} +182 -0
- package/dist/{chunk-LHPEG5AU.cjs → chunk-B3G7BKUV.cjs} +90 -90
- package/dist/{chunk-EF7LZAXQ.js → chunk-BAZMCFVL.js} +1 -1
- package/dist/{chunk-HIO6E7LC.cjs → chunk-BPJSI4NT.cjs} +2 -2
- package/dist/{chunk-XVOP3CGQ.cjs → chunk-EU2ZZA6L.cjs} +393 -62
- package/dist/{chunk-YIC6MAJ2.js → chunk-HFY5LG5J.js} +1 -1
- package/dist/{chunk-7UKFXXWL.js → chunk-HVO6XCI4.js} +1 -1
- package/dist/{chunk-OKHKA43L.cjs → chunk-JBB3GDBB.cjs} +330 -216
- package/dist/{chunk-AGNUD5BI.js → chunk-KZI3YWKW.js} +351 -20
- package/dist/{chunk-EYSHTYLG.js → chunk-LETF75CA.js} +1 -1
- package/dist/{chunk-FQPUF2W2.cjs → chunk-NIBFKXMD.cjs} +217 -35
- package/dist/{chunk-G7NHE2VD.cjs → chunk-NPWWSCWT.cjs} +35 -35
- package/dist/{chunk-OSEXT7JL.js → chunk-QNY7BDFP.js} +1 -1
- package/dist/{chunk-PXDIAYB6.cjs → chunk-STLTOISW.cjs} +34 -214
- package/dist/{chunk-4IDUYB45.js → chunk-UVTO3D4E.js} +130 -16
- package/dist/{chunk-TXFWZ5ZJ.js → chunk-W6JDUXP3.js} +4 -184
- package/dist/{chunk-LA5Y4ETA.cjs → chunk-YOVXQHA3.cjs} +23 -23
- package/dist/{chunk-DT4YQUGT.cjs → chunk-YXP6X3SY.cjs} +101 -34
- package/dist/image-editor/index.cjs +851 -851
- package/dist/image-editor/index.js +23 -23
- package/dist/paint/index.cjs +5 -5
- package/dist/paint/index.js +11 -11
- package/dist/paint-editor/brush-library-tools.d.cts +12 -2
- package/dist/paint-editor/brush-library-tools.d.ts +12 -2
- package/dist/paint-editor/brush-model.d.cts +29 -1
- package/dist/paint-editor/brush-model.d.ts +29 -1
- package/dist/paint-editor/brush-source-art.d.cts +32 -0
- package/dist/paint-editor/brush-source-art.d.ts +32 -0
- package/dist/paint-editor/controller.d.cts +6 -1
- package/dist/paint-editor/controller.d.ts +6 -1
- package/dist/paint-editor/dab-stroke.d.cts +2 -0
- package/dist/paint-editor/dab-stroke.d.ts +2 -0
- package/dist/paint-editor/engine.d.cts +11 -2
- package/dist/paint-editor/engine.d.ts +11 -2
- package/dist/paint-editor/index.cjs +576 -481
- package/dist/paint-editor/index.d.cts +3 -1
- package/dist/paint-editor/index.d.ts +3 -1
- package/dist/paint-editor/index.js +127 -32
- package/dist/paint-editor/stamp-tip.d.cts +8 -5
- package/dist/paint-editor/stamp-tip.d.ts +8 -5
- package/dist/paint-editor/thumbnails.d.cts +6 -0
- package/dist/paint-editor/thumbnails.d.ts +6 -0
- package/dist/paint-editor/tip-grain.d.cts +34 -0
- package/dist/paint-editor/tip-grain.d.ts +34 -0
- package/dist/raster/index.cjs +2 -2
- package/dist/raster/index.js +9 -9
- package/dist/vector/index.cjs +1002 -1002
- package/dist/vector/index.js +7 -7
- package/package.json +1 -1
- package/skills/pixerate-brushes/SKILL.md +35 -8
- package/skills/pixerate-brushes-design/SKILL.md +8 -1
- package/skills/pixerate-paint-editor/SKILL.md +6 -0
- package/skills/pixerate-paint-editor/references/brush-facets.md +3 -1
- package/skills/pixerate-paint-sketch-to-finish/SKILL.md +1 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
+
TileableNoise,
|
|
3
|
+
hash2,
|
|
2
4
|
rand01
|
|
3
5
|
} from "./chunk-4D6KP5BV.js";
|
|
4
6
|
import {
|
|
@@ -1078,6 +1080,180 @@ function coverageTileCoord(key) {
|
|
|
1078
1080
|
return tileCoord(key);
|
|
1079
1081
|
}
|
|
1080
1082
|
|
|
1083
|
+
// src/paint/grain.ts
|
|
1084
|
+
var GRAIN_PATTERNS = ["smooth", "cold-pressed", "hot-pressed", "rough", "vellum", "laid", "ingres", "sanded", "canvas", "linen", "gesso"];
|
|
1085
|
+
var GRAIN_TILE = 256;
|
|
1086
|
+
var clamp01 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
1087
|
+
function patternHeights(pattern, n, seed) {
|
|
1088
|
+
const out = new Float32Array(n * n);
|
|
1089
|
+
const salt = Math.imul(seed | 0, 2654435761) + 17;
|
|
1090
|
+
if (pattern === "smooth") return out.fill(1);
|
|
1091
|
+
const noise = (cx, cy, oct, s = 0) => new TileableNoise(n, cx, cy, oct, salt + s);
|
|
1092
|
+
const k = n / GRAIN_TILE;
|
|
1093
|
+
switch (pattern) {
|
|
1094
|
+
case "cold-pressed": {
|
|
1095
|
+
const base = noise(20 * k, 20 * k, 4);
|
|
1096
|
+
const fine = noise(64 * k, 64 * k, 2, 3);
|
|
1097
|
+
for (let y = 0; y < n; y++)
|
|
1098
|
+
for (let x = 0; x < n; x++) out[y * n + x] = clamp01((base.at(x, y) - 0.5) * 1.8 + 0.5 + (fine.at(x, y) - 0.5) * 0.5 + (hash2(x, y, salt) - 0.5) * 0.12);
|
|
1099
|
+
break;
|
|
1100
|
+
}
|
|
1101
|
+
case "hot-pressed": {
|
|
1102
|
+
const base = noise(40 * k, 40 * k, 3);
|
|
1103
|
+
for (let y = 0; y < n; y++) for (let x = 0; x < n; x++) out[y * n + x] = clamp01((base.at(x, y) - 0.5) * 1.1 + 0.6 + (hash2(x, y, salt) - 0.5) * 0.08);
|
|
1104
|
+
break;
|
|
1105
|
+
}
|
|
1106
|
+
case "rough": {
|
|
1107
|
+
const base = noise(10 * k, 10 * k, 5);
|
|
1108
|
+
const blot = noise(28 * k, 28 * k, 2, 5);
|
|
1109
|
+
for (let y = 0; y < n; y++)
|
|
1110
|
+
for (let x = 0; x < n; x++) out[y * n + x] = clamp01((base.at(x, y) - 0.5) * 2.4 + 0.5 + (blot.at(x, y) - 0.5) * 0.7 + (hash2(x, y, salt) - 0.5) * 0.15);
|
|
1111
|
+
break;
|
|
1112
|
+
}
|
|
1113
|
+
case "vellum": {
|
|
1114
|
+
const base = noise(40 * k, 40 * k, 3);
|
|
1115
|
+
for (let y = 0; y < n; y++) for (let x = 0; x < n; x++) out[y * n + x] = clamp01((base.at(x, y) - 0.5) * 1.6 + 0.55 + (hash2(x, y, salt) - 0.5) * 0.2);
|
|
1116
|
+
break;
|
|
1117
|
+
}
|
|
1118
|
+
case "laid": {
|
|
1119
|
+
const pulp = noise(32 * k, 32 * k, 3);
|
|
1120
|
+
const chain = n / 8;
|
|
1121
|
+
for (let y = 0; y < n; y++) {
|
|
1122
|
+
const laid = 0.5 + 0.5 * Math.cos(2 * Math.PI * y / 4);
|
|
1123
|
+
for (let x = 0; x < n; x++) {
|
|
1124
|
+
const c = Math.abs((x + 0.5) % chain - chain / 2) / (chain / 2);
|
|
1125
|
+
const chainLine = c > 0.94 ? -0.35 : 0;
|
|
1126
|
+
out[y * n + x] = clamp01(0.3 + 0.5 * laid + chainLine + (pulp.at(x, y) - 0.5) * 0.6);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
break;
|
|
1130
|
+
}
|
|
1131
|
+
case "ingres": {
|
|
1132
|
+
const fibres = noise(64 * k, 12 * k, 3);
|
|
1133
|
+
const base = noise(16 * k, 16 * k, 3, 7);
|
|
1134
|
+
for (let y = 0; y < n; y++)
|
|
1135
|
+
for (let x = 0; x < n; x++) {
|
|
1136
|
+
const g = hash2(x, y, salt ^ 85);
|
|
1137
|
+
out[y * n + x] = clamp01((fibres.at(x, y) - 0.5) * 1.5 + (base.at(x, y) - 0.5) * 0.7 + 0.55 + (g < 0.1 ? -0.3 : 0));
|
|
1138
|
+
}
|
|
1139
|
+
break;
|
|
1140
|
+
}
|
|
1141
|
+
case "sanded": {
|
|
1142
|
+
const grit = noise(96 * k, 96 * k, 2);
|
|
1143
|
+
for (let y = 0; y < n; y++)
|
|
1144
|
+
for (let x = 0; x < n; x++) {
|
|
1145
|
+
const h = hash2(x, y, salt);
|
|
1146
|
+
out[y * n + x] = clamp01((grit.at(x, y) - 0.5) * 2.4 + 0.5 + (h - 0.5) * 0.7);
|
|
1147
|
+
}
|
|
1148
|
+
break;
|
|
1149
|
+
}
|
|
1150
|
+
case "canvas":
|
|
1151
|
+
case "linen": {
|
|
1152
|
+
const period = (pattern === "canvas" ? 8 : 5) * k;
|
|
1153
|
+
const threads = Math.max(2, 2 * Math.round(n / period / 2));
|
|
1154
|
+
const p = n / threads;
|
|
1155
|
+
const slub = noise(threads, threads, 2, 11);
|
|
1156
|
+
for (let y = 0; y < n; y++)
|
|
1157
|
+
for (let x = 0; x < n; x++) {
|
|
1158
|
+
const fx = (x + 0.5) / p;
|
|
1159
|
+
const fy = (y + 0.5) / p;
|
|
1160
|
+
const cx = Math.floor(fx);
|
|
1161
|
+
const cy = Math.floor(fy);
|
|
1162
|
+
const warp = Math.sin(Math.PI * (fx - cx));
|
|
1163
|
+
const weft = Math.sin(Math.PI * (fy - cy));
|
|
1164
|
+
const top = (cx + cy) % 2 === 0 ? warp : weft;
|
|
1165
|
+
const irregular = pattern === "linen" ? (slub.at(x, y) - 0.5) * 0.5 : 0;
|
|
1166
|
+
out[y * n + x] = clamp01(0.2 + 0.7 * top + irregular + (hash2(x, y, salt) - 0.5) * 0.15);
|
|
1167
|
+
}
|
|
1168
|
+
break;
|
|
1169
|
+
}
|
|
1170
|
+
case "gesso": {
|
|
1171
|
+
const streaks = noise(2 * k, 28 * k, 3);
|
|
1172
|
+
const tooth = noise(64 * k, 64 * k, 2, 13);
|
|
1173
|
+
for (let y = 0; y < n; y++)
|
|
1174
|
+
for (let x = 0; x < n; x++) out[y * n + x] = clamp01((streaks.at(x, y) - 0.5) * 1.8 + (tooth.at(x, y) - 0.5) * 0.9 + 0.55);
|
|
1175
|
+
break;
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
return out;
|
|
1179
|
+
}
|
|
1180
|
+
var rawCache = /* @__PURE__ */ new Map();
|
|
1181
|
+
function grainHeights(pattern, seed, size = GRAIN_TILE) {
|
|
1182
|
+
const key = `${pattern}:${seed}:${size}`;
|
|
1183
|
+
let h = rawCache.get(key);
|
|
1184
|
+
if (!h) {
|
|
1185
|
+
h = patternHeights(pattern, size, seed);
|
|
1186
|
+
if (rawCache.size > 32) rawCache.delete(rawCache.keys().next().value);
|
|
1187
|
+
rawCache.set(key, h);
|
|
1188
|
+
}
|
|
1189
|
+
return h;
|
|
1190
|
+
}
|
|
1191
|
+
var PaperGrain = class {
|
|
1192
|
+
size = GRAIN_TILE;
|
|
1193
|
+
heights;
|
|
1194
|
+
scale;
|
|
1195
|
+
mirror;
|
|
1196
|
+
ox;
|
|
1197
|
+
oy;
|
|
1198
|
+
flat;
|
|
1199
|
+
constructor(paper, media = "dry") {
|
|
1200
|
+
const raw = grainHeights(paper.pattern, paper.seed);
|
|
1201
|
+
const t = paper[media];
|
|
1202
|
+
this.flat = paper.pattern === "smooth";
|
|
1203
|
+
if (t.contrast === 1 && !t.invert) this.heights = raw;
|
|
1204
|
+
else {
|
|
1205
|
+
const out = new Float32Array(raw.length);
|
|
1206
|
+
for (let i = 0; i < raw.length; i++) {
|
|
1207
|
+
const v = clamp01((raw[i] - 0.5) * t.contrast + 0.5);
|
|
1208
|
+
out[i] = t.invert ? 1 - v : v;
|
|
1209
|
+
}
|
|
1210
|
+
this.heights = out;
|
|
1211
|
+
}
|
|
1212
|
+
this.scale = paper.scale;
|
|
1213
|
+
this.mirror = paper.tiling === "mirror";
|
|
1214
|
+
this.ox = paper.offset?.x ?? 0;
|
|
1215
|
+
this.oy = paper.offset?.y ?? 0;
|
|
1216
|
+
}
|
|
1217
|
+
/** Tile cell index for a coordinate in grain pixels (mirrored on odd tiles when mirroring). */
|
|
1218
|
+
wrap(v) {
|
|
1219
|
+
const n = this.size;
|
|
1220
|
+
if (!this.mirror) return (v % n + n) % n;
|
|
1221
|
+
const p = (v % (2 * n) + 2 * n) % (2 * n);
|
|
1222
|
+
return p < n ? p : 2 * n - 1 - p;
|
|
1223
|
+
}
|
|
1224
|
+
/** Height 0..1 at document position (x, y). */
|
|
1225
|
+
at(x, y) {
|
|
1226
|
+
const u = (x - this.ox) / this.scale - 0.5;
|
|
1227
|
+
const v = (y - this.oy) / this.scale - 0.5;
|
|
1228
|
+
const x0 = Math.floor(u);
|
|
1229
|
+
const y0 = Math.floor(v);
|
|
1230
|
+
const fx = u - x0;
|
|
1231
|
+
const fy = v - y0;
|
|
1232
|
+
const n = this.size;
|
|
1233
|
+
const h = this.heights;
|
|
1234
|
+
const a = this.wrap(x0);
|
|
1235
|
+
const b = this.wrap(x0 + 1);
|
|
1236
|
+
const c = this.wrap(y0) * n;
|
|
1237
|
+
const d = this.wrap(y0 + 1) * n;
|
|
1238
|
+
const top = h[c + a] + (h[c + b] - h[c + a]) * fx;
|
|
1239
|
+
const bot = h[d + a] + (h[d + b] - h[d + a]) * fx;
|
|
1240
|
+
return top + (bot - top) * fy;
|
|
1241
|
+
}
|
|
1242
|
+
};
|
|
1243
|
+
function grainCatch(h, depth, pressure) {
|
|
1244
|
+
if (depth <= 0) return 1;
|
|
1245
|
+
const t = depth * (0.75 - 0.65 * Math.min(1, Math.max(0, pressure)));
|
|
1246
|
+
const u = clamp01((h - t + 0.18) / 0.36);
|
|
1247
|
+
return 1 - depth + depth * u * u * (3 - 2 * u);
|
|
1248
|
+
}
|
|
1249
|
+
function strokeGrainCatch(h, depth, pressure) {
|
|
1250
|
+
if (depth <= 0) return 1;
|
|
1251
|
+
const p = Math.min(1, Math.max(0, pressure));
|
|
1252
|
+
const amount = Math.min(1, depth * (1.4 - 0.6 * p));
|
|
1253
|
+
const u = clamp01((h - 0.2 - 0.25 * (1 - p)) / 0.5);
|
|
1254
|
+
return 1 - amount + amount * u * u * (3 - 2 * u);
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1081
1257
|
// src/paint/exchange.ts
|
|
1082
1258
|
var MIXING_MODELS = ["rgb", "pigment"];
|
|
1083
1259
|
var EMPTY_MIXER_LOAD = { reservoir: null, amount: 0, pickup: null };
|
|
@@ -1741,6 +1917,12 @@ export {
|
|
|
1741
1917
|
applyStrokeToTile,
|
|
1742
1918
|
applyStrokeToDeepTile,
|
|
1743
1919
|
coverageTileCoord,
|
|
1920
|
+
GRAIN_PATTERNS,
|
|
1921
|
+
GRAIN_TILE,
|
|
1922
|
+
grainHeights,
|
|
1923
|
+
PaperGrain,
|
|
1924
|
+
grainCatch,
|
|
1925
|
+
strokeGrainCatch,
|
|
1744
1926
|
MIXING_MODELS,
|
|
1745
1927
|
EMPTY_MIXER_LOAD,
|
|
1746
1928
|
MIXER_PICKUP_RATE,
|