git-hash-art 0.10.0 → 0.11.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/.github/workflows/deploy-www.yml +57 -0
- package/ALGORITHM.md +108 -8
- package/CHANGELOG.md +20 -0
- package/dist/browser.js +873 -64
- package/dist/browser.js.map +1 -1
- package/dist/main.js +875 -64
- package/dist/main.js.map +1 -1
- package/dist/module.js +875 -64
- package/dist/module.js.map +1 -1
- package/package.json +1 -1
- package/src/lib/archetypes.ts +33 -1
- package/src/lib/canvas/colors.ts +52 -5
- package/src/lib/canvas/draw.ts +94 -5
- package/src/lib/render.ts +501 -67
- package/src/lib/utils.ts +109 -0
package/src/lib/utils.ts
CHANGED
|
@@ -54,6 +54,115 @@ export const Proportions = {
|
|
|
54
54
|
|
|
55
55
|
export type ProportionType = keyof typeof Proportions;
|
|
56
56
|
|
|
57
|
+
// ── Deterministic 2D Simplex Noise ──────────────────────────────────
|
|
58
|
+
// A compact implementation seeded from the RNG so every hash produces
|
|
59
|
+
// a unique noise field without external dependencies.
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Create a seeded 2D simplex noise function.
|
|
63
|
+
* Returns noise(x, y) → float in approximately [-1, 1].
|
|
64
|
+
*/
|
|
65
|
+
export function createSimplexNoise(rng: () => number): (x: number, y: number) => number {
|
|
66
|
+
// Build a deterministic permutation table (256 entries, doubled)
|
|
67
|
+
const perm = new Uint8Array(512);
|
|
68
|
+
const p = new Uint8Array(256);
|
|
69
|
+
for (let i = 0; i < 256; i++) p[i] = i;
|
|
70
|
+
// Fisher-Yates shuffle with our seeded RNG
|
|
71
|
+
for (let i = 255; i > 0; i--) {
|
|
72
|
+
const j = Math.floor(rng() * (i + 1));
|
|
73
|
+
const tmp = p[i]; p[i] = p[j]; p[j] = tmp;
|
|
74
|
+
}
|
|
75
|
+
for (let i = 0; i < 512; i++) perm[i] = p[i & 255];
|
|
76
|
+
|
|
77
|
+
// 12 gradient vectors for 2D simplex
|
|
78
|
+
const GRAD2 = [
|
|
79
|
+
[1,1],[-1,1],[1,-1],[-1,-1],
|
|
80
|
+
[1,0],[-1,0],[0,1],[0,-1],
|
|
81
|
+
[1,1],[-1,1],[1,-1],[-1,-1],
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
const F2 = 0.5 * (Math.sqrt(3) - 1);
|
|
85
|
+
const G2 = (3 - Math.sqrt(3)) / 6;
|
|
86
|
+
|
|
87
|
+
function dot2(g: number[], x: number, y: number): number {
|
|
88
|
+
return g[0] * x + g[1] * y;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return function noise2D(xin: number, yin: number): number {
|
|
92
|
+
const s = (xin + yin) * F2;
|
|
93
|
+
const i = Math.floor(xin + s);
|
|
94
|
+
const j = Math.floor(yin + s);
|
|
95
|
+
const t = (i + j) * G2;
|
|
96
|
+
const X0 = i - t;
|
|
97
|
+
const Y0 = j - t;
|
|
98
|
+
const x0 = xin - X0;
|
|
99
|
+
const y0 = yin - Y0;
|
|
100
|
+
|
|
101
|
+
let i1: number, j1: number;
|
|
102
|
+
if (x0 > y0) { i1 = 1; j1 = 0; }
|
|
103
|
+
else { i1 = 0; j1 = 1; }
|
|
104
|
+
|
|
105
|
+
const x1 = x0 - i1 + G2;
|
|
106
|
+
const y1 = y0 - j1 + G2;
|
|
107
|
+
const x2 = x0 - 1 + 2 * G2;
|
|
108
|
+
const y2 = y0 - 1 + 2 * G2;
|
|
109
|
+
|
|
110
|
+
const ii = i & 255;
|
|
111
|
+
const jj = j & 255;
|
|
112
|
+
|
|
113
|
+
let n0 = 0, n1 = 0, n2 = 0;
|
|
114
|
+
|
|
115
|
+
let t0 = 0.5 - x0 * x0 - y0 * y0;
|
|
116
|
+
if (t0 >= 0) {
|
|
117
|
+
t0 *= t0;
|
|
118
|
+
const gi0 = perm[ii + perm[jj]] % 12;
|
|
119
|
+
n0 = t0 * t0 * dot2(GRAD2[gi0], x0, y0);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let t1 = 0.5 - x1 * x1 - y1 * y1;
|
|
123
|
+
if (t1 >= 0) {
|
|
124
|
+
t1 *= t1;
|
|
125
|
+
const gi1 = perm[ii + i1 + perm[jj + j1]] % 12;
|
|
126
|
+
n1 = t1 * t1 * dot2(GRAD2[gi1], x1, y1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
let t2 = 0.5 - x2 * x2 - y2 * y2;
|
|
130
|
+
if (t2 >= 0) {
|
|
131
|
+
t2 *= t2;
|
|
132
|
+
const gi2 = perm[ii + 1 + perm[jj + 1]] % 12;
|
|
133
|
+
n2 = t2 * t2 * dot2(GRAD2[gi2], x2, y2);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Scale to approximately [-1, 1]
|
|
137
|
+
return 70 * (n0 + n1 + n2);
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Fractal Brownian Motion — layer multiple octaves of noise for richer fields.
|
|
143
|
+
* Returns a function (x, y) → float in approximately [-1, 1].
|
|
144
|
+
*/
|
|
145
|
+
export function createFBM(
|
|
146
|
+
noise: (x: number, y: number) => number,
|
|
147
|
+
octaves = 4,
|
|
148
|
+
lacunarity = 2.0,
|
|
149
|
+
gain = 0.5,
|
|
150
|
+
): (x: number, y: number) => number {
|
|
151
|
+
return function fbm(x: number, y: number): number {
|
|
152
|
+
let value = 0;
|
|
153
|
+
let amplitude = 1;
|
|
154
|
+
let frequency = 1;
|
|
155
|
+
let maxAmp = 0;
|
|
156
|
+
for (let i = 0; i < octaves; i++) {
|
|
157
|
+
value += noise(x * frequency, y * frequency) * amplitude;
|
|
158
|
+
maxAmp += amplitude;
|
|
159
|
+
amplitude *= gain;
|
|
160
|
+
frequency *= lacunarity;
|
|
161
|
+
}
|
|
162
|
+
return value / maxAmp;
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
57
166
|
interface Pattern {
|
|
58
167
|
type: string;
|
|
59
168
|
config: any;
|