@pixerate/editor 0.248.0 → 0.250.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 +118 -114
- package/dist/animation-editor/index.js +11 -7
- package/dist/{brushstrokeRender-QLCXROJK.js → brushstrokeRender-2FHFLSEG.js} +8 -4
- package/dist/{brushstrokeRender-DTDPFBLC.cjs → brushstrokeRender-QGRXOKDA.cjs} +15 -11
- package/dist/canvas/index.cjs +71 -15
- package/dist/canvas/index.d.cts +1 -0
- package/dist/canvas/index.d.ts +1 -0
- package/dist/canvas/index.js +58 -2
- package/dist/canvas/stickers.d.cts +35 -0
- package/dist/canvas/stickers.d.ts +35 -0
- package/dist/{chunk-RXZL4NG5.js → chunk-226QDRO3.js} +1 -1
- package/dist/{chunk-SC2RZ5EF.js → chunk-2VJAVXLI.js} +2 -2
- 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-ZFSLEOSQ.js → chunk-3TWOCSCY.js} +11 -9
- package/dist/chunk-4D6KP5BV.js +92 -0
- package/dist/chunk-4JNWA3VT.cjs +302 -0
- package/dist/{chunk-L3JFOTBQ.js → chunk-5E2Q7ZHI.js} +1 -1
- package/dist/{chunk-2ONK3ERD.cjs → chunk-75K3W4D6.cjs} +20 -20
- package/dist/{chunk-AU6MWQKZ.js → chunk-ABL7IWFZ.js} +1 -1
- package/dist/chunk-ATK6ABN3.cjs +303 -0
- package/dist/{chunk-7T7JWTVE.cjs → chunk-BOHDJJ2O.cjs} +8 -8
- package/dist/{chunk-2PBZBRP5.js → chunk-D5KGAO4Z.js} +10 -92
- package/dist/{chunk-HB4ICNNA.cjs → chunk-DPYAO5U6.cjs} +42 -42
- package/dist/{chunk-6G6ZDDDB.cjs → chunk-GT77U7QG.cjs} +303 -149
- package/dist/{chunk-PQ3H2AAN.cjs → chunk-I7NJPHWV.cjs} +122 -204
- package/dist/{chunk-42TWUPNJ.js → chunk-IRSTHLQQ.js} +1 -320
- package/dist/{chunk-GHCSC2WP.cjs → chunk-ISIO63Q5.cjs} +21 -15
- package/dist/{chunk-OFH6Q67U.js → chunk-JA57JIT5.js} +9 -3
- package/dist/{chunk-VMROIWLL.cjs → chunk-KBYB7OWB.cjs} +3 -3
- package/dist/{chunk-Q2HA52V4.js → chunk-KDLBJ6QR.js} +2 -2
- package/dist/{chunk-WVS5KQDH.cjs → chunk-M2VKFE5L.cjs} +246 -244
- package/dist/{chunk-5GLYUSNT.js → chunk-NOHJP5TK.js} +1 -1
- package/dist/{chunk-XNRBMYNB.js → chunk-NTRAVM2I.js} +1 -1
- package/dist/{chunk-VNBUDVD4.js → chunk-OTEPAQJX.js} +228 -74
- package/dist/chunk-OTTT5N3K.js +322 -0
- package/dist/{chunk-QOBCBGGI.cjs → chunk-QKXO6JPP.cjs} +14 -14
- package/dist/{chunk-NZ3O3A5C.js → chunk-SMSGP2HQ.js} +1 -1
- package/dist/chunk-SZTI6EER.js +13 -0
- package/dist/chunk-U4NUOKBT.js +303 -0
- package/dist/chunk-U67EN7GG.cjs +13 -0
- package/dist/chunk-W5M3J7PV.cjs +322 -0
- package/dist/{chunk-4P6H35HU.js → chunk-WA44NKPF.js} +2 -2
- package/dist/chunk-WKH5ZAUA.js +302 -0
- package/dist/{chunk-L6REDLNB.cjs → chunk-WPUXGDH4.cjs} +7 -7
- package/dist/{chunk-P3NIPIKS.js → chunk-WQCNC4DK.js} +1 -1
- package/dist/{chunk-IBDU6EGZ.cjs → chunk-X7WRL5ZZ.cjs} +35 -35
- package/dist/{chunk-XWTRATIM.cjs → chunk-YM6ZBTXG.cjs} +23 -23
- package/dist/{chunk-TPWB4Y6L.cjs → chunk-YW43M56C.cjs} +1 -1
- package/dist/{chunk-K5DS2JTA.cjs → chunk-Z3BRH4JK.cjs} +6 -6
- package/dist/{chunk-XNZFVYC2.cjs → chunk-ZBCT5MEA.cjs} +7 -7
- package/dist/effects/helpers.d.cts +6 -0
- package/dist/effects/helpers.d.ts +6 -0
- package/dist/effects/index.cjs +62 -60
- package/dist/effects/index.js +5 -3
- package/dist/effects/tools.d.cts +6 -0
- package/dist/effects/tools.d.ts +6 -0
- package/dist/image-editor/effects.d.cts +1 -1
- package/dist/image-editor/effects.d.ts +1 -1
- package/dist/image-editor/index.cjs +1097 -1069
- package/dist/image-editor/index.d.cts +1 -0
- package/dist/image-editor/index.d.ts +1 -0
- package/dist/image-editor/index.js +58 -30
- package/dist/image-editor/stickers.d.cts +9 -0
- package/dist/image-editor/stickers.d.ts +9 -0
- package/dist/paint/index.cjs +8 -5
- package/dist/paint/index.js +13 -10
- package/dist/paint-editor/controller.d.cts +37 -1
- package/dist/paint-editor/controller.d.ts +37 -1
- package/dist/paint-editor/index.cjs +753 -609
- package/dist/paint-editor/index.d.cts +3 -0
- package/dist/paint-editor/index.d.ts +3 -0
- package/dist/paint-editor/index.js +187 -43
- 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/ui.d.cts +10 -2
- package/dist/paint-editor/ui.d.ts +10 -2
- package/dist/raster/index.cjs +6 -4
- package/dist/raster/index.js +12 -10
- 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 +337 -0
- package/dist/stickers/index.d.cts +16 -0
- package/dist/stickers/index.d.ts +16 -0
- package/dist/stickers/index.js +337 -0
- package/dist/stickers/stamps.d.cts +13 -0
- package/dist/stickers/stamps.d.ts +13 -0
- package/dist/stickers/tools.d.cts +81 -0
- package/dist/stickers/tools.d.ts +81 -0
- package/dist/stickers/types.d.cts +123 -0
- package/dist/stickers/types.d.ts +123 -0
- package/dist/vector/index.cjs +1018 -981
- package/dist/vector/index.d.cts +1 -0
- package/dist/vector/index.d.ts +1 -0
- package/dist/vector/index.js +44 -7
- package/dist/vector/stickers.d.cts +11 -0
- package/dist/vector/stickers.d.ts +11 -0
- package/dist/video-editor/index.cjs +344 -344
- package/dist/video-editor/index.js +4 -4
- package/package.json +11 -1
- package/skills/README.md +1 -0
- package/skills/pixerate-image-editor/SKILL.md +1 -1
- package/skills/pixerate-paint-editor/SKILL.md +8 -5
- package/skills/pixerate-stickers/SKILL.md +57 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stickers on the canvas: `insert_sticker` (see `@pixerate/editor/stickers`) adds a shape node
|
|
3
|
+
* whose path is the sticker's outline (`silhouette`), filled in its colour (the tint, or its
|
|
4
|
+
* dominant colour), so it resizes, recolours and combines like any shape. The canvas has no image
|
|
5
|
+
* nodes, so multi-colour art is reduced to its outline in one colour; `data.sticker` keeps the ref
|
|
6
|
+
* and licence.
|
|
7
|
+
*/
|
|
8
|
+
import type { Command } from '../history/types.js';
|
|
9
|
+
import type { StickerLicence, StickerRef } from '../stickers/types.js';
|
|
10
|
+
import type { StickerInsertHost, StickerPlacement } from '../stickers/tools.js';
|
|
11
|
+
import type { CanvasNode } from './types.js';
|
|
12
|
+
/** What a sticker node remembers: where it came from. */
|
|
13
|
+
export interface CanvasStickerData {
|
|
14
|
+
ref: StickerRef;
|
|
15
|
+
licence: StickerLicence;
|
|
16
|
+
}
|
|
17
|
+
export interface CanvasStickerHostOptions<TNode extends CanvasNode = CanvasNode> {
|
|
18
|
+
getNodes: () => TNode[];
|
|
19
|
+
setNodes: (nodes: TNode[]) => void;
|
|
20
|
+
/** When set, every insertion is one undoable command. */
|
|
21
|
+
history?: {
|
|
22
|
+
execute(command: Command): void;
|
|
23
|
+
};
|
|
24
|
+
/** New node ids (default `sticker-<n>`, skipping ids in use). */
|
|
25
|
+
createId?: () => string;
|
|
26
|
+
/** The default centre (default the middle of the nodes' bounds, or 0, 0). */
|
|
27
|
+
defaultCentre?: () => {
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** The shape node for a placed sticker (top-left at its box), or a refusal naming what is missing. */
|
|
33
|
+
export declare function stickerCanvasNode(placement: StickerPlacement, id: string): CanvasNode;
|
|
34
|
+
/** `insert_sticker` for a canvas: a shape node from the sticker's outline, one undo step. */
|
|
35
|
+
export declare function createCanvasStickerHost<TNode extends CanvasNode = CanvasNode>(options: CanvasStickerHostOptions<TNode>): StickerInsertHost;
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
defaultEffectGradient,
|
|
6
6
|
hasActiveEffects,
|
|
7
7
|
layerEffectLabel
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-3PPJRMIG.js";
|
|
9
9
|
import {
|
|
10
10
|
BLEND_MODES
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-IRSTHLQQ.js";
|
|
12
12
|
|
|
13
13
|
// src/raster/effects/ui.ts
|
|
14
14
|
function layerEffectsPanel(layer) {
|
|
@@ -7,10 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
var _chunk474IQG74cjs = require('./chunk-474IQG74.cjs');
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
var _chunkXFM3OCHUcjs = require('./chunk-XFM3OCHU.cjs');
|
|
13
|
-
|
|
14
10
|
// src/raster/pigment.ts
|
|
15
11
|
var PIGMENT_BANDS = 36;
|
|
16
12
|
var PIGMENT_LAMBDA_MIN = 380;
|
|
@@ -990,321 +986,6 @@ function keepDeepSamples(before, after) {
|
|
|
990
986
|
return tiles ? new (0, _chunk474IQG74cjs.TiledSurface)(ch, tiles, after.defaultValue) : after;
|
|
991
987
|
}
|
|
992
988
|
|
|
993
|
-
// src/raster/png.ts
|
|
994
|
-
var SIGNATURE = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
995
|
-
var crcTable = null;
|
|
996
|
-
function crc32(bytes, start, end) {
|
|
997
|
-
if (!crcTable) {
|
|
998
|
-
crcTable = new Uint32Array(256);
|
|
999
|
-
for (let n = 0; n < 256; n++) {
|
|
1000
|
-
let c2 = n;
|
|
1001
|
-
for (let k = 0; k < 8; k++) c2 = c2 & 1 ? 3988292384 ^ c2 >>> 1 : c2 >>> 1;
|
|
1002
|
-
crcTable[n] = c2 >>> 0;
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
let c = 4294967295;
|
|
1006
|
-
for (let i = start; i < end; i++) c = crcTable[(c ^ bytes[i]) & 255] ^ c >>> 8;
|
|
1007
|
-
return (c ^ 4294967295) >>> 0;
|
|
1008
|
-
}
|
|
1009
|
-
function paeth(a, b, c) {
|
|
1010
|
-
const p = a + b - c;
|
|
1011
|
-
const pa = Math.abs(p - a);
|
|
1012
|
-
const pb = Math.abs(p - b);
|
|
1013
|
-
const pc = Math.abs(p - c);
|
|
1014
|
-
return pa <= pb && pa <= pc ? a : pb <= pc ? b : c;
|
|
1015
|
-
}
|
|
1016
|
-
function encodePng(width, height, data, channels = 4) {
|
|
1017
|
-
const stride = width * channels;
|
|
1018
|
-
const raw = new Uint8Array((stride + 1) * height);
|
|
1019
|
-
const bpp = channels;
|
|
1020
|
-
const cand = [new Uint8Array(stride), new Uint8Array(stride), new Uint8Array(stride), new Uint8Array(stride), new Uint8Array(stride)];
|
|
1021
|
-
for (let y = 0; y < height; y++) {
|
|
1022
|
-
const row = y * stride;
|
|
1023
|
-
const prevRow = (y - 1) * stride;
|
|
1024
|
-
let best = 0;
|
|
1025
|
-
let bestScore = Infinity;
|
|
1026
|
-
for (let f = 0; f < 5; f++) {
|
|
1027
|
-
const out2 = cand[f];
|
|
1028
|
-
let score = 0;
|
|
1029
|
-
for (let x = 0; x < stride; x++) {
|
|
1030
|
-
const v = data[row + x];
|
|
1031
|
-
const a = x >= bpp ? data[row + x - bpp] : 0;
|
|
1032
|
-
const b = y > 0 ? data[prevRow + x] : 0;
|
|
1033
|
-
const c = x >= bpp && y > 0 ? data[prevRow + x - bpp] : 0;
|
|
1034
|
-
let r;
|
|
1035
|
-
switch (f) {
|
|
1036
|
-
case 0:
|
|
1037
|
-
r = v;
|
|
1038
|
-
break;
|
|
1039
|
-
case 1:
|
|
1040
|
-
r = v - a;
|
|
1041
|
-
break;
|
|
1042
|
-
case 2:
|
|
1043
|
-
r = v - b;
|
|
1044
|
-
break;
|
|
1045
|
-
case 3:
|
|
1046
|
-
r = v - (a + b >> 1);
|
|
1047
|
-
break;
|
|
1048
|
-
default:
|
|
1049
|
-
r = v - paeth(a, b, c);
|
|
1050
|
-
}
|
|
1051
|
-
r &= 255;
|
|
1052
|
-
out2[x] = r;
|
|
1053
|
-
score += r < 128 ? r : 256 - r;
|
|
1054
|
-
if (score >= bestScore) break;
|
|
1055
|
-
}
|
|
1056
|
-
if (score < bestScore) {
|
|
1057
|
-
bestScore = score;
|
|
1058
|
-
best = f;
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
const o = y * (stride + 1);
|
|
1062
|
-
raw[o] = best;
|
|
1063
|
-
raw.set(cand[best], o + 1);
|
|
1064
|
-
}
|
|
1065
|
-
const idat = _chunkXFM3OCHUcjs.deflate.call(void 0, raw);
|
|
1066
|
-
const chunks = [];
|
|
1067
|
-
const ihdr = new Uint8Array(13);
|
|
1068
|
-
writeU32(ihdr, 0, width);
|
|
1069
|
-
writeU32(ihdr, 4, height);
|
|
1070
|
-
ihdr[8] = 8;
|
|
1071
|
-
ihdr[9] = channels === 1 ? 0 : 6;
|
|
1072
|
-
chunks.push(["IHDR", ihdr], ["IDAT", idat], ["IEND", new Uint8Array(0)]);
|
|
1073
|
-
let size = 8;
|
|
1074
|
-
for (const [, d] of chunks) size += 12 + d.length;
|
|
1075
|
-
const out = new Uint8Array(size);
|
|
1076
|
-
out.set(SIGNATURE, 0);
|
|
1077
|
-
let p = 8;
|
|
1078
|
-
for (const [type, d] of chunks) {
|
|
1079
|
-
writeU32(out, p, d.length);
|
|
1080
|
-
for (let i = 0; i < 4; i++) out[p + 4 + i] = type.charCodeAt(i);
|
|
1081
|
-
out.set(d, p + 8);
|
|
1082
|
-
writeU32(out, p + 8 + d.length, crc32(out, p + 4, p + 8 + d.length));
|
|
1083
|
-
p += 12 + d.length;
|
|
1084
|
-
}
|
|
1085
|
-
return out;
|
|
1086
|
-
}
|
|
1087
|
-
function writeU32(b, o, v) {
|
|
1088
|
-
b[o] = v >>> 24;
|
|
1089
|
-
b[o + 1] = v >>> 16 & 255;
|
|
1090
|
-
b[o + 2] = v >>> 8 & 255;
|
|
1091
|
-
b[o + 3] = v & 255;
|
|
1092
|
-
}
|
|
1093
|
-
function readU32(b, o) {
|
|
1094
|
-
return (b[o] << 24 | b[o + 1] << 16 | b[o + 2] << 8 | b[o + 3]) >>> 0;
|
|
1095
|
-
}
|
|
1096
|
-
function isPng(bytes) {
|
|
1097
|
-
return bytes.length > 8 && SIGNATURE.every((v, i) => bytes[i] === v);
|
|
1098
|
-
}
|
|
1099
|
-
function decodePng(bytes, options = {}) {
|
|
1100
|
-
if (!isPng(bytes)) throw new Error("Not a PNG image.");
|
|
1101
|
-
let p = 8;
|
|
1102
|
-
let width = 0;
|
|
1103
|
-
let height = 0;
|
|
1104
|
-
let depth = 0;
|
|
1105
|
-
let type = 0;
|
|
1106
|
-
let interlace = 0;
|
|
1107
|
-
let palette = null;
|
|
1108
|
-
let trns = null;
|
|
1109
|
-
const idat = [];
|
|
1110
|
-
while (p + 8 <= bytes.length) {
|
|
1111
|
-
const len = readU32(bytes, p);
|
|
1112
|
-
const t = String.fromCharCode(bytes[p + 4], bytes[p + 5], bytes[p + 6], bytes[p + 7]);
|
|
1113
|
-
const body = bytes.subarray(p + 8, p + 8 + len);
|
|
1114
|
-
if (p + 12 + len > bytes.length) throw new Error("Truncated PNG.");
|
|
1115
|
-
if (t === "IHDR") {
|
|
1116
|
-
width = readU32(body, 0);
|
|
1117
|
-
height = readU32(body, 4);
|
|
1118
|
-
depth = body[8];
|
|
1119
|
-
type = body[9];
|
|
1120
|
-
interlace = body[12];
|
|
1121
|
-
} else if (t === "PLTE") palette = body;
|
|
1122
|
-
else if (t === "tRNS") trns = body;
|
|
1123
|
-
else if (t === "IDAT") idat.push(body);
|
|
1124
|
-
else if (t === "IEND") break;
|
|
1125
|
-
p += 12 + len;
|
|
1126
|
-
}
|
|
1127
|
-
if (!width || !height) throw new Error("PNG has no image header.");
|
|
1128
|
-
if (interlace) throw new Error("Interlaced PNGs are not supported here; decode them with a canvas.");
|
|
1129
|
-
const maxPixels = _nullishCoalesce(options.maxPixels, () => ( 1 << 28));
|
|
1130
|
-
if (width * height > maxPixels) throw new Error(`PNG is too large (${width}\xD7${height}).`);
|
|
1131
|
-
const samples = type === 0 ? 1 : type === 2 ? 3 : type === 3 ? 1 : type === 4 ? 2 : type === 6 ? 4 : 0;
|
|
1132
|
-
if (!samples || ![1, 2, 4, 8, 16].includes(depth)) throw new Error(`Unsupported PNG format (type ${type}, depth ${depth}).`);
|
|
1133
|
-
let total = 0;
|
|
1134
|
-
for (const c of idat) total += c.length;
|
|
1135
|
-
const z = new Uint8Array(total);
|
|
1136
|
-
let o = 0;
|
|
1137
|
-
for (const c of idat) {
|
|
1138
|
-
z.set(c, o);
|
|
1139
|
-
o += c.length;
|
|
1140
|
-
}
|
|
1141
|
-
const bitsPerPixel = samples * depth;
|
|
1142
|
-
const stride = Math.ceil(width * bitsPerPixel / 8);
|
|
1143
|
-
const raw = _chunkXFM3OCHUcjs.inflate.call(void 0, z, { maxOutput: (stride + 1) * height, sizeHint: (stride + 1) * height });
|
|
1144
|
-
if (raw.length < (stride + 1) * height) throw new Error("PNG image data is truncated.");
|
|
1145
|
-
const bpp = Math.max(1, bitsPerPixel >> 3);
|
|
1146
|
-
const lines = new Uint8Array(stride * height);
|
|
1147
|
-
for (let y = 0; y < height; y++) {
|
|
1148
|
-
const f = raw[y * (stride + 1)];
|
|
1149
|
-
const src = y * (stride + 1) + 1;
|
|
1150
|
-
const dst = y * stride;
|
|
1151
|
-
const up = dst - stride;
|
|
1152
|
-
for (let x = 0; x < stride; x++) {
|
|
1153
|
-
const v = raw[src + x];
|
|
1154
|
-
const a = x >= bpp ? lines[dst + x - bpp] : 0;
|
|
1155
|
-
const b = y > 0 ? lines[up + x] : 0;
|
|
1156
|
-
const c = x >= bpp && y > 0 ? lines[up + x - bpp] : 0;
|
|
1157
|
-
let r;
|
|
1158
|
-
switch (f) {
|
|
1159
|
-
case 0:
|
|
1160
|
-
r = v;
|
|
1161
|
-
break;
|
|
1162
|
-
case 1:
|
|
1163
|
-
r = v + a;
|
|
1164
|
-
break;
|
|
1165
|
-
case 2:
|
|
1166
|
-
r = v + b;
|
|
1167
|
-
break;
|
|
1168
|
-
case 3:
|
|
1169
|
-
r = v + (a + b >> 1);
|
|
1170
|
-
break;
|
|
1171
|
-
case 4:
|
|
1172
|
-
r = v + paeth(a, b, c);
|
|
1173
|
-
break;
|
|
1174
|
-
default:
|
|
1175
|
-
throw new Error(`Invalid PNG filter ${f}.`);
|
|
1176
|
-
}
|
|
1177
|
-
lines[dst + x] = r & 255;
|
|
1178
|
-
}
|
|
1179
|
-
}
|
|
1180
|
-
const sample = (y, i) => {
|
|
1181
|
-
const row = y * stride;
|
|
1182
|
-
if (depth === 8) return lines[row + i];
|
|
1183
|
-
if (depth === 16) return lines[row + i * 2];
|
|
1184
|
-
const perByte = 8 / depth;
|
|
1185
|
-
const byte = lines[row + Math.floor(i / perByte)];
|
|
1186
|
-
const shift = 8 - depth * (i % perByte + 1);
|
|
1187
|
-
const v = byte >> shift & (1 << depth) - 1;
|
|
1188
|
-
return type === 3 ? v : Math.round(v * 255 / ((1 << depth) - 1));
|
|
1189
|
-
};
|
|
1190
|
-
const gray = options.keepGray && type === 0 && !trns;
|
|
1191
|
-
const channels = gray ? 1 : 4;
|
|
1192
|
-
const out = new Uint8ClampedArray(width * height * channels);
|
|
1193
|
-
const trnsGray = trns && type === 0 ? depth === 16 ? trns[0] : sample16(trns, 0, depth) : -1;
|
|
1194
|
-
const trnsRgb = trns && type === 2 ? [0, 1, 2].map((k) => depth === 16 ? trns[k * 2] : sample16(trns, k, depth)) : null;
|
|
1195
|
-
for (let y = 0; y < height; y++) {
|
|
1196
|
-
for (let x = 0; x < width; x++) {
|
|
1197
|
-
const d = (y * width + x) * channels;
|
|
1198
|
-
if (type === 0) {
|
|
1199
|
-
const v = sample(y, x);
|
|
1200
|
-
if (gray) out[d] = v;
|
|
1201
|
-
else {
|
|
1202
|
-
out[d] = out[d + 1] = out[d + 2] = v;
|
|
1203
|
-
out[d + 3] = v === trnsGray && trns ? 0 : 255;
|
|
1204
|
-
}
|
|
1205
|
-
} else if (type === 2) {
|
|
1206
|
-
const r = sample(y, x * 3);
|
|
1207
|
-
const g = sample(y, x * 3 + 1);
|
|
1208
|
-
const b = sample(y, x * 3 + 2);
|
|
1209
|
-
out[d] = r;
|
|
1210
|
-
out[d + 1] = g;
|
|
1211
|
-
out[d + 2] = b;
|
|
1212
|
-
out[d + 3] = trnsRgb && r === trnsRgb[0] && g === trnsRgb[1] && b === trnsRgb[2] ? 0 : 255;
|
|
1213
|
-
} else if (type === 3) {
|
|
1214
|
-
const i = sample(y, x);
|
|
1215
|
-
if (!palette || i * 3 + 2 >= palette.length) throw new Error("PNG palette index out of range.");
|
|
1216
|
-
out[d] = palette[i * 3];
|
|
1217
|
-
out[d + 1] = palette[i * 3 + 1];
|
|
1218
|
-
out[d + 2] = palette[i * 3 + 2];
|
|
1219
|
-
out[d + 3] = trns && i < trns.length ? trns[i] : 255;
|
|
1220
|
-
} else if (type === 4) {
|
|
1221
|
-
const v = sample(y, x * 2);
|
|
1222
|
-
out[d] = out[d + 1] = out[d + 2] = v;
|
|
1223
|
-
out[d + 3] = sample(y, x * 2 + 1);
|
|
1224
|
-
} else {
|
|
1225
|
-
out[d] = sample(y, x * 4);
|
|
1226
|
-
out[d + 1] = sample(y, x * 4 + 1);
|
|
1227
|
-
out[d + 2] = sample(y, x * 4 + 2);
|
|
1228
|
-
out[d + 3] = sample(y, x * 4 + 3);
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
return { width, height, channels, data: out };
|
|
1233
|
-
}
|
|
1234
|
-
function sample16(trns, k, depth) {
|
|
1235
|
-
const v = trns[k * 2] << 8 | trns[k * 2 + 1];
|
|
1236
|
-
if (depth === 8) return v & 255;
|
|
1237
|
-
return Math.round((v & (1 << depth) - 1) * 255 / ((1 << depth) - 1));
|
|
1238
|
-
}
|
|
1239
|
-
var B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1240
|
-
var B64_INV = null;
|
|
1241
|
-
function bytesToBase64(bytes) {
|
|
1242
|
-
const parts = [];
|
|
1243
|
-
const CHUNK = 3 * 4096;
|
|
1244
|
-
for (let start = 0; start < bytes.length; start += CHUNK) {
|
|
1245
|
-
const end = Math.min(bytes.length, start + CHUNK);
|
|
1246
|
-
let s = "";
|
|
1247
|
-
let i = start;
|
|
1248
|
-
for (; i + 2 < end; i += 3) {
|
|
1249
|
-
const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
|
|
1250
|
-
s += B64[n >> 18] + B64[n >> 12 & 63] + B64[n >> 6 & 63] + B64[n & 63];
|
|
1251
|
-
}
|
|
1252
|
-
if (i < end) {
|
|
1253
|
-
const n = bytes[i] << 16 | (i + 1 < end ? bytes[i + 1] << 8 : 0);
|
|
1254
|
-
s += B64[n >> 18] + B64[n >> 12 & 63] + (i + 1 < end ? B64[n >> 6 & 63] : "=") + "=";
|
|
1255
|
-
}
|
|
1256
|
-
parts.push(s);
|
|
1257
|
-
}
|
|
1258
|
-
return parts.join("");
|
|
1259
|
-
}
|
|
1260
|
-
function base64ToBytes(text) {
|
|
1261
|
-
if (!B64_INV) {
|
|
1262
|
-
B64_INV = new Int16Array(128).fill(-1);
|
|
1263
|
-
for (let i = 0; i < 64; i++) B64_INV[B64.charCodeAt(i)] = i;
|
|
1264
|
-
B64_INV["-".charCodeAt(0)] = 62;
|
|
1265
|
-
B64_INV["_".charCodeAt(0)] = 63;
|
|
1266
|
-
}
|
|
1267
|
-
const inv = B64_INV;
|
|
1268
|
-
const clean = text.replace(/[\s=]/g, "");
|
|
1269
|
-
const out = new Uint8Array(Math.floor(clean.length * 3 / 4));
|
|
1270
|
-
let bits = 0;
|
|
1271
|
-
let acc = 0;
|
|
1272
|
-
let o = 0;
|
|
1273
|
-
for (let i = 0; i < clean.length; i++) {
|
|
1274
|
-
const c = clean.charCodeAt(i);
|
|
1275
|
-
const v = c < 128 ? inv[c] : -1;
|
|
1276
|
-
if (v < 0) throw new Error("Invalid base64 data.");
|
|
1277
|
-
acc = acc << 6 | v;
|
|
1278
|
-
bits += 6;
|
|
1279
|
-
if (bits >= 8) {
|
|
1280
|
-
bits -= 8;
|
|
1281
|
-
out[o++] = acc >> bits & 255;
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
return out.subarray(0, o);
|
|
1285
|
-
}
|
|
1286
|
-
function parseDataUrl(url) {
|
|
1287
|
-
const m = /^data:([^;,]*)((?:;[^;,]*)*?),/i.exec(url);
|
|
1288
|
-
if (!m) return null;
|
|
1289
|
-
const body = url.slice(m[0].length);
|
|
1290
|
-
const isBase64 = /;base64/i.test(m[2]);
|
|
1291
|
-
if (isBase64) return { mime: m[1] || "text/plain", bytes: base64ToBytes(body) };
|
|
1292
|
-
const text = decodeURIComponent(body);
|
|
1293
|
-
const bytes = new Uint8Array(text.length);
|
|
1294
|
-
for (let i = 0; i < text.length; i++) bytes[i] = text.charCodeAt(i) & 255;
|
|
1295
|
-
return { mime: m[1] || "text/plain", bytes };
|
|
1296
|
-
}
|
|
1297
|
-
function pngDataUrl(width, height, data, channels = 4) {
|
|
1298
|
-
return `data:image/png;base64,${bytesToBase64(encodePng(width, height, data, channels))}`;
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
989
|
|
|
1309
990
|
|
|
1310
991
|
|
|
@@ -1358,4 +1039,4 @@ function pngDataUrl(width, height, data, channels = 4) {
|
|
|
1358
1039
|
|
|
1359
1040
|
|
|
1360
1041
|
|
|
1361
|
-
exports.PIGMENT_BANDS = PIGMENT_BANDS; exports.PIGMENT_LAMBDA_MIN = PIGMENT_LAMBDA_MIN; exports.PIGMENT_LAMBDA_STEP = PIGMENT_LAMBDA_STEP; exports.PIGMENT_WAVELENGTHS = PIGMENT_WAVELENGTHS; exports.rgbToReflectance = rgbToReflectance; exports.reflectanceToRgb = reflectanceToRgb; exports.createPigment = createPigment; exports.setPigmentColor = setPigmentColor; exports.mixPigments = mixPigments; exports.lerpPigment = lerpPigment; exports.lerpPigmentInto = lerpPigmentInto; exports.BLEND_MODES = BLEND_MODES; exports.isBlendMode = isBlendMode; exports.PAINTERLY_BLEND_MODES = PAINTERLY_BLEND_MODES; exports.isPainterlyBlendMode = isPainterlyBlendMode; exports.standardBlendMode = standardBlendMode; exports.normalizeBlendMode = normalizeBlendMode; exports.canvasCompositeOperation = canvasCompositeOperation; exports.isSeparableBlendMode = isSeparableBlendMode; exports.blendChannel = blendChannel; exports.blendLum = blendLum; exports.setLum = setLum; exports.blendRgb = blendRgb; exports.SHADOW_AMBIENT = SHADOW_AMBIENT; exports.mixPigmentRgb = mixPigmentRgb; exports.pigment8 = pigment8; exports.mixPigment8 = mixPigment8; exports.blendPixel = blendPixel; exports.blendImageData = blendImageData; exports.BIT_DEPTHS = BIT_DEPTHS; exports.isBitDepth = isBitDepth; exports.srgbDecode = srgbDecode; exports.srgbEncode = srgbEncode; exports.to16From8 = to16From8; exports.to32From8 = to32From8; exports.to32From16 = to32From16; exports.to16From32 = to16From32; exports.to8From16 = to8From16; exports.to8From32 = to8From32; exports.proxyOf = proxyOf; exports.depthOf = depthOf; exports.deepTile = deepTile; exports.tileSamples16 = tileSamples16; exports.tileSamples32 = tileSamples32; exports.tileSamples = tileSamples; exports.surfaceDepth = surfaceDepth; exports.readDeepRegion = readDeepRegion; exports.writeDeepRegion = writeDeepRegion; exports.surfaceFromDeepPixels = surfaceFromDeepPixels; exports.convertSurfaceDepth = convertSurfaceDepth; exports.deepBytes = deepBytes; exports.keepDeepSamples = keepDeepSamples;
|
|
1042
|
+
exports.PIGMENT_BANDS = PIGMENT_BANDS; exports.PIGMENT_LAMBDA_MIN = PIGMENT_LAMBDA_MIN; exports.PIGMENT_LAMBDA_STEP = PIGMENT_LAMBDA_STEP; exports.PIGMENT_WAVELENGTHS = PIGMENT_WAVELENGTHS; exports.rgbToReflectance = rgbToReflectance; exports.reflectanceToRgb = reflectanceToRgb; exports.createPigment = createPigment; exports.setPigmentColor = setPigmentColor; exports.mixPigments = mixPigments; exports.lerpPigment = lerpPigment; exports.lerpPigmentInto = lerpPigmentInto; exports.BLEND_MODES = BLEND_MODES; exports.isBlendMode = isBlendMode; exports.PAINTERLY_BLEND_MODES = PAINTERLY_BLEND_MODES; exports.isPainterlyBlendMode = isPainterlyBlendMode; exports.standardBlendMode = standardBlendMode; exports.normalizeBlendMode = normalizeBlendMode; exports.canvasCompositeOperation = canvasCompositeOperation; exports.isSeparableBlendMode = isSeparableBlendMode; exports.blendChannel = blendChannel; exports.blendLum = blendLum; exports.setLum = setLum; exports.blendRgb = blendRgb; exports.SHADOW_AMBIENT = SHADOW_AMBIENT; exports.mixPigmentRgb = mixPigmentRgb; exports.pigment8 = pigment8; exports.mixPigment8 = mixPigment8; exports.blendPixel = blendPixel; exports.blendImageData = blendImageData; exports.BIT_DEPTHS = BIT_DEPTHS; exports.isBitDepth = isBitDepth; exports.srgbDecode = srgbDecode; exports.srgbEncode = srgbEncode; exports.to16From8 = to16From8; exports.to32From8 = to32From8; exports.to32From16 = to32From16; exports.to16From32 = to16From32; exports.to8From16 = to8From16; exports.to8From32 = to8From32; exports.proxyOf = proxyOf; exports.depthOf = depthOf; exports.deepTile = deepTile; exports.tileSamples16 = tileSamples16; exports.tileSamples32 = tileSamples32; exports.tileSamples = tileSamples; exports.surfaceDepth = surfaceDepth; exports.readDeepRegion = readDeepRegion; exports.writeDeepRegion = writeDeepRegion; exports.surfaceFromDeepPixels = surfaceFromDeepPixels; exports.convertSurfaceDepth = convertSurfaceDepth; exports.deepBytes = deepBytes; exports.keepDeepSamples = keepDeepSamples;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); var _class;// src/paint/rand.ts
|
|
2
|
+
function mix32(h) {
|
|
3
|
+
h ^= h >>> 16;
|
|
4
|
+
h = Math.imul(h, 2246822507);
|
|
5
|
+
h ^= h >>> 13;
|
|
6
|
+
h = Math.imul(h, 3266489909);
|
|
7
|
+
h ^= h >>> 16;
|
|
8
|
+
return h >>> 0;
|
|
9
|
+
}
|
|
10
|
+
function hash2(x, y, salt) {
|
|
11
|
+
const h = mix32((Math.imul(x | 0, 668265261) ^ mix32((y | 0) + Math.imul(salt | 0, 374761393))) >>> 0);
|
|
12
|
+
return h / 4294967296;
|
|
13
|
+
}
|
|
14
|
+
function rand01(seed, index, stream) {
|
|
15
|
+
return hash2(index, stream, seed);
|
|
16
|
+
}
|
|
17
|
+
function randSigned(seed, index, stream) {
|
|
18
|
+
return rand01(seed, index, stream) * 2 - 1;
|
|
19
|
+
}
|
|
20
|
+
function seedFromString(text) {
|
|
21
|
+
let h = 2166136261;
|
|
22
|
+
for (let i = 0; i < text.length; i++) {
|
|
23
|
+
h ^= text.charCodeAt(i);
|
|
24
|
+
h = Math.imul(h, 16777619);
|
|
25
|
+
}
|
|
26
|
+
return mix32(h >>> 0);
|
|
27
|
+
}
|
|
28
|
+
var smooth = (t) => t * t * (3 - 2 * t);
|
|
29
|
+
var Lattice = class {
|
|
30
|
+
constructor(px, py, salt) {
|
|
31
|
+
this.px = px;
|
|
32
|
+
this.py = py;
|
|
33
|
+
this.values = new Float32Array(px * py);
|
|
34
|
+
for (let j = 0; j < py; j++) for (let i = 0; i < px; i++) this.values[j * px + i] = hash2(i, j, salt);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
/** Value noise at (x, y) in lattice cells; wraps every `px` / `py` cells. */
|
|
40
|
+
at(x, y) {
|
|
41
|
+
const { px, py } = this;
|
|
42
|
+
const x0 = Math.floor(x);
|
|
43
|
+
const y0 = Math.floor(y);
|
|
44
|
+
const tx = smooth(x - x0);
|
|
45
|
+
const ty = smooth(y - y0);
|
|
46
|
+
const i0 = (x0 % px + px) % px;
|
|
47
|
+
const j0 = (y0 % py + py) % py;
|
|
48
|
+
const i1 = (i0 + 1) % px;
|
|
49
|
+
const j1 = (j0 + 1) % py;
|
|
50
|
+
const v = this.values;
|
|
51
|
+
const a = v[j0 * px + i0] + (v[j0 * px + i1] - v[j0 * px + i0]) * tx;
|
|
52
|
+
const b = v[j1 * px + i0] + (v[j1 * px + i1] - v[j1 * px + i0]) * tx;
|
|
53
|
+
return a + (b - a) * ty;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var TileableNoise = (_class = class {
|
|
57
|
+
constructor(size, cellsX, cellsY, octaves, salt) {;_class.prototype.__init.call(this);
|
|
58
|
+
this.size = size;
|
|
59
|
+
let cx = Math.max(1, Math.round(cellsX));
|
|
60
|
+
let cy = Math.max(1, Math.round(cellsY));
|
|
61
|
+
for (let o = 0; o < octaves; o++) {
|
|
62
|
+
this.octaves.push(new Lattice(cx, cy, salt + o * 7919 | 0));
|
|
63
|
+
cx *= 2;
|
|
64
|
+
cy *= 2;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
__init() {this.octaves = []}
|
|
69
|
+
/** Fractal noise at pixel (x, y). */
|
|
70
|
+
at(x, y) {
|
|
71
|
+
let sum = 0;
|
|
72
|
+
let amp = 1;
|
|
73
|
+
let norm = 0;
|
|
74
|
+
const u = x / this.size;
|
|
75
|
+
const v = y / this.size;
|
|
76
|
+
for (const l of this.octaves) {
|
|
77
|
+
sum += l.at(u * l.px, v * l.py) * amp;
|
|
78
|
+
norm += amp;
|
|
79
|
+
amp *= 0.5;
|
|
80
|
+
}
|
|
81
|
+
return norm > 0 ? sum / norm : 0.5;
|
|
82
|
+
}
|
|
83
|
+
}, _class);
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
exports.mix32 = mix32; exports.hash2 = hash2; exports.rand01 = rand01; exports.randSigned = randSigned; exports.seedFromString = seedFromString; exports.TileableNoise = TileableNoise;
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
validateEffectGradient,
|
|
49
49
|
validateLayerEffects,
|
|
50
50
|
warpSurface
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-3PPJRMIG.js";
|
|
52
52
|
import {
|
|
53
53
|
affineFromHomography,
|
|
54
54
|
applyHomography,
|
|
@@ -106,7 +106,7 @@ import {
|
|
|
106
106
|
transformTextRect,
|
|
107
107
|
translateMatrix,
|
|
108
108
|
warpPresetMesh
|
|
109
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-KDLBJ6QR.js";
|
|
110
110
|
import {
|
|
111
111
|
bezierPathBounds,
|
|
112
112
|
outlineStroke,
|
|
@@ -117,22 +117,24 @@ import {
|
|
|
117
117
|
} from "./chunk-WEIK3UYB.js";
|
|
118
118
|
import {
|
|
119
119
|
BLEND_MODES,
|
|
120
|
-
base64ToBytes,
|
|
121
120
|
blendRgb,
|
|
122
|
-
bytesToBase64,
|
|
123
|
-
decodePng,
|
|
124
|
-
encodePng,
|
|
125
121
|
isBlendMode,
|
|
126
122
|
mixPigmentRgb,
|
|
127
123
|
normalizeBlendMode,
|
|
128
|
-
parseDataUrl,
|
|
129
|
-
pngDataUrl,
|
|
130
124
|
readDeepRegion,
|
|
131
125
|
setLum,
|
|
132
126
|
surfaceDepth,
|
|
133
127
|
surfaceFromDeepPixels,
|
|
134
128
|
writeDeepRegion
|
|
135
|
-
} from "./chunk-
|
|
129
|
+
} from "./chunk-IRSTHLQQ.js";
|
|
130
|
+
import {
|
|
131
|
+
base64ToBytes,
|
|
132
|
+
bytesToBase64,
|
|
133
|
+
decodePng,
|
|
134
|
+
encodePng,
|
|
135
|
+
parseDataUrl,
|
|
136
|
+
pngDataUrl
|
|
137
|
+
} from "./chunk-OTTT5N3K.js";
|
|
136
138
|
import {
|
|
137
139
|
TILE,
|
|
138
140
|
TiledSurface,
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// src/paint/rand.ts
|
|
2
|
+
function mix32(h) {
|
|
3
|
+
h ^= h >>> 16;
|
|
4
|
+
h = Math.imul(h, 2246822507);
|
|
5
|
+
h ^= h >>> 13;
|
|
6
|
+
h = Math.imul(h, 3266489909);
|
|
7
|
+
h ^= h >>> 16;
|
|
8
|
+
return h >>> 0;
|
|
9
|
+
}
|
|
10
|
+
function hash2(x, y, salt) {
|
|
11
|
+
const h = mix32((Math.imul(x | 0, 668265261) ^ mix32((y | 0) + Math.imul(salt | 0, 374761393))) >>> 0);
|
|
12
|
+
return h / 4294967296;
|
|
13
|
+
}
|
|
14
|
+
function rand01(seed, index, stream) {
|
|
15
|
+
return hash2(index, stream, seed);
|
|
16
|
+
}
|
|
17
|
+
function randSigned(seed, index, stream) {
|
|
18
|
+
return rand01(seed, index, stream) * 2 - 1;
|
|
19
|
+
}
|
|
20
|
+
function seedFromString(text) {
|
|
21
|
+
let h = 2166136261;
|
|
22
|
+
for (let i = 0; i < text.length; i++) {
|
|
23
|
+
h ^= text.charCodeAt(i);
|
|
24
|
+
h = Math.imul(h, 16777619);
|
|
25
|
+
}
|
|
26
|
+
return mix32(h >>> 0);
|
|
27
|
+
}
|
|
28
|
+
var smooth = (t) => t * t * (3 - 2 * t);
|
|
29
|
+
var Lattice = class {
|
|
30
|
+
constructor(px, py, salt) {
|
|
31
|
+
this.px = px;
|
|
32
|
+
this.py = py;
|
|
33
|
+
this.values = new Float32Array(px * py);
|
|
34
|
+
for (let j = 0; j < py; j++) for (let i = 0; i < px; i++) this.values[j * px + i] = hash2(i, j, salt);
|
|
35
|
+
}
|
|
36
|
+
px;
|
|
37
|
+
py;
|
|
38
|
+
values;
|
|
39
|
+
/** Value noise at (x, y) in lattice cells; wraps every `px` / `py` cells. */
|
|
40
|
+
at(x, y) {
|
|
41
|
+
const { px, py } = this;
|
|
42
|
+
const x0 = Math.floor(x);
|
|
43
|
+
const y0 = Math.floor(y);
|
|
44
|
+
const tx = smooth(x - x0);
|
|
45
|
+
const ty = smooth(y - y0);
|
|
46
|
+
const i0 = (x0 % px + px) % px;
|
|
47
|
+
const j0 = (y0 % py + py) % py;
|
|
48
|
+
const i1 = (i0 + 1) % px;
|
|
49
|
+
const j1 = (j0 + 1) % py;
|
|
50
|
+
const v = this.values;
|
|
51
|
+
const a = v[j0 * px + i0] + (v[j0 * px + i1] - v[j0 * px + i0]) * tx;
|
|
52
|
+
const b = v[j1 * px + i0] + (v[j1 * px + i1] - v[j1 * px + i0]) * tx;
|
|
53
|
+
return a + (b - a) * ty;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var TileableNoise = class {
|
|
57
|
+
constructor(size, cellsX, cellsY, octaves, salt) {
|
|
58
|
+
this.size = size;
|
|
59
|
+
let cx = Math.max(1, Math.round(cellsX));
|
|
60
|
+
let cy = Math.max(1, Math.round(cellsY));
|
|
61
|
+
for (let o = 0; o < octaves; o++) {
|
|
62
|
+
this.octaves.push(new Lattice(cx, cy, salt + o * 7919 | 0));
|
|
63
|
+
cx *= 2;
|
|
64
|
+
cy *= 2;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
size;
|
|
68
|
+
octaves = [];
|
|
69
|
+
/** Fractal noise at pixel (x, y). */
|
|
70
|
+
at(x, y) {
|
|
71
|
+
let sum = 0;
|
|
72
|
+
let amp = 1;
|
|
73
|
+
let norm = 0;
|
|
74
|
+
const u = x / this.size;
|
|
75
|
+
const v = y / this.size;
|
|
76
|
+
for (const l of this.octaves) {
|
|
77
|
+
sum += l.at(u * l.px, v * l.py) * amp;
|
|
78
|
+
norm += amp;
|
|
79
|
+
amp *= 0.5;
|
|
80
|
+
}
|
|
81
|
+
return norm > 0 ? sum / norm : 0.5;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export {
|
|
86
|
+
mix32,
|
|
87
|
+
hash2,
|
|
88
|
+
rand01,
|
|
89
|
+
randSigned,
|
|
90
|
+
seedFromString,
|
|
91
|
+
TileableNoise
|
|
92
|
+
};
|