export const PARAMS = {
count: { value: 5, min: 2, max: 10, step: 1, label: "Shape Count", folder: "Structure" },
radius: { value: 120, min: 30, max: 300, step: 1, label: "Radius", folder: "Structure" },
smooth: { value: 60, min: 1, max: 200, step: 1, label: "Blend Smoothness", folder: "Structure" },
bands: { value: 8, min: 2, max: 30, step: 1, label: "Iso Bands", folder: "Appearance" },
hue: { value: 220, min: 0, max: 360, step: 1, label: "Base Hue", folder: "Appearance" },
cspread:{ value: 90, min: 0, max: 180, step: 1, label: "Hue Spread", folder: "Appearance" },
step: { value: 4, min: 1, max: 12, step: 1, label: "Sample Step (px)", folder: "Performance" },
};
export const SHARE = { bookmarked: ["count", "radius", "smooth", "bands", "hue", "cspread"] };
export function sketchSetup(ctx, w, h, tng) {
const centers = [];
for (let i = 0; i < 10; i++) {
centers.push([tng.randomRange(w * 0.2, w * 0.8), tng.randomRange(h * 0.2, h * 0.8)]);
}
return { centers };
}
export function sketchDraw(ctx, w, h, params, tng, state) {
const img = ctx.createImageData(w, h);
const data = img.data;
const step = params.step;
for (let y = 0; y < h; y += step) {
for (let x = 0; x < w; x += step) {
let d = Infinity;
for (let i = 0; i < params.count; i++) {
const c = state.centers[i];
const di = tng.sdf.circle(x, y, c[0], c[1], params.radius);
d = i === 0 ? di : tng.sdf.smin(d, di, params.smooth);
}
const band = Math.floor((d / params.radius + 1) * params.bands * 0.5);
const t = Math.abs(((band % 2) + 2) % 2);
const hue = (params.hue + (band / params.bands) * params.cspread) % 360;
const [r, g, b] = tng.color.oklchToRgb(0.4 + t * 0.4, 0.12, hue);
const sx = step, sy = step;
for (let dy = 0; dy < sy && y + dy < h; dy++) {
for (let dx = 0; dx < sx && x + dx < w; dx++) {
const idx = ((y + dy) * w + (x + dx)) * 4;
data[idx] = r * 255;
data[idx + 1] = g * 255;
data[idx + 2] = b * 255;
data[idx + 3] = 255;
}
}
}
}
ctx.putImageData(img, 0, 0);
}