diff --git a/src/App.svelte b/src/App.svelte index 0c85d92..ede4a3a 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -1,47 +1,13 @@
diff --git a/src/colorUtils.ts b/src/colorUtils.ts new file mode 100644 index 0000000..776aba6 --- /dev/null +++ b/src/colorUtils.ts @@ -0,0 +1,56 @@ +export function randomRgbColor(): number[] { + const r = Math.floor(Math.random() * 255); + const g = Math.floor(Math.random() * 255); + const b = Math.floor(Math.random() * 255); + return [r, g, b]; +} + +export function cmykToRgb(cmyk: number[]): number[] { + return [ + Math.round(255 * (1 - cmyk[0] / 100) * (1 - cmyk[3] / 100)), + Math.round(255 * (1 - cmyk[1] / 100) * (1 - cmyk[3] / 100)), + Math.round(255 * (1 - cmyk[2] / 100) * (1 - cmyk[3] / 100)), + ]; +} + +export function rgbToCmyk(rgb: number[]): number[] { + let r = rgb[0] / 255; + let g = rgb[1] / 255; + let b = rgb[2] / 255; + let k = 1 - Math.max(r, g, b); + let c = Math.round(((1 - r - k) / (1 - k)) * 100); + let m = Math.round(((1 - g - k) / (1 - k)) * 100); + let y = Math.round(((1 - b - k) / (1 - k)) * 100); + return [c || 0, m || 0, y || 0, Math.round(k * 100)]; +} + +export function stringToRgb(input: string): number[] | undefined { + if (input.startsWith("#")) { + let parts = input.match(/([0-f0-F]){2}/g); + if (!parts || parts.length != 3) return undefined; + return parts.map((e) => parseInt(e, 16)); + } else if (input.startsWith("rgb(")) { + let parts = input.match(/[0-9]{1,3}/g); + if (!parts || parts.length != 3) return undefined; + return parts.map((e) => parseInt(e)); + } else if (input.startsWith("cmyk(")) { + let parts = input.match(/[0-9]{1,3}/g); + if (!parts || parts.length != 4) return undefined; + return cmykToRgb(parts.map((e) => parseInt(e))); + } +} + +// From: https://github.com/susam/myrgb/blob/main/myrgb.html#L206 +export function score(rgb1: number[], rgb2: number[]) { + const maxRErr = Math.max(rgb1[0], 15 - rgb1[0]); + const maxGErr = Math.max(rgb1[1], 15 - rgb1[1]); + const maxBErr = Math.max(rgb1[2], 15 - rgb1[2]); + const maxDist = Math.sqrt( + maxRErr * maxRErr + maxGErr * maxGErr + maxBErr * maxBErr + ); + const rErr = Math.abs(rgb2[0] - rgb1[0]); + const gErr = Math.abs(rgb2[1] - rgb1[1]); + const bErr = Math.abs(rgb2[2] - rgb1[2]); + const dist = Math.sqrt(rErr * rErr + gErr * gErr + bErr * bErr); + return Math.max(0, Math.floor(100 * (1 - dist / maxDist))); +}