231 lines
8.2 KiB
JavaScript
231 lines
8.2 KiB
JavaScript
/* ============================================================
|
|
qft-variations-light.mjs — sketch 04.
|
|
Lighter backgrounds, larger field scales (most bleed past the
|
|
frame), per-edge hue GRADIENTS within each field, and
|
|
noticeably THICKER strokes than previous sketches. Custom
|
|
paperOverride RGB for the more unusual pale grounds.
|
|
Output → output/qft/sketch04/
|
|
============================================================ */
|
|
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
import { generateQFTScene } from '../src/qft/scene.js';
|
|
import { paramsFromSeed } from '../src/qft/params.js';
|
|
import { renderQFTSVG } from '../src/qft/renderer.js';
|
|
|
|
const BASE_SEED = 'FEYNMAN-7167';
|
|
const OUT_DIR = 'output/qft/sketch04';
|
|
const SIZE = 1800;
|
|
mkdirSync(OUT_DIR, { recursive: true });
|
|
|
|
const F = (hueStart, hueEnd, saturation, lightness, opacity) =>
|
|
({ hueStart, hueEnd, saturation, lightness, opacity });
|
|
|
|
// helper: build a paperOverride from one RGB and derive sensible glow stops
|
|
const paper = (flat, glowInDelta = [18, 16, 14], glowOutDelta = [-25, -22, -20]) => ({
|
|
flat,
|
|
glowIn: [flat[0] + glowInDelta[0], flat[1] + glowInDelta[1], flat[2] + glowInDelta[2]],
|
|
glowOut: [flat[0] + glowOutDelta[0], flat[1] + glowOutDelta[1], flat[2] + glowOutDelta[2]],
|
|
});
|
|
|
|
// dark header/vignette tones to read against light paper
|
|
const DARK_FEATURE = [60, 48, 36];
|
|
const DARK_VIGN = [70, 55, 40];
|
|
|
|
const variations = [
|
|
{
|
|
name: '01_warm-sunset-cream',
|
|
label: 'Warm sunset · cream · huge cubic bleeding past frame',
|
|
overrides: {
|
|
substrate: 'cream',
|
|
stroke: 2.6,
|
|
cubicScale: 1.75,
|
|
schlegelScale: 0.85,
|
|
e8Count: 3, e8Scale: 0.22, e8OriginRadius: 0.55,
|
|
fields: {
|
|
cubic: F(0.10, 0.02, 0.65, 0.40, 0.82), // amber → red
|
|
schlegel: F(0.13, 0.06, 0.45, 0.38, 0.65), // gold → orange
|
|
e8: F(0.05, 0.13, 0.75, 0.42, 0.92), // red → gold
|
|
links: F(0.95, 0.04, 0.85, 0.38, 0.96), // pink → red bright
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: '02_pale-verdigris-linen',
|
|
label: 'Pale verdigris · linen ground · large scales',
|
|
overrides: {
|
|
paperOverride: paper([222, 210, 184]),
|
|
vignOverride: DARK_VIGN,
|
|
featureOverride: DARK_FEATURE,
|
|
stroke: 2.4,
|
|
cubicScale: 1.55,
|
|
schlegelScale: 1.35,
|
|
e8Count: 3, e8Scale: 0.24, e8OriginRadius: 0.48,
|
|
fields: {
|
|
cubic: F(0.44, 0.50, 0.55, 0.34, 0.82), // teal → cyan
|
|
schlegel: F(0.06, 0.10, 0.55, 0.38, 0.66), // copper accents
|
|
e8: F(0.35, 0.46, 0.60, 0.32, 0.90), // sage → teal
|
|
links: F(0.04, 0.10, 0.80, 0.38, 0.95),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: '03_rose-peach',
|
|
label: 'Rose pastel on peach paper · huge cubic',
|
|
overrides: {
|
|
paperOverride: paper([232, 200, 175]),
|
|
vignOverride: [90, 50, 40],
|
|
featureOverride: [110, 60, 50],
|
|
stroke: 2.8,
|
|
cubicScale: 1.65,
|
|
schlegelScale: 0.75, schlegelOriginX: 0.20,
|
|
e8Count: 2, e8Scale: 0.28, e8OriginRadius: 0.52,
|
|
fields: {
|
|
cubic: F(0.92, 0.04, 0.55, 0.42, 0.82),
|
|
schlegel: F(0.88, 0.94, 0.45, 0.40, 0.66),
|
|
e8: F(0.96, 0.06, 0.65, 0.42, 0.92),
|
|
links: F(0.90, 0.04, 0.85, 0.38, 0.96),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: '04_pale-sky-ivory',
|
|
label: 'Pale sky · ivory · huge Schlegel tesseract',
|
|
overrides: {
|
|
paperOverride: paper([232, 222, 200]),
|
|
vignOverride: [60, 50, 40],
|
|
featureOverride: DARK_FEATURE,
|
|
stroke: 2.4,
|
|
cubicScale: 0.70,
|
|
schlegelScale: 1.95, // massive — bleeds significantly
|
|
e8Count: 3, e8Scale: 0.20, e8OriginRadius: 0.60,
|
|
fields: {
|
|
cubic: F(0.58, 0.66, 0.55, 0.30, 0.80), // blue → violet
|
|
schlegel: F(0.62, 0.72, 0.55, 0.32, 0.66), // indigo → violet
|
|
e8: F(0.55, 0.70, 0.65, 0.30, 0.92),
|
|
links: F(0.60, 0.80, 0.85, 0.32, 0.96),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: '05_mint-gold-pale',
|
|
label: 'Mint & gold · pale-mint ground',
|
|
overrides: {
|
|
paperOverride: paper([210, 225, 208]),
|
|
vignOverride: [30, 55, 35],
|
|
featureOverride: [40, 70, 45],
|
|
stroke: 2.6,
|
|
cubicScale: 1.50,
|
|
schlegelScale: 1.25,
|
|
e8Count: 3, e8Scale: 0.26, e8OriginRadius: 0.48,
|
|
fields: {
|
|
cubic: F(0.40, 0.50, 0.55, 0.30, 0.82), // mint teal
|
|
schlegel: F(0.10, 0.16, 0.60, 0.36, 0.66), // gold
|
|
e8: F(0.13, 0.20, 0.80, 0.40, 0.92),
|
|
links: F(0.08, 0.14, 0.85, 0.40, 0.96),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: '06_bone-radial-gradient',
|
|
label: 'Bone china · radial gradient (cool centre → warm edges)',
|
|
overrides: {
|
|
paperOverride: paper([234, 230, 222]),
|
|
vignOverride: [70, 60, 50],
|
|
featureOverride: DARK_FEATURE,
|
|
stroke: 2.6, gradientMode: 'radial',
|
|
cubicScale: 1.55, schlegelScale: 1.30,
|
|
e8Count: 3, e8Scale: 0.22, e8OriginRadius: 0.55,
|
|
fields: {
|
|
cubic: F(0.55, 0.06, 0.62, 0.36, 0.82), // cyan centre → orange edges
|
|
schlegel: F(0.58, 0.04, 0.50, 0.34, 0.70),
|
|
e8: F(0.55, 0.05, 0.72, 0.40, 0.92),
|
|
links: F(0.55, 0.05, 0.85, 0.40, 0.96),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: '07_pale-mauve-violet',
|
|
label: 'Pale mauve fog · violet → pink gradients · thick',
|
|
overrides: {
|
|
paperOverride: paper([222, 205, 224]),
|
|
vignOverride: [55, 35, 60],
|
|
featureOverride: [75, 50, 90],
|
|
stroke: 3.0,
|
|
cubicScale: 1.85, // bleeds heavily
|
|
schlegelScale: 0.90,
|
|
e8Count: 3, e8Scale: 0.22, e8OriginRadius: 0.50,
|
|
fields: {
|
|
cubic: F(0.74, 0.92, 0.55, 0.34, 0.84),
|
|
schlegel: F(0.78, 0.86, 0.50, 0.32, 0.68),
|
|
e8: F(0.82, 0.96, 0.65, 0.38, 0.92),
|
|
links: F(0.78, 0.95, 0.85, 0.36, 0.96),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: '08_faded-blueprint',
|
|
label: 'Faded blueprint · pale cyan paper · huge Schlegel',
|
|
overrides: {
|
|
paperOverride: paper([186, 214, 228]),
|
|
vignOverride: [40, 55, 70],
|
|
featureOverride: [30, 50, 75],
|
|
stroke: 2.8,
|
|
cubicScale: 0.80,
|
|
schlegelScale: 1.90,
|
|
e8Count: 3, e8Scale: 0.22, e8OriginRadius: 0.55,
|
|
fields: {
|
|
cubic: F(0.60, 0.66, 0.60, 0.22, 0.86), // dark blue → navy
|
|
schlegel: F(0.58, 0.62, 0.55, 0.20, 0.66),
|
|
e8: F(0.62, 0.72, 0.70, 0.28, 0.92),
|
|
links: F(0.58, 0.68, 0.85, 0.28, 0.96),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: '09_linen-sepia-large',
|
|
label: 'Linen · warm sepia gradients · everything LARGE · thickest strokes',
|
|
overrides: {
|
|
paperOverride: paper([226, 210, 178]),
|
|
vignOverride: [80, 55, 30],
|
|
featureOverride: [85, 55, 30],
|
|
stroke: 3.4, // chunkiest of the set
|
|
cubicScale: 1.65, schlegelScale: 1.55,
|
|
e8Count: 3, e8Scale: 0.28, e8OriginRadius: 0.50,
|
|
fields: {
|
|
cubic: F(0.06, 0.12, 0.55, 0.30, 0.86),
|
|
schlegel: F(0.10, 0.03, 0.45, 0.28, 0.70),
|
|
e8: F(0.08, 0.16, 0.70, 0.36, 0.92),
|
|
links: F(0.02, 0.12, 0.85, 0.30, 0.96),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: '10_pearl-pastel-spectrum',
|
|
label: 'Pearl · pastel rainbow (per-field hue families)',
|
|
overrides: {
|
|
paperOverride: paper([240, 235, 230]),
|
|
vignOverride: [70, 65, 60],
|
|
featureOverride: [80, 70, 60],
|
|
stroke: 2.8,
|
|
cubicScale: 1.50, schlegelScale: 1.40,
|
|
e8Count: 3, e8Scale: 0.24, e8OriginRadius: 0.55,
|
|
fields: {
|
|
cubic: F(0.55, 0.70, 0.50, 0.42, 0.80), // cyan → violet pastel
|
|
schlegel: F(0.08, 0.18, 0.45, 0.42, 0.62), // gold → yellow pastel
|
|
e8: F(0.86, 0.04, 0.55, 0.42, 0.86), // pink → red pastel
|
|
links: F(0.38, 0.55, 0.70, 0.40, 0.94), // green → cyan pastel
|
|
},
|
|
},
|
|
},
|
|
];
|
|
|
|
const base = paramsFromSeed(BASE_SEED);
|
|
for (const v of variations) {
|
|
const params = { ...base, ...v.overrides };
|
|
if (v.overrides.fields) params.fields = v.overrides.fields;
|
|
const svg = renderQFTSVG(generateQFTScene(params), params, SIZE);
|
|
const path = `${OUT_DIR}/${v.name}.svg`;
|
|
writeFileSync(path, svg);
|
|
console.log(`ok ${v.name} · ${v.label}`);
|
|
}
|
|
console.log(`\nrendered ${variations.length} variations → ${OUT_DIR}/`);
|