此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。
颜色混合器
此工具可通过 color-mix()
函数在任意色彩空间中混合两种颜色,并将混合后的颜色以任何 CSS 颜色格式复制出来。
两个输入颜色 color-one
和 color-two
显示在外侧,函数返回的混合颜色显示在中间。点击外侧色块可选择新的混合颜色。使用滑块调整每种输入颜色的混合比例。通过下拉菜单可更改函数输出的色彩空间。最终生成的颜色值以多种格式呈现于控件下方表格中,可直接复制。点击颜色格式名称可查看详细说明。
<div id="color-mixer">
<div>第一个颜色</div>
<div>混合的颜色</div>
<div>第二个颜色</div>
<div id="color-background">
<button
id="color-one"
type="button"
class="color-one"
aria-label="打开第一个颜色选择器对话框"></button>
<div id="mixed-color"></div>
<button
id="color-two"
type="button"
class="color-two"
aria-label="打开第二个颜色选择器对话框"></button>
</div>
<div>
<label
id="percentage-one-label"
for="percentage-one"
aria-label="第一个颜色的百分比">
50%
</label>
<input id="percentage-one" type="range" name="percent1" step="0.01" />
</div>
<div>
<label
id="percentage-two-label"
for="percentage-two"
aria-label="第二个颜色的百分比">
50%
</label>
<input id="percentage-two" type="range" name="percent2" step="0.01" />
</div>
<label for="color-space">颜色空间</label>
<select id="color-space">
<option value="srgb">sRGB</option>
<option value="srgb-linear">sRGB 线性</option>
<option value="hsl">HSL</option>
<option value="hwb">HWB</option>
<option value="lab">Lab</option>
<option value="lch">LCH</option>
<option value="oklab" selected>Oklab</option>
<option value="oklch">OkLCh</option>
<option value="xyz-d50">XYZ-D50</option>
<option value="xyz-d65">XYZ-D65</option>
</select>
<label id="interpolation-method-label" for="interpolation-method">
色相插值方法:
</label>
<select id="interpolation-method">
<option value="shorter hue" selected>短路径色相插值</option>
<option value="longer hue">长路径色相插值</option>
<option value="increasing hue">色相增加方向</option>
<option value="decreasing hue">色相减少方向</option>
</select>
<div id="mix-output-text"></div>
<dialog id="picker-dialog">
<div>选择一个颜色</div>
<table>
<tr>
<td><label for="color-text">输入颜色:</label></td>
<td><input type="text" id="color-text" value="#bada55" /></td>
</tr>
<tr>
<td><label for="color-input">选择颜色:</label></td>
<td><input type="color" id="color-input" value="#bada55" /></td>
</tr>
<tr>
<td><label for="color-opacity">选择透明度:</label></td>
<td>
<input
type="range"
id="color-opacity"
value="1"
min="0"
max="1"
step="0.01" />
</td>
</tr>
</table>
<div><button id="picker-ok-button">确定</button></div>
</dialog>
</div>
<hr />
<table id="output-colors">
<caption>
不同格式的混合颜色:
</caption>
<tbody>
<tr id="rgb-function">
<th>
<a
href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/color_value/rgb"
target="_blank">
RGB
</a>
</th>
<td><button id="copy-rgb-button">复制</button><span></span></td>
</tr>
<tr id="hex">
<th>
<a
href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/hex-color"
target="_blank"
>HEX</a
>
</th>
<td><button id="copy-hex-button">复制</button><span></span></td>
</tr>
<tr id="hsl-function">
<th>
<a
href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/color_value/hsl"
target="_blank">
HSL
</a>
</th>
<td><button id="copy-hsl-button">复制</button><span></span></td>
</tr>
<tr id="hwb-function">
<th>
<a
href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/color_value/hwb"
target="_blank">
HWB
</a>
</th>
<td><button id="copy-hwb-button">复制</button><span></span></td>
</tr>
<tr id="color-function">
<th>
<a
href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/color_value/color"
target="_blank">
color()
</a>
</th>
<td><button id="copy-color-button">复制</button><span></span></td>
</tr>
<tr id="lab-function">
<th>
<a
href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/color_value/lab"
target="_blank">
Lab
</a>
</th>
<td><button id="copy-lab-button">复制</button><span></span></td>
</tr>
<tr id="lch-function">
<th>
<a
href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/color_value/lch"
target="_blank">
LCH
</a>
</th>
<td><button id="copy-lch-button">复制</button><span></span></td>
</tr>
<tr id="oklab-function">
<th>
<a
href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/color_value/oklab"
target="_blank">
Oklab
</a>
</th>
<td><button id="copy-oklab-button">复制</button><span></span></td>
</tr>
<tr id="oklch-function">
<th>
<a
href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/color_value/oklch"
target="_blank">
OkLCh
</a>
</th>
<td><button id="copy-oklch-button">复制</button><span></span></td>
</tr>
<tr id="xyz-d50-function">
<th>
<a
href="https://developer.mozilla.org/zh-CN/docs/Glossary/Color_space#xyz-d50"
target="_blank">
XYZ D50
</a>
</th>
<td><button id="copy-xyz-d50-button">复制</button><span></span></td>
</tr>
<tr id="xyz-d65-function">
<th>
<a
href="https://developer.mozilla.org/zh-CN/docs/Glossary/Color_space#xyz"
target="_blank">
XYZ D65
</a>
</th>
<td><button id="copy-xyz-d65-button">复制</button><span></span></td>
</tr>
</tbody>
</table>
#picker-dialog[open] {
position: fixed;
top: 30%;
z-index: 100;
padding: 1rem;
width: 70vw;
background: #dddddd;
display: flex;
flex-flow: column;
align-items: center;
}
#picker-dialog #color-opacity {
width: 200px;
}
#picker-dialog > div:first-child {
font-weight: bold;
margin-bottom: 1rem;
}
#picker-dialog > div {
width: max-content;
margin: 0.4rem auto;
white-space: nowrap;
}
#picker-dialog #color-text {
width: 200px;
}
#picker-dialog label {
margin: 1rem 0;
}
#picker-dialog button {
width: 100px;
margin-top: 1rem;
}
dialog#picker-dialog table {
width: fit-content;
}
#color-mixer {
margin: 0.5rem;
font-family: sans-serif;
display: grid;
grid-template-columns: 150px 1fr 1fr 150px;
grid-template-areas:
"color-one-label mix-label mix-label color-two-label"
"color-background color-background color-background color-background"
"percent-one percent-one percent-two percent-two"
"color-space-label color-space interpolation-label interpolation"
"mix-output-text mix-output-text mix-output-text mix-output-text";
}
#color-mixer > * {
padding: 0;
margin: 0 auto;
}
#color-mixer > :nth-child(1) {
grid-area: color-one-label;
}
#color-mixer > :nth-child(2) {
grid-area: mix-label;
}
#color-mixer > :nth-child(3) {
grid-area: color-two-label;
}
#color-mixer > :nth-child(4) {
grid-area: color-background;
background:
linear-gradient(
0deg,
transparent 0 38%,
47%,
rgb(0 0 0 / 0.7) 50%,
white 50% 100%
),
conic-gradient(
black 0 90deg,
transparent 90deg 180deg,
black 180deg 270deg,
transparent 270deg 360deg
);
background-size:
100% 100%,
20px 20px;
display: flex;
align-items: center;
margin: 0;
padding: 0;
border-radius: 10%;
}
#color-one {
height: 100px;
flex: 1 1 100%;
border-radius: 20% 0 0 20%;
cursor: pointer;
border: none;
z-index: 1;
box-shadow: -5px 5px 5px grey;
background-color: coral;
}
#mixed-color {
flex: 2 0.7 100%;
height: 100px;
}
#color-two {
height: 100px;
flex: 1 1 100%;
border-radius: 0 20% 20% 0;
cursor: pointer;
border: none;
z-index: 1;
box-shadow: 5px 5px 5px grey;
background-color: cyan;
}
#color-mixer > :nth-child(5) {
grid-area: percent-one;
width: 100%;
display: flex;
}
#percentage-one-label,
#percentage-two-label {
width: 2rem;
text-align: end;
}
#color-mixer > :nth-child(6) {
grid-area: percent-two;
width: 100%;
display: flex;
}
#color-mixer > :nth-child(7) {
grid-area: color-space-label;
margin: 0.5rem 0 0 auto;
}
#color-mixer > :nth-child(8) {
grid-area: color-space;
margin: 0.5rem auto 0 1rem;
}
#color-mixer > :nth-child(9) {
grid-area: interpolation-label;
margin: 0.5rem 0 0 auto;
}
#color-mixer > :nth-child(10) {
grid-area: interpolation;
margin: 0.5rem auto 0 1rem;
}
#color-mixer > :nth-child(11) {
grid-area: mix-output-text;
margin: 1rem 0;
padding: 1rem 0;
text-align: center;
background-color: #dfdfde;
font-family: monospace;
}
input[type="range"] {
width: 80%;
}
label {
margin: 1rem;
}
*:focus {
outline: 2px dashed purple;
outline-offset: 1px;
}
table {
width: 100%;
}
caption {
font-family: sans-serif;
}
th {
padding: 5px 15px;
background-color: #ededed;
}
td {
background-color: #dedede;
font-family: monospace;
padding: 5px;
}
#output-colors th {
padding-right: 0;
width: 20%;
}
#output-colors td button {
margin-right: 0.4rem;
}
const root = document.querySelector(":root");
const colorSpace = document.getElementById("color-space");
const interpolationMethod = document.getElementById("interpolation-method");
const interpolationMethodLabel = document.getElementById(
"interpolation-method-label",
);
const colorOneButton = document.getElementById("color-one");
const colorTwoButton = document.getElementById("color-two");
const mixedColorDiv = document.getElementById("mixed-color");
const mixedOutputText = document.getElementById("mix-output-text");
const percentageOneLabel = document.getElementById("percentage-one-label");
const percentageTwoLabel = document.getElementById("percentage-two-label");
const percentageOneSlider = document.getElementById("percentage-one");
const percentageTwoSlider = document.getElementById("percentage-two");
// 弹出对话框元素
const pickerDialog = document.getElementById("picker-dialog");
const colorTextInput = document.getElementById("color-text");
const colorInput = document.getElementById("color-input");
const colorOpacitySlider = document.getElementById("color-opacity");
const pickerOkButton = document.getElementById("picker-ok-button");
// 颜色输出 span
const hexOutput = document.querySelector("#hex td > span");
const colorFunctionOutput = document.querySelector("#color-function td > span");
const rgbFunctionOutput = document.querySelector("#rgb-function td > span");
const hslFunctionOutput = document.querySelector("#hsl-function td > span");
const hwbFunctionOutput = document.querySelector("#hwb-function td > span");
const labFunctionOutput = document.querySelector("#lab-function td > span");
const oklabFunctionOutput = document.querySelector("#oklab-function td > span");
const lchFunctionOutput = document.querySelector("#lch-function td > span");
const oklchFunctionOutput = document.querySelector("#oklch-function td > span");
const xyzD50FunctionOutput = document.querySelector(
"#xyz-d50-function td > span",
);
const xyzD65FunctionOutput = document.querySelector(
"#xyz-d65-function td > span",
);
const LRGB_LMS_MATRIX = [
[0.4122214708, 0.5363325363, 0.0514459929],
[0.2119034982, 0.6806995451, 0.1073969566],
[0.0883024619, 0.2817188376, 0.6299787005],
];
const LMS_LAB_MATRIX = [
[+0.2104542553, +0.793617785, -0.0040720468],
[+1.9779984951, -2.428592205, +0.4505937099],
[+0.0259040371, +0.7827717662, -0.808675766],
];
// 从 srgb-linear 转换为 xyz-d50
// 矩阵取自 http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html
const LRGB_XYZ_D50_MATRIX = [
[0.4360747, 0.3850649, 0.1430804],
[0.2225045, 0.7168786, 0.0606169],
[0.0139322, 0.0971045, 0.7141733],
];
// 从 srgb-linear 转换为 xyz-d65
// 矩阵取自 http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html
const LRGB_XYZ_D65_MATRIX = [
[0.4124564, 0.3575761, 0.1804375],
[0.2126729, 0.7151522, 0.072175],
[0.0193339, 0.119192, 0.9503041],
];
const polarColorSpaces = ["hsl", "hwb", "lch", "oklch"];
const colorOne = { r: 255, g: 127, b: 80, alpha: 1.0 };
const colorTwo = { r: 0, g: 255, b: 255, alpha: 1.0 };
let currentColor = null;
function rgbToLinear(c) {
return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
}
function intToHex(i) {
return Math.floor(i).toString(16).padStart(2, "0").toLowerCase();
}
function rgbToHEXText(c) {
return `#${intToHex(c.r)}${intToHex(c.g)}${intToHex(c.b)}`;
}
function colorToRGBA(c) {
const ctx = new OffscreenCanvas(1, 1).getContext("2d");
ctx.fillStyle = c;
ctx.fillRect(0, 0, 1, 1);
const data = ctx.getImageData(0, 0, 1, 1).data;
return {
r: data[0],
g: data[1],
b: data[2],
alpha: data[3] / 255,
};
}
function multiplyByMatrix(matrix, tuple) {
let i = [0, 0, 0];
let j = matrix.length;
let k = matrix[0].length;
for (let l = 0; l < j; l++)
for (let m = 0; m < k; m++) i[l] += matrix[l][m] * tuple[m];
return i;
}
function rgbaToHEXAText(color) {
const hexText = rgbToHEXText(color);
if (color.alpha === 1.0) {
return hexText;
}
const alpha = intToHex(color.alpha * 255);
return `${hexText}${alpha}`;
}
function rgbaToHSLA(color) {
let { r, g, b, alpha } = color;
// r、g、b 需要在范围 [0, 1] 内
r /= 255;
g /= 255;
b /= 255;
const min = Math.min(r, g, b);
const max = Math.max(r, g, b);
const delta = max - min;
let h, s, l;
if (delta === 0) {
h = 0;
} else if (max === r) {
h = ((g - b) / delta) % 6;
} else if (max === g) {
h = (b - r) / delta + 2;
} else h = (r - g) / delta + 4;
h = Math.round(h * 60);
// 需要一个 0 到 360° 之间的角度
if (h < 0) {
h += 360;
}
l = (max + min) / 2;
s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
s = Number((s * 100).toFixed(1));
l = Number((l * 100).toFixed(1));
return { h, s, l, alpha };
}
function toHSLAText(color) {
const { h, s, l, alpha } = rgbaToHSLA(color);
return `hsl(${h.toFixed(0)} ${s.toFixed(0)}% ${l.toFixed(0)}%${
alpha < 1.0 ? ` / ${alpha.toFixed(3)}` : ""
})`;
}
function rgbaToHWBAText(color) {
let { h, s, l, alpha } = rgbaToHSLA(color);
const chroma = s * (1 - Math.abs(l / 50 - 1));
let W = (l - chroma / 2).toFixed(0);
let B = (100 - l - chroma / 2).toFixed(0);
return `hwb(${h} ${W}% ${B}%${alpha < 1.0 ? ` / ${alpha.toFixed(3)}` : ""})`;
}
function rgbaToXYZD50(color) {
let { r, g, b, alpha } = color;
r = rgbToLinear(r / 255) * 255;
g = rgbToLinear(g / 255) * 255;
b = rgbToLinear(b / 255) * 255;
const xyz = multiplyByMatrix(LRGB_XYZ_D50_MATRIX, [r, g, b]);
return { x: xyz[0] / 255, y: xyz[1] / 255, z: xyz[2] / 255, alpha };
}
function rgbaToXYZD50Text(color) {
let { alpha } = color;
const xyz = rgbaToXYZD50(color);
return `color(xyz-d50 ${xyz.x.toFixed(5)} ${xyz.y.toFixed(5)} ${xyz.z.toFixed(
5,
)}${alpha < 1.0 ? ` / ${alpha.toFixed(3)}` : ""})`;
}
function rgbaToXYZD65(color) {
let { r, g, b, alpha } = color;
r = rgbToLinear(r / 255) * 255;
g = rgbToLinear(g / 255) * 255;
b = rgbToLinear(b / 255) * 255;
const xyz = multiplyByMatrix(LRGB_XYZ_D65_MATRIX, [r, g, b]);
return { x: xyz[0] / 255, y: xyz[1] / 255, z: xyz[2] / 255, alpha };
}
function rgbaToXYZD65Text(color) {
let { alpha } = color;
const xyz = rgbaToXYZD65(color);
return `color(xyz-d65 ${xyz.x.toFixed(5)} ${xyz.y.toFixed(5)} ${xyz.z.toFixed(
5,
)}${alpha < 1.0 ? ` / ${alpha.toFixed(3)}` : ""})`;
}
const D65 = [0.3457 / 0.3585, 1, 0.2958 / 0.3585];
function xyzToLab(color) {
let { x, y, z, alpha } = color;
[x, y, z] = [x, y, z].map((v, i) => {
v /= D65[i];
return v > 0.0088564516 ? Math.cbrt(v) : v * 903.2962962962963 + 16 / 116;
});
return { l: 116 * y - 16, a: 500 * (x - y), b: 200 * (y - z), alpha };
}
function rgbaToLabText(color) {
let { alpha } = color;
const xyz = rgbaToXYZD50(color);
const lab = xyzToLab(xyz);
return `lab(${lab.l.toFixed(3)} ${lab.a.toFixed(3)} ${lab.b.toFixed(3)}${
alpha < 1.0 ? ` / ${alpha.toFixed(3)}` : ""
})`;
}
function rgbToOklab(color) {
let { r, g, b, alpha } = color;
r = rgbToLinear(r / 255);
g = rgbToLinear(g / 255);
b = rgbToLinear(b / 255);
const lms = multiplyByMatrix(LRGB_LMS_MATRIX, [r, g, b]).map((v) =>
Math.cbrt(v),
);
const oklab = multiplyByMatrix(LMS_LAB_MATRIX, lms);
return { l: oklab[0], a: oklab[1], b: oklab[2], alpha };
}
function toOkLabText(color) {
let { alpha } = color;
const oklab = rgbToOklab(color);
return `oklab(${oklab.l.toFixed(5)} ${oklab.a.toFixed(5)} ${oklab.b.toFixed(
5,
)}${alpha < 1.0 ? ` / ${alpha.toFixed(3)}` : ""})`;
}
function labToLCH(color) {
const { l, a, b, alpha } = color;
const c = Math.sqrt(a * a + b * b);
let h = Math.atan2(b, a) * (180 / Math.PI);
if (h < 0) {
h += 360;
}
return { l, c, h, alpha };
}
function toLCHText(color) {
let { alpha } = color;
const xyz = rgbaToXYZD50(color);
const lab = xyzToLab(xyz);
const lch = labToLCH(lab);
return `lch(${lch.l.toFixed(3)} ${lch.c.toFixed(3)} ${lch.h.toFixed(3)}${
alpha < 1.0 ? ` / ${alpha.toFixed(3)}` : ""
})`;
}
function rgbaToOkLCh(color) {
const lab = rgbToOklab(color);
const oklch = labToLCH(lab);
return { l: oklch.l, c: oklch.c, h: oklch.h, alpha: color.alpha };
}
function toOkLChText(color) {
let { alpha } = color;
const oklch = rgbaToOkLCh(color);
return `oklch(${oklch.l.toFixed(5)} ${oklch.c.toFixed(5)} ${oklch.h.toFixed(
5,
)}${alpha < 1.0 ? ` / ${alpha.toFixed(3)}` : ""})`;
}
function updateColorMix() {
let colorMixFunction = "color-mix(in ";
root.style.setProperty("--color-space", colorSpace.value);
colorMixFunction += colorSpace.value;
if (polarColorSpaces.includes(colorSpace.value)) {
root.style.setProperty("--interpolation-method", interpolationMethod.value);
colorMixFunction += ` ${interpolationMethod.value}, `;
} else {
root.style.setProperty("--interpolation-method", "");
colorMixFunction += `, `;
}
root.style.setProperty(
"--color-one",
colorOneButton.style.getPropertyValue("background-color"),
);
root.style.setProperty("--percentage-one", `${percentageOneSlider.value}%`);
colorMixFunction += `${rgbaToHEXAText(colorOne)} ${
percentageOneSlider.value
}%, `;
root.style.setProperty(
"--color-two",
colorTwoButton.style.getPropertyValue("background-color"),
);
root.style.setProperty("--percentage-two", `${percentageTwoSlider.value}%`);
colorMixFunction += `${rgbaToHEXAText(colorTwo)} ${
percentageTwoSlider.value
}%)`;
mixedColorDiv.style.setProperty("background-color", colorMixFunction);
mixedOutputText.innerText = colorMixFunction;
displayOutputColors(window.getComputedStyle(mixedColorDiv).backgroundColor);
}
function displayOutputColors(color) {
let rgbaColor = colorToRGBA(color);
hexOutput.innerText = rgbaToHEXAText(rgbaColor);
rgbFunctionOutput.innerText = `rgb(${Math.round(rgbaColor.r)} ${Math.round(
rgbaColor.g,
)} ${Math.round(rgbaColor.b)}`;
if (rgbaColor.alpha && rgbaColor.alpha < 1.0) {
rgbFunctionOutput.innerText += ` / ${rgbaColor.alpha.toFixed(3)}`;
}
rgbFunctionOutput.innerText += `)`;
colorFunctionOutput.innerText = `color(srgb ${(rgbaColor.r / 255).toFixed(
3,
)} ${(rgbaColor.g / 255).toFixed(3)} ${(rgbaColor.b / 255).toFixed(3)}`;
if (rgbaColor.alpha && rgbaColor.alpha < 1.0) {
colorFunctionOutput.innerText += ` / ${rgbaColor.alpha.toFixed(3)}`;
}
colorFunctionOutput.innerText += `)`;
hslFunctionOutput.innerText = toHSLAText(rgbaColor);
hwbFunctionOutput.innerText = rgbaToHWBAText(rgbaColor);
labFunctionOutput.innerText = rgbaToLabText(rgbaColor);
xyzD50FunctionOutput.innerText = rgbaToXYZD50Text(rgbaColor);
xyzD65FunctionOutput.innerText = rgbaToXYZD65Text(rgbaColor);
lchFunctionOutput.innerText = toLCHText(rgbaColor);
oklabFunctionOutput.innerText = toOkLabText(rgbaColor);
oklchFunctionOutput.innerText = toOkLChText(rgbaColor);
}
function setColorToDialog() {
colorTextInput.value = rgbaToHEXAText(currentColor);
colorInput.value = rgbToHEXText(currentColor);
colorOpacitySlider.value = currentColor.alpha;
}
function init() {
percentageOneSlider.addEventListener("input", (e) => {
percentageOneLabel.innerText = `${e.target.value}%`;
updateColorMix();
});
percentageTwoSlider.addEventListener("input", (e) => {
percentageTwoLabel.innerText = `${e.target.value}%`;
updateColorMix();
});
colorSpace.addEventListener("change", (e) => {
if (polarColorSpaces.includes(e.target.value)) {
interpolationMethod.style.visibility = "visible";
interpolationMethodLabel.style.visibility = "visible";
} else {
interpolationMethod.style.visibility = "hidden";
interpolationMethodLabel.style.visibility = "hidden";
}
updateColorMix();
});
interpolationMethod.addEventListener("change", () => {
updateColorMix();
});
interpolationMethod.style.visibility = "hidden";
interpolationMethodLabel.style.visibility = "hidden";
colorOneButton.addEventListener("click", () => {
currentColor = colorOne;
setColorToDialog();
pickerDialog.showModal();
});
colorTwoButton.addEventListener("click", () => {
currentColor = colorTwo;
setColorToDialog();
pickerDialog.showModal();
});
colorTextInput.addEventListener("input", (e) => {
const color = colorToRGBA(e.target.value);
Object.assign(currentColor, color);
colorInput.value = rgbToHEXText(currentColor);
colorOpacitySlider.value = currentColor.alpha;
});
colorInput.addEventListener("input", (e) => {
const text = e.target.value;
currentColor.r = parseInt(text.slice(1, 3), 16);
currentColor.g = parseInt(text.slice(3, 5), 16);
currentColor.b = parseInt(text.slice(5, 7), 16);
colorTextInput.value = rgbaToHEXAText(currentColor);
colorOpacitySlider.value = currentColor.alpha;
});
colorOpacitySlider.addEventListener("input", (e) => {
const value = parseFloat(e.target.value);
if (value >= 0 && value <= 1) {
currentColor.alpha = value;
colorTextInput.value = rgbaToHEXAText(currentColor);
}
});
pickerOkButton.addEventListener("click", () => {
colorOneButton.style.setProperty(
"background-color",
rgbaToHEXAText(colorOne),
);
colorTwoButton.style.setProperty(
"background-color",
rgbaToHEXAText(colorTwo),
);
pickerDialog.close();
updateColorMix();
});
document.querySelectorAll("#output-colors button").forEach((button) => {
button.addEventListener("click", (e) => {
const text = e.target.nextElementSibling.innerText;
navigator.clipboard.writeText(text);
e.target.innerText = "Copied!";
setTimeout(() => {
e.target.innerText = "Copy";
}, 1000);
});
});
updateColorMix();
}
init();