HSLA色を白と混合し、Chroma.jsで非アルファHSLに変換します
私はたくさんの色のデザインシステムを持っています。すべての色が他のすべての色と混合され、各組み合わせの色のコントラスト比(CCR)が出力される色のテーブルを作成しました。目標は、アクセスできない色の組み合わせにフラグを立てることです。
Chroma.jsを使用して色を操作し、CCRを出力しています。それは私のHSLで定義された色の大部分で見事に機能します。
私のデザインシステムがアルファチャンネルのある色を使用しているときに問題が発生します。片方または両方が透明な場合に、CCRで色のペアがどのように機能するかを判断するのは問題があります。HSLA色を白と混合またはブレンドしてから、その上でコントラスト機能を実行するために、いくつかの異なる方法を試しています。これが私がしていることの抜粋です:
// 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
結果は、私がまとめたこのグラフィックで視覚化されます。左は2色で、真ん中に重ねてあります。Adobe Illustratorでは、黄褐色の色に25%の透明度を使用し、「通常の」ブレンドモードを使用しました。CSSでも同じことを行い、スクリーンショットを作成してから、Photoshopで結果のカラーミックスを測定しました。右側は、クロマカラー関数の出力です。

Chroma.jsのオプションであると私が理解していることを試しましたが、CCRテストが正確になるように、結果をブラウザー出力に近づけるために他に何ができるのか疑問に思っています。皆さんありがとう。
@GrahamRitchieからの回答のおかげで、私の出力テーブルは次のようになりました。小さな「複合」ラベルは、これらの関数によって生成された色を示していますが、メイン出力は、透明な色を相互に重ね、背景に重ねています。

回答
あなたが言及したライブラリ(Chroma.js)でこれを行う方法はわかりませんが、バニラJavaScript関数が役立つことを願っています。
以下の関数は、正しく機能するために常に不透明な背景色を想定していることに注意してください(したがって、背景RGBと前景RGBA)。
両方ともアルファチャネルを持つ2つの色で作業する必要がある場合は、最初に背景色(前景色として)で機能を実行し、次に2つの色を組み合わせます。
この関数は2つのRGBカラーも組み合わせます。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>