Misture uma cor HSLA com branco e converta para HSL não alfa com Chroma.js
Eu tenho um sistema de design com muitas, muitas cores. Eu criei uma tabela de cores onde todas as cores são misturadas com todas as outras cores e a taxa de contraste de cor (CCR) de cada combinação é produzida. O objetivo é sinalizar combinações de cores inacessíveis.
Estou usando o Chroma.js para manipular as cores e gerar os CCRs. Funciona de forma brilhante com a maioria das minhas cores definidas em HSL.
O problema surge quando meu sistema de design usa uma cor com um canal alfa. Determinar o desempenho de um par de cores com CCR quando uma ou ambas são transparentes é problemático. Estou tentando algumas coisas diferentes para misturar ou mesclar uma cor HSLA com branco e, em seguida, executar a função de contraste nisso. Aqui está um trecho do que estou fazendo:
// where either foreground or background has an alpha value present less than 1
var background = chroma.mix(background, '#fff', 1, 'lab').css();
var foreground = chroma.mix(foreground, background, 1, 'lab').css();
var ccr = chroma.contrast(foreground, background);
// lab gets the closest but not the same as the way CSS overlays colors
Os resultados são visualizados com este gráfico que montei. À esquerda estão duas cores com uma sobreposição delas no meio. No Adobe Illustrator, usei 25% de transparência na cor bronzeada e um modo de mesclagem "normal". Fiz o mesmo em CSS e, em seguida, fiz uma captura de tela e medi a mistura de cores resultante no Photoshop. À direita estão as saídas das funções de cor Chroma:

Depois de tentar o que entendi serem as opções em Chroma.js, estou me perguntando o que mais posso tentar para obter meus resultados mais próximos da saída do navegador para que meus testes de CCR sejam precisos. Obrigado a todos.
Graças à resposta aceita de @GrahamRitchie, minha tabela de saída agora se parece com isso. Os pequenos rótulos "compostos" mostram as cores que foram produzidas por essas funções, enquanto a saída principal ainda sobrepõe as cores transparentes umas sobre as outras e sobre o fundo.

Respostas
Não sei como fazer isso com a biblioteca que você mencionou (Chroma.js), mas espero que uma função JavaScript vanilla ajude.
Observe que a função abaixo sempre assume uma cor de fundo opaca para funcionar corretamente (portanto RGB de fundo e RGBA de primeiro plano).
Se você precisar trabalhar com 2 cores com canais alfa, você executará a função na cor de fundo primeiro (como a cor de primeiro plano) com um fundo branco e, em seguida, combinará as duas cores.
A função também combinará duas cores RGB, simplesmente omita o canal alfa ao passar sua cor RGB ( convertToRGB({r,g,b}, {r,g,b})
)
function convertToRGB(frontRGBA, backgroundRGB){
var rtrn = {};
//allows the function to just accept a front colour and assume the background is a plain white.
backgroundRGB = backgroundRGB || {r:255,g:255,b:255};
//allows a RGB value to be passed in assuming full alpha channel.
frontRGBA.a = frontRGBA.a || 1;
//normalise the alpha channel across the foreground and background.
rtrn.r = ((1 - frontRGBA.a) * backgroundRGB.r) + (frontRGBA.a * frontRGBA.r);
rtrn.g = ((1 - frontRGBA.a) * backgroundRGB.g) + (frontRGBA.a * frontRGBA.g);
rtrn.b = ((1 - frontRGBA.a) * backgroundRGB.b) + (frontRGBA.a * frontRGBA.b);
//just check that we don't end up with a value greater than 255 for any channel.
rtrn.r = (rtrn.r > 255) ? 255 : rtrn.r;
rtrn.g = (rtrn.g > 255) ? 255 : rtrn.g;
rtrn.b = (rtrn.b > 255) ? 255 : rtrn.b;
return rtrn;
}
var backgroundRGB = {r:165,g:193,b:211};
var frontRGBA = {r:210,g:203,b:178,a:0.25};
//used for example
var rgb = convertToRGB(frontRGBA, backgroundRGB);
document.querySelector(".output").style.background = "rgb(" + rgb.r + "," + rgb.g + "," + rgb.b + ")";
document.querySelector(".output").innerHTML = "Output<br/>R:" + rgb.r + "<br/>G:" + rgb.g + "<br/>B:" + rgb.b;
.container div{
width: 200px;
height: 200px;
float: left;
}
.div1{
background: rgba(165,193,211,1);
}
.div2{
background: rgba(210,203,178,0.25);
}
<div class="container">
<div class="div1">Background<br/>R:165<br/>G:193<br/>B:211<br/>A:1</div>
<div class="output">Output</div>
<div class="div2">Foreground<br/>R:210<br/>G:203<br/>B:178<br/>A:0.25</div>
</div>