Working substrate backgrounds

This commit is contained in:
Lani Aung
2025-06-07 18:40:04 -07:00
parent 660dd859d1
commit 28610b0c3b
9 changed files with 128 additions and 92 deletions
+11 -6
View File
@@ -1,22 +1,27 @@
import HSL from "./hsl"
abstract class Scheme {
export abstract class Scheme {
protected primary: HSL
colors: number[]
protected constructor(initial: number) {
this.primary = HSL.fromHex(initial)
}
colors: number[]
toString(): string {
let values = this.colors.map(color => color.toString(16)).join(",")
return `${this.constructor.name}: ${values}`
}
}
export class Analogous extends Scheme {
constructor(initial: number) {
super(initial)
const left1 = new HSL(this.primary.hue - 60, this.primary.saturation, this.primary.lightness)
const left2 = new HSL(this.primary.hue - 30, this.primary.saturation, this.primary.lightness)
const right1 = new HSL(this.primary.hue + 30, this.primary.saturation, this.primary.lightness)
const right2 = new HSL(this.primary.hue + 60, this.primary.saturation, this.primary.lightness)
const left1 = new HSL(this.primary.hue - 30, this.primary.saturation, this.primary.lightness)
const left2 = new HSL(this.primary.hue - 15, this.primary.saturation, this.primary.lightness)
const right1 = new HSL(this.primary.hue + 15, this.primary.saturation, this.primary.lightness)
const right2 = new HSL(this.primary.hue + 30, this.primary.saturation, this.primary.lightness)
this.colors = [
left1.toHex(),
+6 -8
View File
@@ -6,13 +6,13 @@ export default class RGB {
blue: number
constructor(red: number, green: number, blue: number) {
this.red = red
this.green = green
this.blue = blue
this.red = Math.floor(red < 0 ? 0 : red > 255 ? 255 : red)
this.green = Math.floor(green < 0 ? 0 : green > 255 ? 255 : green)
this.blue = Math.floor(blue < 0 ? 0 : blue > 255 ? 255 : blue)
}
toHex(): number {
return this.red << 16 + this.green << 8 + this.blue
return (this.red << 16) + (this.green << 8) + this.blue
}
// https://en.wikipedia.org/wiki/HSL_and_HSV
@@ -20,12 +20,10 @@ export default class RGB {
let red = 0,
green = 0,
blue = 0
const saturationValue = hsl.saturation / 100,
lightnessValue = hsl.lightness / 100,
chroma = 1 - Math.abs(2 * hsl.lightness - 1) * saturationValue,
const chroma = (1 - Math.abs(2 * hsl.lightness - 1)) * hsl.saturation,
range = hsl.hue / 60,
intermediate = chroma * (1 - Math.abs(range % 2 - 1)),
match = lightnessValue - chroma / 2
match = hsl.lightness - chroma / 2
if (range >= 0 && range < 1) {
red = chroma
+1 -1
View File
@@ -7,7 +7,7 @@ export default class SandPainter {
constructor(crack: Crack) {
this.crack = crack
this.color = this.crack.state.getRandomColor()
this.color = this.crack.state.getNextColor()
this.gain = Math.random() / 10
}
+6 -4
View File
@@ -2,17 +2,18 @@ import Crack from "./crack"
export default class State {
readonly canvas: HTMLCanvasElement
colors: number[]
readonly maxCracks: number
readonly grid: number[][]
colors: number[]
seeds: {x: number, y: number}[]
cracks: Crack[]
colorIndex: number = 0
constructor(colors: number[], maxCracks: number, canvas: HTMLCanvasElement) {
this.canvas = canvas
this.colors = colors
this.maxCracks = maxCracks
this.grid = []
this.colors = colors
this.cracks = []
this.seeds = []
@@ -24,6 +25,7 @@ export default class State {
this.cracks.length = 0
this.grid.length = 0
this.seeds.length = 0
this.colorIndex = 0
const height = this.canvas.height
const width = this.canvas.width
@@ -55,8 +57,8 @@ export default class State {
this.cracks.push(new Crack(this, x, y, angle))
}
getRandomColor(): number {
return this.colors[Math.floor(Math.random() * this.colors.length)]
getNextColor(): number {
return this.colors[this.colorIndex++ % this.colors.length]
}
isWithinBoundary(x: number, y: number): boolean {
+17 -8
View File
@@ -1,6 +1,6 @@
// TS attempt of http://www.complexification.net/gallery/machines/substrate/index.php by laniaung.me
import State from "./state"
import {Analogous, Monochromatic, SplitComplementary, Square, Tetradic, Triadic} from "./color-schemes"
import {Scheme, Analogous, Monochromatic, SplitComplementary, Square, Tetradic, Triadic} from "./color-schemes"
export default class Substrate {
private readonly state: State
@@ -24,25 +24,34 @@ export default class Substrate {
requestAnimationFrame(draw)
}
setInterval(() => me.state.init(me.getRandomColorScheme()), 30 * 1000)
setInterval(() => me.state.init(me.getRandomColorScheme()), 120 * 1000)
draw()
}
getRandomColorScheme(): number[] {
const color = Math.floor(Math.random() * Math.pow(256, 3))
let scheme: Scheme
switch (Math.floor(Math.random() * 6)) {
case 1:
return new Monochromatic(color).colors
scheme = new Monochromatic(color)
break;
case 2:
return new SplitComplementary(color).colors
scheme = new SplitComplementary(color)
break;
case 3:
return new Triadic(color).colors
scheme = new Triadic(color)
break;
case 4:
return new Tetradic(color).colors
scheme = new Tetradic(color)
break;
case 5:
return new Square(color).colors
scheme = new Square(color)
break;
default:
return new Analogous(color).colors
scheme = new Analogous(color)
}
console.info(scheme.toString())
return scheme.colors
}
}