refactor rainbow-quox scripting
This commit is contained in:
parent
dff263856c
commit
ddc36a9eea
10 changed files with 556 additions and 461 deletions
120
rainbow-quox/script/color/rand.ts
Normal file
120
rainbow-quox/script/color/rand.ts
Normal file
|
@ -0,0 +1,120 @@
|
|||
import * as R from '../rand.js';
|
||||
import * as Color from './def.js';
|
||||
|
||||
const max = Math.max;
|
||||
const min = Math.min;
|
||||
|
||||
|
||||
export type State = R.State;
|
||||
|
||||
|
||||
export type CloseFar = 'close' | 'far';
|
||||
export type LightDark = 'light' | 'dark';
|
||||
|
||||
export class Rand extends R.Rand {
|
||||
maxl: Color.Luma = 0.9;
|
||||
minl: Color.Luma = 0.4;
|
||||
minlLight: Color.Luma = 0.7;
|
||||
maxlDark: Color.Luma = 0.65;
|
||||
|
||||
mincLight: Color.Chroma = 0.08;
|
||||
maxcLight: Color.Chroma = 0.1;
|
||||
mincDark: Color.Chroma = 0.12;
|
||||
maxcDark: Color.Chroma = 0.175;
|
||||
|
||||
// max spread for a sequence of analogous colors. unless that would put them
|
||||
// too close together
|
||||
maxhWidth: Color.HueDistance = 80;
|
||||
|
||||
// minimum distance between adjacent analogous colors
|
||||
minhSep: Color.HueDistance = 5;
|
||||
|
||||
// size of the wedge a "complementary" color can be in
|
||||
maxhCompl: Color.HueDistance = 40;
|
||||
|
||||
// size of the wedge a "triadic" color can be in
|
||||
maxhTriad: Color.HueDistance = 25;
|
||||
|
||||
constructor();
|
||||
constructor([a, b, c, d]: State);
|
||||
constructor(str: string);
|
||||
constructor(st?: State | string) {
|
||||
if (st === undefined) super();
|
||||
else if (typeof st === 'string') super(st);
|
||||
else super(st);
|
||||
}
|
||||
|
||||
isLight(l: Color.Luma): boolean { return l >= this.minlLight; }
|
||||
|
||||
lightFor(baseL: Color.Luma, d: CloseFar = 'close'): Color.Luma {
|
||||
const maxl = d == 'close' ? min(this.maxl, baseL * 1.25) : this.maxl;
|
||||
return this.float(baseL, maxl);
|
||||
}
|
||||
darkFor(baseL: Color.Luma, d: CloseFar = 'close'): Color.Luma {
|
||||
const minl = d == 'close' ? max(this.minl, baseL * 0.8) : this.minl
|
||||
return this.float(minl, baseL);
|
||||
}
|
||||
|
||||
brightFor(l: Color.Luma, baseC: Color.Chroma): Color.Chroma {
|
||||
return this.float(baseC, this.isLight(l) ? this.maxcLight : this.maxcDark);
|
||||
}
|
||||
|
||||
dullFor(l: Color.Luma, baseC: Color.Chroma): Color.Chroma {
|
||||
return this.float(baseC, this.isLight(l) ? this.mincLight : this.mincDark);
|
||||
}
|
||||
|
||||
analogous1(baseH: Color.Hue): Color.Hue {
|
||||
const size = this.float(this.minhSep, 2 * this.minhSep);
|
||||
return this.boolean() ? baseH + size : baseH - size;
|
||||
}
|
||||
|
||||
analogous(baseH: Color.Hue, count: number): Color.Hue[] {
|
||||
const minWidth = min(count * this.minhSep, this.maxhWidth * 0.8);
|
||||
const width = this.float(minWidth, this.maxhWidth);
|
||||
const sep = width / (count - 1);
|
||||
const start = baseH - (width / 2);
|
||||
const numbers = Array.from({length: count}, (_u, i) => start + i * sep);
|
||||
return this.boolean() ? numbers : numbers.reverse();
|
||||
}
|
||||
|
||||
complementary1(baseH: Color.Hue): Color.Hue {
|
||||
return this.analogous1((baseH + 180) % 360);
|
||||
}
|
||||
|
||||
complementary(baseH: Color.Hue, count: number): Color.Hue[] {
|
||||
const angle = this.float(180 - this.maxhCompl/2, 180 + this.maxhCompl/2);
|
||||
return this.analogous(baseH + angle, count);
|
||||
}
|
||||
|
||||
triad(baseH: Color.Hue): [Color.Hue, Color.Hue] {
|
||||
const angle = this.float(120 - this.maxhTriad/2, 120 + this.maxhTriad/2);
|
||||
return [baseH - angle, baseH + angle];
|
||||
}
|
||||
|
||||
baseLuma(ld?: LightDark): Color.Luma {
|
||||
if (ld == 'light') {
|
||||
return this.float(this.minlLight, this.maxl);
|
||||
} else if (ld == 'dark') {
|
||||
return this.float(this.minl, this.maxlDark);
|
||||
} else {
|
||||
return this.float(this.minl, this.maxl);
|
||||
}
|
||||
}
|
||||
|
||||
baseChroma(l: Color.Luma): Color.Chroma {
|
||||
if (l >= this.minlLight) {
|
||||
return this.float(this.mincLight, this.maxcLight);
|
||||
} else {
|
||||
return this.float(this.mincDark, this.maxcDark);
|
||||
}
|
||||
}
|
||||
|
||||
baseHue(): Color.Hue { return this.float(360); }
|
||||
|
||||
color(ld?: LightDark): Color.Color {
|
||||
const l = this.baseLuma(ld);
|
||||
const c = this.baseChroma(l);
|
||||
const h = this.baseHue();
|
||||
return Color.oklch(l, c, h);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue