我想转换一个CSS Lch颜色字符串,比如:
--my-color: lch(20% 8.5 220.0);
转换为RGB十六进制代码。我试着使用像chroma的Lch解析器这样的工具,但所有这些工具似乎都使用第一个纵坐标的绝对值(在我的例子中是20%(。
有没有一些标准的方法可以将这20%转换为大多数Lch转换工具使用的亮度值?
w3c正在起草一份草案,并附上了javascript中的示例代码(在这里发布有点太长,需要更高的数学运算才能做到这一点(至少sin
和2.4
的幂(。
JS原生CanvasRenderingContext2D实例可以读取任何CSS格式的颜色(作为字符串(,并将其写入RGBA缓冲区(0到255(:
const myCssColor = "lch(20% 8.5 220.0)";
function cssColor_to_rgba255Color(string) {
const canvas = document.createElement("canvas");
canvas.width = canvas.height = 1;
const ctx = canvas.getContext("2d", {willReadFrequently: true});
ctx.fillStyle = string;
ctx.fillRect(0, 0, 1, 1);
return ctx.getImageData(0, 0, 1, 1).data;
}
const rgba = cssColor_to_rgba255Color(myCssColor);
console.log( rgba[0], rgba[1], rgba[2], rgba[3] );
// 33 51 56 255
该功能可能具有较差的性能,但可以通过总是回收(使用clearRect(相同的";ctx";对象
我可以给你这个我自己写的函数,从LCH到HEX,或者RGB,如果你愿意的话。我用PHP写的,所以很容易适应任何其他语言
function lch2hex($l, $c, $h) {
$a=round($c*cos(deg2rad($h)));
$b=round($c*sin(deg2rad($h)));
unset($c,$h);
// Reference white values for D65 Light Europe Observer
// $xw = 0.95047;
// $yw = 1.00000;
// $zw = 1.08883;
// Reference white values for CIE 1964 10° Standard Observer
$xw = 0.948110;
$yw = 1.00000;
$zw = 1.07304;
// Compute intermediate values
$fy = ($l + 16) / 116;
$fx = $fy + ($a / 500);
$fz = $fy - ($b / 200);
// Compute XYZ values
$x = round($xw * (($fx ** 3 > 0.008856) ? $fx ** 3 : (($fx - 16 / 116) / 7.787)),5);
$y = round($yw * (($fy ** 3 > 0.008856) ? $fy ** 3 : (($fy - 16 / 116) / 7.787)),5);
$z = round($zw * (($fz ** 3 > 0.008856) ? $fz ** 3 : (($fz - 16 / 116) / 7.787)),5);
unset($l,$a,$b,$xw,$yw,$zw,$fy,$fx,$fz);
$r = $x * 3.2406 - $y * 1.5372 - $z * 0.4986;
$g = -$x * 0.9689 + $y * 1.8758 + $z * 0.0415;
$b = $x * 0.0557 - $y * 0.2040 + $z * 1.0570;
unset($x,$y,$z);
$r = $r > 0.0031308 ? 1.055 * pow($r, 1 / 2.4) - 0.055 : 12.92 * $r;
$g = $g > 0.0031308 ? 1.055 * pow($g, 1 / 2.4) - 0.055 : 12.92 * $g;
$b = $b > 0.0031308 ? 1.055 * pow($b, 1 / 2.4) - 0.055 : 12.92 * $b;
$r = round(max(min($r, 1), 0) * 255);
$g = round(max(min($g, 1), 0) * 255);
$b = round(max(min($b, 1), 0) * 255);
return '#' . sprintf('%02X%02X%02X', $r, $g, $b);
}