34 lines
1.2 KiB
JavaScript
34 lines
1.2 KiB
JavaScript
import {calcAPCA} from './apca-w3.js';
|
|
import { formatHex, converter} from './culori.mjs';
|
|
import {nearestNamedColors} from './color-picker.js';
|
|
|
|
export function find_contrast(col_a, col_b, target_contrast=90, num_close_colours=1, temp=0.1) {
|
|
const [bname] = nearestNamedColors(col_b,1);
|
|
let tcol_b = col_b;
|
|
function score(c) {
|
|
return Math.abs(c - target_contrast);
|
|
}
|
|
for(let j=0;j<30;j++) {
|
|
const possibles = [];
|
|
for(let i =0; i<50; i++) {
|
|
const {l, a, b} = tcol_b;
|
|
const [nl, na, nb] = [l,a,b].map(x=>x+(Math.random()*2-1)*temp);
|
|
const ncol = {mode: 'oklab', l: nl, a: na, b: nb};
|
|
const names = nearestNamedColors(culori.oklab(formatHex(ncol)),num_close_colours);
|
|
if(!names.some(name => name==bname)) {
|
|
continue;
|
|
}
|
|
const contrast = Math.abs(calcAPCA(formatHex(col_a), formatHex(ncol)));
|
|
possibles.push({ncol, contrast});
|
|
}
|
|
if(possibles.length==0) {
|
|
continue;
|
|
}
|
|
const [best] = possibles.sort((a,b) => {const ca = score(a.contrast); const cb = score(b.contrast); return ca<cb ? -1 : 1});
|
|
tcol_b = best.ncol;
|
|
temp *= 0.9;
|
|
}
|
|
const [{name}] = nearestNamedColors(tcol_b,1);
|
|
return tcol_b;
|
|
}
|
|
|