From f49a1617fb23f122bb1197bb770f3897fad3e988 Mon Sep 17 00:00:00 2001 From: Lani Aung Date: Mon, 2 Jun 2025 21:59:10 -0700 Subject: [PATCH] First stabby stab (cherry picked from commit 300e6cec5fb57ef15b7f4339750f58f522e8a799) --- .gitignore | 1 + src/color-converter.ts | 83 ++++++++++++++++++++++++++++++++++++++++++ src/substrate.ts | 78 +++++++++++++++++++++++++++++++++++++++ tsconfig.json | 10 +++++ www/index.html | 10 +++++ 5 files changed, 182 insertions(+) create mode 100644 .gitignore create mode 100644 src/color-converter.ts create mode 100644 src/substrate.ts create mode 100644 tsconfig.json create mode 100644 www/index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..723ef36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/src/color-converter.ts b/src/color-converter.ts new file mode 100644 index 0000000..3104b16 --- /dev/null +++ b/src/color-converter.ts @@ -0,0 +1,83 @@ +export class HSL { + hue: number + saturation: number + lightness: number + + constructor(hue: number, saturation: number, lightness: number) { + this.hue = hue + this.saturation = saturation + this.lightness = lightness + } + + // https://en.wikipedia.org/wiki/RGB_color_model + public static fromRgb(rgb: RGB) { + const redValue = rgb.red / 255, + greenValue = rgb.green / 255, + blueValue = rgb.blue / 255, + lightness = (redValue + greenValue + blueValue) / 3, + saturation = 1 - (3 / (redValue + greenValue + blueValue)) * Math.min(redValue, greenValue, blueValue) + + const dividend = (redValue - greenValue) + (redValue - blueValue) + const divisor = 2 * Math.sqrt((redValue - greenValue) ^ 2 + (redValue - blueValue) * (greenValue - blueValue)) + let hue = (1 / Math.cos(dividend / divisor)) + if (greenValue > blueValue) hue = 360 - hue + + return new HSL(hue, saturation, lightness) + } +} + +export class RGB { + red: number + green: number + blue: number + + constructor(red: number, green: number, blue: number) { + this.red = red + this.green = green + this.blue = blue + } + + // https://en.wikipedia.org/wiki/HSL_and_HSV + public static fromHsl(hsl: HSL): 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, + range = hsl.hue / 60, + intermediate = chroma * (1 - Math.abs(range % 2 - 1)), + match = lightnessValue - chroma / 2 + + if (range >= 0 && range < 1) { + red = chroma + green = intermediate + } else if (range >= 1 && range < 2) { + red = intermediate + green = chroma + } else if (range >= 2 && range < 3) { + green = chroma + blue = intermediate + } else if (range >= 3 && range < 4) { + green = intermediate + blue = chroma + } else if (range >= 4 && range < 5) { + red = intermediate + blue = chroma + } else if (range >= 5 && range < 6) { + red = chroma + blue = intermediate + } + + return new RGB((red + match) * 255, (green + match) * 255, (blue + match) * 255) + } +} + +export enum Schemes { + Analogous, + Monochromatic, + SplitComplementary, + Triadic, + Tetradic, + Square +} \ No newline at end of file diff --git a/src/substrate.ts b/src/substrate.ts new file mode 100644 index 0000000..071cb7d --- /dev/null +++ b/src/substrate.ts @@ -0,0 +1,78 @@ +// TS attempt of http://www.complexification.net/gallery/machines/substrate/index.php by laniaung.me 2025-06-02 +export default class Substrate { + private colors = [ 0x3a1e3e, 0x7c2d3b, 0xb94f3c, 0xf4a462, 0xf9c54e ] // https://colormagic.app/palette/671eeb6c42273fc4c1bb1ac7 + private maxCracks = 20 + + constructor(maxCracks: number) { + this.maxCracks = maxCracks + } +} + +class State { + crackGrid: number[] + height: number + width: number + + constructor(height: number, width: number) { + this.height = height + this.width = width + this.crackGrid = [] + + for (let x = 0; x < width; x++) { + for (let y = 0; y < height; y++) { + this.crackGrid[y * width + x] = 10000 + } + } + + for (let i = 0; i < 16; i++) { + this.crackGrid[Math.floor(Math.random() * (height * width))] = Math.ceil(Math.random() * 360) + } + } +} + +class SandPainter { +} + +class Crack { + private x: number = 0 + private y: number = 0 + private angle: number = 0 + private painter: SandPainter + private state: State + + constructor(state: State) { + this.painter = new SandPainter() + this.state = state + this.init() + } + + init() { + let x = 0, y = 0, found = false, tries = 0 + while (!found && tries++ < 1000) { + x = Math.random() * this.state.width + y = Math.random() * this.state.height + found = this.state.crackGrid[y * this.state.height + x] < 10000 + } + + if (!found) { + console.warn("Unable to start crack due to timeout") + return + } + + const negative = Math.random() < 0.5 + let value = this.state.crackGrid[y * this.state.height + x] + + if (negative) value -= 90 + Math.floor(Math.random() * 4.1 - 2) + else value += 90 + Math.floor(Math.random() * 4.1 - 2) + } + + start(x: number, y: number, angle: number) { + this.x = x + .61 * Math.cos(angle * Math.PI / 180) + this.y = y + .61 * Math.sin(angle * Math.PI / 180) + this.angle = angle + } + + continue() { + + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..3ffa57b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "es2016", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true + } +} diff --git a/www/index.html b/www/index.html new file mode 100644 index 0000000..8468cba --- /dev/null +++ b/www/index.html @@ -0,0 +1,10 @@ + + + + + Weather + + + + + \ No newline at end of file