diff --git a/rainbow-quox/script/color.ts b/rainbow-quox/script/color.ts index 4fdd815..65b9f54 100644 --- a/rainbow-quox/script/color.ts +++ b/rainbow-quox/script/color.ts @@ -37,20 +37,18 @@ export function makeColorInfo(f: (l: Layer) => A): Record { return Object.fromEntries(allLayers.map(l => [l, f(l)])) as Record; } -export type BaseCol = 'outer' | 'belly' | 'fins'; -export type OptionalBaseCol = 'eyes' | 'stripes'; - -type KnownPalette = - Record & Partial>; +type KnownPalette = Partial>; export function colors(r: Rand = new Rand(), base?: KnownPalette): Scheme { const outer = base?.outer ?? r.color('dark'); - const outerCols: OuterCols = - { outer, spines: mkSpines(r, outer), vitiligo1: mkVitiligo(r, outer) }; + const spines = base?.spines ?? mkSpines(r, outer); + const vitiligo1 = base?.vitiligo1 ?? mkVitiligo(r, outer); + const outerCols: OuterCols = { outer, spines, vitiligo1 }; - const stripes = mkStripes(r); - const sockCols: SockCols = { stripes, cuffs: mkCuffs(r, stripes) }; + const stripes = base?.stripes ?? mkStripes(r); + const cuffs = base?.cuffs ?? mkCuffs(r, stripes); + const sockCols: SockCols = { stripes, cuffs }; let finCols: FinCols, bellyCols: BellyCols, type: SchemeType; const whichBody = r.float(); @@ -105,7 +103,7 @@ function mkCuffs(r: Rand, sock: Color): Color { function mkFins(r: Rand, h: Hue, outer: Color, base?: KnownPalette): FinCols { - const baseFin1 = base?.fins; + const baseFin1 = base?.fins1; const [fin1Hue, fin2Hue, fin3Hue] = r.analogous(baseFin1?.hue ?? h, 3); const direction: 'lighter' | 'darker' = r.choice(['lighter', 'darker']); @@ -119,32 +117,35 @@ function mkFins(r: Rand, h: Hue, outer: Color, const fins1 = baseFin1 ?? oklch(ll(outer.luma), cc(outer.luma, outer.chroma), fin1Hue!); - const fins2 = oklch(ll(fins1.luma), cc(fins1.luma, fins1.chroma), fin2Hue!); - const fins3 = oklch(ll(fins2.luma), cc(fins2.luma, fins2.chroma), fin3Hue!); + const fins2 = base?.fins2 ?? + oklch(ll(fins1.luma), cc(fins1.luma, fins1.chroma), fin2Hue!); + const fins3 = base?.fins3 ?? + oklch(ll(fins2.luma), cc(fins2.luma, fins2.chroma), fin3Hue!); const lighter = fins1.luma >= fins3.luma ? fins1 : fins3; - const vitiligo4 = mkVitiligo(r, lighter); + const vitiligo4 = base?.vitiligo4 ?? mkVitiligo(r, lighter); return { fins1, fins2, fins3, vitiligo4 }; } function mkBelly(r: Rand, h: Hue, base?: KnownPalette): BellyCols { - const baseBelly1 = base?.belly; + const baseBelly1 = base?.belly1; const [belly1Hue, belly2Hue] = r.analogous(baseBelly1?.hue ?? h, 2); const belly1 = baseBelly1 ?? oklch(r.float(0.7, r.maxl), r.baseChroma(1), belly1Hue!); - const belly2 = belly1.with({ type: 'oklch', + const belly2 = base?.belly2 ?? belly1.with({ type: 'oklch', l: x => min(r.maxl, x * 1.1), c: x => x * 0.9, h: [belly2Hue!], }); - const vitiligo3 = mkVitiligo(r, belly1); - const vitiligo2 = mkVitiligo(r, belly2); + const vitiligo3 = base?.vitiligo3 ?? mkVitiligo(r, belly1); + const vitiligo2 = base?.vitiligo2 ?? mkVitiligo(r, belly2); return { belly1, belly2, vitiligo2, vitiligo3 }; } function mkMisc(r: Rand, o: OuterCols, f: FinCols, b: BellyCols, base?: KnownPalette): MiscCols { - const masks = oklch(r.float(0.8, r.maxl), r.float(0.01, 0.06), - r.analogous1(r.choice([o.outer, b.belly1, f.fins1]).hue)); + const masks = base?.masks ?? + oklch(r.float(0.8, r.maxl), r.float(0.01, 0.06), + r.analogous1(r.choice([o.outer, b.belly1, f.fins1]).hue)); return { masks, eyes: base?.eyes ?? oklch( @@ -152,13 +153,14 @@ function mkMisc(r: Rand, o: OuterCols, f: FinCols, b: BellyCols, r.float(0.28, r.maxcLight), r.boolean() ? r.analogous1(o.outer.hue) : r.complementary1(o.outer.hue) ), - claws: masks.with({ type: 'oklch', - l: x => min(r.maxl, x + r.float(0, 0.1)), - c: [r.float(0.01, 0.06)], - h: h => r.analogous1(h), - }), - lines: oklch(r.float(0.01, 0.06), r.baseChroma(0), - r.analogous1(o.outer.hue)), + claws: base?.claws ?? + masks.with({ type: 'oklch', + l: x => min(r.maxl, x + r.float(0, 0.1)), + c: [r.float(0.01, 0.06)], + h: h => r.analogous1(h), + }), + lines: base?.lines ?? + oklch(r.float(0.01, 0.06), r.baseChroma(0), r.analogous1(o.outer.hue)), }; } @@ -177,69 +179,67 @@ function merge({ outer, spines, vitiligo1 }: OuterCols, export const KNOWN: Record = { niss: { - outer: oklch(0.83, 0.201, 151), - belly: oklch(0.87, 0.082, 99), - fins: oklch(0.68, 0.178, 16), - eyes: oklch(0.73, 0.135, 242), + outer: oklch(0.83, 0.201, 151), + belly1: oklch(0.87, 0.082, 99), + fins1: oklch(0.68, 0.178, 16), + eyes: oklch(0.73, 0.135, 242), }, kesi: { - outer: oklch(0.86, 0.147, 147), - belly: oklch(0.96, 0.04, 108), - fins: oklch(0.94, 0.142, 102), - eyes: oklch(0.76, 0.115, 300), + outer: oklch(0.86, 0.147, 147), + belly1: oklch(0.96, 0.04, 108), + fins1: oklch(0.94, 0.142, 102), + eyes: oklch(0.76, 0.115, 300), }, 60309: { - outer: oklch(0.84, 0.068, 212), - belly: oklch(0.56, 0.035, 233), - fins: oklch(0.55, 0.101, 268), - eyes: oklch(0.86, 0.146, 154), + outer: oklch(0.84, 0.068, 212), + belly1: oklch(0.56, 0.035, 233), + fins1: oklch(0.55, 0.101, 268), + eyes: oklch(0.86, 0.146, 154), }, 'prickly pear': { - outer: oklch(0.64, 0.087, 316), - belly: oklch(0.88, 0.03, 88), - fins: oklch(0.6, 0.071, 142), - eyes: oklch(0.66, 0.091, 134), + outer: oklch(0.64, 0.087, 316), + belly1: oklch(0.88, 0.03, 88), + fins1: oklch(0.6, 0.071, 142), + eyes: oklch(0.66, 0.091, 134), }, 'the goo': { - outer: oklch(0.92, 0.046, 354), - belly: oklch(0.83, 0.099, 354), - fins: oklch(0.74, 0.115, 354), - eyes: oklch(0.73, 0.149, 0), + outer: oklch(0.92, 0.046, 354), + belly1: oklch(0.83, 0.099, 354), + fins1: oklch(0.74, 0.115, 354), + eyes: oklch(0.73, 0.149, 0), }, lambda: { - outer: oklch(0.71, 0.154, 58), - belly: oklch(0.9, 0.05, 80), - fins: oklch(0.76, 0.16, 140), - eyes: oklch(0.82, 0.178, 141), + outer: oklch(0.71, 0.154, 58), + belly1: oklch(0.9, 0.05, 80), + fins1: oklch(0.76, 0.16, 140), + eyes: oklch(0.82, 0.178, 141), }, flussence: { - outer: oklch(0.77, 0.118, 133), - belly: oklch(0.71, 0.086, 253), - fins: oklch(0.58, 0.102, 254), - eyes: oklch(0.37, 0.107, 278), + outer: oklch(0.77, 0.118, 133), + belly1: oklch(0.71, 0.086, 253), + fins1: oklch(0.58, 0.102, 254), + eyes: oklch(0.37, 0.107, 278), }, serena: { - outer: oklch(0.69, 0.176, 349), - belly: oklch(0.92, 0.04, 350), - fins: oklch(0.74, 0.138, 319), - eyes: oklch(0.65, 0.206, 4), + outer: oklch(0.69, 0.176, 349), + belly1: oklch(0.92, 0.04, 350), + fins1: oklch(0.74, 0.138, 319), + eyes: oklch(0.65, 0.206, 4), }, pippin: { - outer: oklch(0.74, 0.08, 61), - belly: oklch(0.82, 0.062, 70), - fins: oklch(0.52, 0.09, 45), - eyes: oklch(0.74, 0.167, 136), + outer: oklch(0.74, 0.08, 61), + belly1: oklch(0.82, 0.062, 70), + fins1: oklch(0.52, 0.09, 45), + eyes: oklch(0.74, 0.167, 136), }, su: { - outer: oklch(0.29, 0.012, 219), - belly: oklch(0.89, 0.01, 256), - fins: oklch(0.53, 0.093, 20), - // eyes: oklch(0.53, 0.109, 254), + outer: oklch(0.29, 0.012, 219), + belly1: oklch(0.89, 0.01, 256), + fins1: oklch(0.53, 0.093, 20), }, trans: { - outer: oklch(0.83, 0.065, 228), - belly: oklch(0.95, 0.021, 137), - fins: oklch(0.86, 0.069, 352), - // eyes: oklch(0.57, 0.158, 273), + outer: oklch(0.83, 0.065, 228), + belly1: oklch(0.95, 0.021, 137), + fins1: oklch(0.86, 0.069, 352), }, };