weed-sim / src /shared /color.ts
Yufok1
Checkpoint Devvit v0.0.26
616ae7b
Raw
History Blame Contribute Delete
2.47 kB
import type { ColorAlleles, Hsv, Rgb } from './types';
export function clampByte(value: number): number {
return Math.max(0, Math.min(255, Math.trunc(value)));
}
export function hsvToRgb(hueDeg: number, saturation: number, value: number): Rgb {
const h = (((hueDeg % 360) + 360) % 360) / 60;
const c = value * saturation;
const x = c * (1 - Math.abs((h % 2) - 1));
const m = value - c;
let r = 0;
let g = 0;
let b = 0;
if (h < 1) {
r = c;
g = x;
} else if (h < 2) {
r = x;
g = c;
} else if (h < 3) {
g = c;
b = x;
} else if (h < 4) {
g = x;
b = c;
} else if (h < 5) {
r = x;
b = c;
} else {
r = c;
b = x;
}
return [
clampByte((r + m) * 255),
clampByte((g + m) * 255),
clampByte((b + m) * 255),
];
}
export function rgbToHsv(rgb: Rgb): Hsv {
const [r, g, b] = rgb.map((channel) => channel / 255) as Rgb;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const delta = max - min;
let hue = 0;
if (delta !== 0) {
if (max === r) {
hue = 60 * (((g - b) / delta) % 6);
} else if (max === g) {
hue = 60 * ((b - r) / delta + 2);
} else {
hue = 60 * ((r - g) / delta + 4);
}
}
return [((hue % 360) + 360) % 360, max === 0 ? 0 : delta / max, max];
}
export function expressedRgbFromAlleles(hsvAlleles: ColorAlleles): Rgb {
const hue = (hsvAlleles.Hue[0] + hsvAlleles.Hue[1]) / 2;
const saturation = (hsvAlleles.Saturation[0] + hsvAlleles.Saturation[1]) / 2;
const value = (hsvAlleles.Value[0] + hsvAlleles.Value[1]) / 2;
return hsvToRgb(hue, saturation, value);
}
export function derivePlantColor(budRgb: Rgb, leafRgb: Rgb): Rgb {
const bud = rgbToHsv(budRgb);
const leaf = rgbToHsv(leafRgb);
return hsvToRgb(
(bud[0] + leaf[0]) / 2,
(bud[1] + leaf[1]) / 2,
(bud[2] + leaf[2]) / 2
);
}
export function hueFromRgb(rgb: Rgb): number {
return Math.round(rgbToHsv(rgb)[0] * 10) / 10;
}
export function vibrance(rgb: Rgb): number {
const [red, green, blue] = rgb;
return Math.round(((Math.max(red, green, blue) - Math.min(red, green, blue)) / 255) * 1000) / 10;
}
export function colorFamily(hue: number): string {
if (hue < 15 || hue >= 330) return 'red';
if (hue < 40) return 'orange';
if (hue < 70) return 'yellow';
if (hue < 160) return 'green';
if (hue < 200) return 'cyan';
if (hue < 260) return 'blue';
if (hue < 290) return 'purple';
return 'magenta';
}