Templates-Meta Art
This commit is contained in:
153
src/compose/templates.js
Normal file
153
src/compose/templates.js
Normal file
@@ -0,0 +1,153 @@
|
||||
/* ============================================================
|
||||
compose/templates.js — composition TEMPLATES: the geometric
|
||||
skeletons of famous pictures, applied to our vocabulary. Each
|
||||
template is a coherent point in the 7-axis composition space
|
||||
(horizon ratio · focal placement · thrust · symmetry · figure:void
|
||||
· atmosphere · palette). build(seed, i) → a full composition config;
|
||||
the seed supplies content, the template supplies structure.
|
||||
See docs/COMPOSITION-TEMPLATES.md.
|
||||
============================================================ */
|
||||
import { DEFAULT_COMPOSITION } from './schema.js';
|
||||
|
||||
const clone = (o) => JSON.parse(JSON.stringify(o));
|
||||
const merge = (a, b) => {
|
||||
const o = { ...a };
|
||||
for (const k in b) o[k] = (b[k] && typeof b[k] === 'object' && !Array.isArray(b[k])) ? merge(a[k] || {}, b[k]) : b[k];
|
||||
return o;
|
||||
};
|
||||
// variation per index: 0 = as-authored · 1 = mirror across X · 2 = tonal/horizon drift
|
||||
function vary(c, i) {
|
||||
if (i === 1) {
|
||||
for (const g of ['disk', 'bubble', 'fiduciaries', 'fieldGrid', 'fieldSea'])
|
||||
if (c[g] && c[g].transform) c[g].transform.x = -(c[g].transform.x || 0);
|
||||
if (c.fieldGrid) { if (c.fieldGrid.yaw != null) c.fieldGrid.yaw = -c.fieldGrid.yaw; if (c.fieldGrid.originX != null) c.fieldGrid.originX = -c.fieldGrid.originX; }
|
||||
if (c.fiduciaries && c.fiduciaries.from) c.fiduciaries.from = [-c.fiduciaries.from[0], c.fiduciaries.from[1]];
|
||||
} else if (i === 2) {
|
||||
if (c.fieldSea) {
|
||||
c.fieldSea.horizonY = Math.min(0.74, (c.fieldSea.horizonY ?? 0.36) + 0.05);
|
||||
if (c.fieldSea.color) { c.fieldSea.color.hueBack = (c.fieldSea.color.hueBack ?? 0.5) + 0.04; c.fieldSea.color.hueFront = (c.fieldSea.color.hueFront ?? 0.5) + 0.04; }
|
||||
}
|
||||
if (c.disk && c.disk.transform) c.disk.transform.y = (c.disk.transform.y || 0) - 0.04;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
export const TEMPLATES = [
|
||||
// 1 — HOKUSAI · dynamic asymmetry: low horizon, swelling sea, tiny low event,
|
||||
// small high sun; indigo/Prussian. ×3
|
||||
{
|
||||
id: 'great-wave', name: 'Great Wave', source: 'Hokusai', reps: 3,
|
||||
seeds: ['HOKUSAI-3311', 'KANAGAWA-1820', 'SURGE-7782'],
|
||||
over: {
|
||||
background: { color: 'rgb(224,223,213)', glow: { strength: 0.42, followSun: true }, vignette: { strength: 0.34 } },
|
||||
fieldSea: { color: { hueBack: 0.62, hueFront: 0.58, sat: 0.55 }, chaos: 0.5, blips: 1.2, mound: 0.62, horizonY: 0.5, lines: 54 },
|
||||
fieldGrid: { opacity: 0.3, pos: 'behind', color: { hue: 0.6, hue2: 0.58, sat: 0.3, lightNear: 0.34, lightFar: 0.62 }, pitch: 0.42, yaw: 0.5, dist: 3.0 },
|
||||
disk: { transform: { x: 0.42, y: -0.5, rotation: 0, scale: 0.5 }, hue: 0.05, sat: 0.85, size: 0.13, pressure: 0.7 },
|
||||
bubble: { transform: { x: -0.24, y: 0.3, rotation: -12, scale: 0.55 }, palette: 'magentarise', primaries: 16, sweepers: 6, eloss: 0.32 },
|
||||
fiduciaries: { label: 'auto', from: [0.3, -0.4] },
|
||||
},
|
||||
},
|
||||
// 2 — FRIEDRICH · the sublime void: horizon sliver low, one tiny cool sun, ~85%
|
||||
// empty, no grid/fiduciaries. ×2
|
||||
{
|
||||
id: 'monk-by-sea', name: 'Monk by the Sea', source: 'Friedrich', reps: 2,
|
||||
seeds: ['CASPAR-1810', 'RUCKEN-0042'],
|
||||
over: {
|
||||
background: { color: 'rgb(214,216,215)', glow: { strength: 0.5, followSun: false }, vignette: { strength: 0.28 } },
|
||||
fieldSea: { color: { hueBack: 0.6, hueFront: 0.58, sat: 0.26 }, chaos: 0.18, blips: 0.4, mound: 0.12, horizonY: 0.72, lines: 40, layerOpacity: 0.82 },
|
||||
fieldGrid: { enabled: false },
|
||||
disk: { transform: { x: -0.06, y: 0.46, rotation: 0, scale: 0.32 }, hue: 0.58, sat: 0.42, size: 0.12, pressure: 0.4 },
|
||||
bubble: { transform: { x: 0.12, y: 0.5, rotation: 0, scale: 0.3 }, palette: 'mono', primaries: 8, sweepers: 2, cosmics: 2, deltaRate: 0.4, layerOpacity: 0.8 },
|
||||
fiduciaries: { enabled: false },
|
||||
},
|
||||
},
|
||||
// 3 — ROTHKO · colour fields: flat band over a contrasting ground, centred seam,
|
||||
// strong glow + vignette, no figure. ×2
|
||||
{
|
||||
id: 'rothko', name: 'Colour Fields', source: 'Rothko', reps: 2,
|
||||
seeds: ['MARK-1957', 'SEAGRAM-0015'],
|
||||
over: {
|
||||
background: { color: 'rgb(178,108,94)', glow: { strength: 0.6, followSun: false }, vignette: { strength: 0.56 } },
|
||||
fieldSea: { color: { hueBack: 0.99, hueFront: 0.02, sat: 0.5 }, chaos: 0.1, blips: 0.18, mound: 0.0, horizonY: 0.52, lines: 32, layerOpacity: 0.9 },
|
||||
fieldGrid: { enabled: false }, disk: { enabled: false }, bubble: { enabled: false }, fiduciaries: { enabled: false },
|
||||
},
|
||||
},
|
||||
// 4 — TURNER · atmospheric dissolution: high warm glow, low opacities everywhere,
|
||||
// bright high sun, dissolving warm grid; gold-haze. ×3
|
||||
{
|
||||
id: 'turner', name: 'Atmospheric Dissolution', source: 'Turner', reps: 3,
|
||||
seeds: ['JMW-1844', 'RAIN-STEAM-09', 'NORHAM-1798'],
|
||||
over: {
|
||||
background: { color: 'rgb(233,222,196)', glow: { strength: 0.95, followSun: true }, vignette: { strength: 0.24 } },
|
||||
fieldSea: { color: { hueBack: 0.1, hueFront: 0.08, sat: 0.35 }, chaos: 0.3, blips: 0.6, mound: 0.3, horizonY: 0.46, lines: 46, layerOpacity: 0.58 },
|
||||
fieldGrid: { opacity: 0.22, color: { hue: 0.1, hue2: 0.08, sat: 0.2, lightNear: 0.5, lightFar: 0.68 }, pitch: 0.3, yaw: 0.3, ripple: { amp: 0.4 }, layerOpacity: 0.7 },
|
||||
disk: { transform: { x: 0.08, y: -0.34, rotation: 0, scale: 0.6 }, hue: 0.1, sat: 0.8, size: 0.18, pressure: 0.3, intensity: 0.95 },
|
||||
bubble: { transform: { x: 0.12, y: -0.04, rotation: 0, scale: 0.7 }, palette: 'kindrise', saturation: 0.9, primaries: 16, eloss: 0.3, layerOpacity: 0.68 },
|
||||
fiduciaries: { enabled: false },
|
||||
},
|
||||
},
|
||||
// 5 — HIROSHIGE / MA · asymmetric negative space: forms to one corner, a bold
|
||||
// two-point diagonal, a large quiet void opposite. ×2
|
||||
{
|
||||
id: 'ma', name: 'Ma · Negative Space', source: 'Hiroshige', reps: 2,
|
||||
seeds: ['ANDO-1857', 'EDO-0100'],
|
||||
over: {
|
||||
background: { color: 'rgb(228,224,210)', glow: { strength: 0.4, followSun: false }, vignette: { strength: 0.3 } },
|
||||
fieldSea: { color: { hueBack: 0.5, hueFront: 0.52, sat: 0.3 }, chaos: 0.22, blips: 0.5, mound: 0.2, horizonY: 0.42, lines: 42, layerOpacity: 0.8 },
|
||||
fieldGrid: { opacity: 0.4, pos: 'over', color: { hue: 0.55, hue2: 0.5, sat: 0.28, lightNear: 0.34, lightFar: 0.64 }, pitch: 0.3, yaw: 0.72, dist: 2.6, originX: 0.3 },
|
||||
disk: { transform: { x: 0.55, y: -0.46, rotation: 0, scale: 0.4 }, hue: 0.06, sat: 0.82, size: 0.12, pressure: 0.7 },
|
||||
bubble: { transform: { x: 0.5, y: 0.4, rotation: 8, scale: 0.5 }, palette: 'magentarise', primaries: 14, sweepers: 5 },
|
||||
fiduciaries: { label: 'auto', from: [0.2, -0.05] },
|
||||
},
|
||||
},
|
||||
// 6 — MALEVICH · single form on void: one bold dark/saturated disk off-centre,
|
||||
// sea off, a single faint tilted grid plane. ×2
|
||||
{
|
||||
id: 'suprematist', name: 'Single Form on Void', source: 'Malevich', reps: 2,
|
||||
seeds: ['KAZIMIR-1915', 'BLACK-SQ-00'],
|
||||
over: {
|
||||
background: { color: 'rgb(233,230,220)', glow: { strength: 0.3, followSun: true }, vignette: { strength: 0.2 } },
|
||||
fieldSea: { enabled: false },
|
||||
fieldGrid: { opacity: 0.26, pos: 'behind', transform: { x: 0, y: 0, rotation: 18, scale: 1.1 }, pitch: 0.18, yaw: 0.0, color: { hue: 0.0, hue2: 0.02, sat: 0.18, lightNear: 0.4, lightFar: 0.66 } },
|
||||
disk: { transform: { x: -0.2, y: -0.1, rotation: 0, scale: 1.0 }, hue: 0.0, sat: 0.92, size: 0.2, pressure: 0.95, intensity: 0.9, striations: 0.15 },
|
||||
bubble: { transform: { x: 0.34, y: 0.28, rotation: 0, scale: 0.34 }, palette: 'mono', primaries: 7, sweepers: 1, deltaRate: 0.5, layerOpacity: 0.85, showBoundary: false, instrument: 0 },
|
||||
fiduciaries: { enabled: false },
|
||||
},
|
||||
},
|
||||
// 7 — RENAISSANCE φ · classical balance: sun on a φ point, event on the opposing
|
||||
// third, horizon on the lower third, a measured grid. ×3
|
||||
{
|
||||
id: 'golden-thirds', name: 'Golden Section', source: 'Renaissance φ', reps: 3,
|
||||
seeds: ['VITRUVIAN-1490', 'PHI-1618', 'URBINO-1465'],
|
||||
over: {
|
||||
background: { color: 'rgb(230,224,206)', glow: { strength: 0.55, followSun: true }, vignette: { strength: 0.35 } },
|
||||
fieldSea: { color: { hueBack: 0.52, hueFront: 0.47, sat: 0.5 }, chaos: 0.28, blips: 0.7, mound: 0.3, horizonY: 0.62, lines: 46 },
|
||||
fieldGrid: { opacity: 0.34, pos: 'over', pitch: 0.4, yaw: 0.38, color: { hue: 0.54, hue2: 0.5, sat: 0.28, lightNear: 0.34, lightFar: 0.64 } },
|
||||
disk: { transform: { x: -0.236, y: -0.382, rotation: 0, scale: 0.6 }, hue: 0.07, sat: 0.82, size: 0.15, pressure: 0.8 },
|
||||
bubble: { transform: { x: 0.236, y: 0.1, rotation: 8, scale: 0.62 }, palette: 'magentarise', primaries: 18, sweepers: 5 },
|
||||
fiduciaries: { label: 'auto' },
|
||||
},
|
||||
},
|
||||
// 8 — FRANK LLOYD WRIGHT · organic rectilinearity: low strong horizon, bold near-
|
||||
// frontal orthogonal grid, flat horizontal sea, hearth-anchor disk (Cherokee
|
||||
// red, dark core) off-centre; earthy Taliesin palette. ×3
|
||||
{
|
||||
id: 'wright', name: 'Cantilevered Horizontal', source: 'Frank Lloyd Wright', reps: 3,
|
||||
seeds: ['TALIESIN-1911', 'FALLINGWATER-37', 'PRAIRIE-1901'],
|
||||
over: {
|
||||
background: { color: 'rgb(226,218,196)', glow: { strength: 0.45, followSun: true }, vignette: { strength: 0.34 } },
|
||||
fieldSea: { color: { hueBack: 0.1, hueFront: 0.13, sat: 0.4 }, chaos: 0.15, blips: 0.3, mound: 0.05, horizonY: 0.6, lines: 40, layerOpacity: 0.85 },
|
||||
fieldGrid: { opacity: 0.5, pos: 'over', style: 'floor', pitch: 0.5, yaw: 0.08, persp: 1.0, dist: 2.8, nx: 18, nz: 20, originY: 0.3, color: { hue: 0.08, hue2: 0.06, sat: 0.3, lightNear: 0.32, lightFar: 0.6 } },
|
||||
disk: { transform: { x: -0.32, y: 0.02, rotation: 0, scale: 0.8 }, hue: 0.03, sat: 0.85, size: 0.16, pressure: 0.9, striations: 0.4 },
|
||||
bubble: { transform: { x: 0.3, y: -0.05, rotation: 0, scale: 0.7 }, palette: 'kind', saturation: 0.95, primaries: 16, sweepers: 3, bfield: 1.2 },
|
||||
fiduciaries: { label: 'auto' },
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// build the composition for a template at variation index i
|
||||
export function buildTemplate(t, i) {
|
||||
const c = merge(clone(DEFAULT_COMPOSITION), t.over);
|
||||
c.seed = t.seeds[i % t.seeds.length];
|
||||
return vary(c, i);
|
||||
}
|
||||
Reference in New Issue
Block a user