中間色作る。
参考
Google Colab上でhtmlとして動作する。
Google Colabでなくhtmlファイルとして動作させたければ%%htmlを外す。
%%html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>16進数色変換ツール</title>
<style>
#colorDisplay {
width: 300px;
height: 100px;
margin-top: 10px;
}
canvas {
margin-top: 10px;
}
</style>
</head>
<body>
<label for="colorInput">16進数色: #</label>
<input type="text" id="colorInput" placeholder="例:ff5733" oninput="updateColor()">
<div id="colorDisplay"></div>
<div id="rgb"></div>
<div id="hsb"></div>
<div id="cmyk"></div>
<canvas id="combinedCanvas" width="1000" height="600"></canvas><br>
<script>
function hexToRgb(hex) {
let bigint = parseInt(hex, 16);
let r = (bigint >> 16) & 255;
let g = (bigint >> 8) & 255;
let b = bigint & 255;
return [r, g, b];
}
function rgbToHsb(r, g, b) {
let rr = r / 255;
let gg = g / 255;
let bb = b / 255;
let max = Math.max(rr, gg, bb);
let min = Math.min(rr, gg, bb);
let h, s;
let v = max;
let d = max - min;
s = max === 0 ? 0 : d / max;
if (max === min) {
h = 0;
} else {
switch (max) {
case rr: h = (gg - bb) + d * (gg < bb ? 6 : 0); h /= 6; break;
case gg: h = (bb - rr) + d * 2; h /= 6; break;
case bb: h = (rr - gg) + d * 4; h /= 6; break;
}
}
return [h * 360, s * 100, v * 100];
}
function rgbToCmyk(r, g, b) {
let rr = r / 255;
let gg = g / 255;
let bb = b / 255;
let k = 1 - Math.max(rr, gg, bb);
let c = (1 - rr - k) / (1 - k) || 0;
let m = (1 - gg - k) / (1 - k) || 0;
let y = (1 - bb - k) / (1 - k) || 0;
return [c * 100, m * 100, y * 100, k * 100];
}
function hexToHSL(H) {
let r = parseInt(H.substring(1, 3), 16) / 255;
let g = parseInt(H.substring(3, 5), 16) / 255;
let b = parseInt(H.substring(5, 7), 16) / 255;
let max = Math.max(r, g, b),
min = Math.min(r, g, b);
let h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0;
} else {
let d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return [Math.round(h * 360), Math.round(s * 100), Math.round(l * 100)];
}
function hslToHex(h, s, l) {
l /= 100;
const a = s * Math.min(l, 1 - l) / 100;
const f = n => {
const k = (n + h / 30) % 12;
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color).toString(16).padStart(2, '0');
};
return `#${f(0)}${f(8)}${f(4)}`;
}
function updateColor() {
let hex = document.getElementById('colorInput').value;
if (hex.length === 6) {
let [r, g, b] = hexToRgb(hex);
let [h, s, v] = rgbToHsb(r, g, b);
let [c, m, y, k] = rgbToCmyk(r, g, b);
document.getElementById('colorDisplay').style.backgroundColor = `#${hex}`;
document.getElementById('rgb').textContent = `RGB: ${r}, ${g}, ${b}`;
document.getElementById('hsb').textContent = `HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%、${v.toFixed(2)}%`;
document.getElementById('cmyk').textContent = `CMYK: ${c.toFixed(2)}%、${m.toFixed(2)}%、${y.toFixed(2)}%、${k.toFixed(2)}%`;
const compColorHex = complementaryColor(`#${hex}`);
const triadicColors = triadicHarmony(`#${hex}`);
const tetradicColors = tetradicHarmony(`#${hex}`);
const triadicMiddleColors = generateMiddleColors2(triadicColors, 3);
const tetradicMiddleColors = generateMiddleColors2(tetradicColors, 4);
displayAllColorsOnCanvas(`#${hex}`, compColorHex, triadicColors, tetradicColors, triadicMiddleColors, tetradicMiddleColors);
}
}
function generateMiddleColors(colors, numMiddleColors) {
let middleColors = [];
for (let i = 0; i < colors.length; i++) {
let nextColor = colors[(i + 1) % colors.length];
let middle = interpolateColors(colors[i], nextColor, numMiddleColors);
middleColors = middleColors.concat(middle);
}
return middleColors;
}
function generateMiddleColors2(colors, numMiddleColors) {
let allColors = [];
for (let i = 0; i < colors.length; i++) {
allColors.push(colors[i]);
let nextColor = colors[(i + 1) % colors.length];
let middle = interpolateColors(colors[i], nextColor, numMiddleColors);
allColors = allColors.concat(middle);
}
return allColors;
}
function interpolateColors(color1, color2, numSteps) {
let [r1, g1, b1] = hexToRgb(color1.slice(1));
let [r2, g2, b2] = hexToRgb(color2.slice(1));
let steps = [];
for (let i = 1; i <= numSteps; i++) {
let r = Math.round(r1 + (r2 - r1) * (i / (numSteps + 1)));
let g = Math.round(g1 + (g2 - g1) * (i / (numSteps + 1)));
let b = Math.round(b1 + (b2 - b1) * (i / (numSteps + 1)));
steps.push(`#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase()}`);
}
return steps;
}
function displayAllColorsOnCanvas(hex, compColorHex, triadicColors, tetradicColors, triadicMiddleColors, tetradicMiddleColors) {
const canvas = document.getElementById('combinedCanvas');
const ctx = canvas.getContext('2d');
const segmentHeight = canvas.height / 6;
let hindex = 0;
let [r, g, b] = hexToRgb(hex.slice(1));
let [h, s, v] = rgbToHsb(r, g, b);
let [c, m, y, k] = rgbToCmyk(r, g, b);
ctx.fillStyle = `rgb(${r},${g},${b})`;
ctx.fillRect(0, segmentHeight * hindex, canvas.width, segmentHeight);
ctx.fillStyle = 'white';
ctx.font = '12px Arial';
ctx.fillText(`HEX: ${hex}`, 10, segmentHeight * hindex + 20);
ctx.fillText(`RGB: ${r}, ${g}, ${b}`, 10, segmentHeight * hindex + 40);
ctx.fillText(`HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%、${v.toFixed(2)}%`, 10, segmentHeight * hindex + 60);
ctx.fillText(`CMYK: ${c.toFixed(2)}%、${m.toFixed(2)}%、${y.toFixed(2)}%、${k.toFixed(2)}%`, 10, segmentHeight * hindex + 80);
hindex = 1;
[r, g, b] = hexToRgb(compColorHex.slice(1));
[h, s, v] = rgbToHsb(r, g, b);
[c, m, y, k] = rgbToCmyk(r, g, b);
ctx.fillStyle = `rgb(${r},${g},${b})`;
ctx.fillRect(0, segmentHeight * hindex, canvas.width, segmentHeight);
ctx.fillStyle = 'white';
ctx.font = '12px Arial';
ctx.fillText(`HEX: ${compColorHex}`, 10, segmentHeight * hindex + 20);
ctx.fillText(`RGB: ${r}, ${g}, ${b}`, 10, segmentHeight * hindex + 40);
ctx.fillText(`HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%、${v.toFixed(2)}%`, 10, segmentHeight * hindex + 60);
ctx.fillText(`CMYK: ${c.toFixed(2)}%、${m.toFixed(2)}%、${y.toFixed(2)}%、${k.toFixed(2)}%`, 10, segmentHeight * hindex + 80);
hindex = 2;
let segmentWidth = canvas.width / triadicColors.length;
triadicColors.forEach((triadicColor, rindex) => {
[r, g, b] = hexToRgb(triadicColor.slice(1));
[h, s, v] = rgbToHsb(r, g, b);
[c, m, y, k] = rgbToCmyk(r, g, b);
ctx.fillStyle = `rgb(${r},${g},${b})`;
ctx.fillRect(segmentWidth * rindex, segmentHeight * hindex, segmentWidth, segmentHeight);
ctx.fillStyle = 'white';
ctx.font = '12px Arial';
ctx.fillText(`HEX: ${triadicColor}`, segmentWidth * rindex + 10, segmentHeight * hindex + 20);
ctx.fillText(`RGB: ${r}, ${g}, ${b}`, segmentWidth * rindex + 10, segmentHeight * hindex + 40);
ctx.fillText(`HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%、${v.toFixed(2)}%`, segmentWidth * rindex + 10, segmentHeight * hindex + 60);
ctx.fillText(`CMYK: ${c.toFixed(2)}%、${m.toFixed(2)}%、${y.toFixed(2)}%、${k.toFixed(2)}%`, segmentWidth * rindex + 10, segmentHeight * hindex + 80);
});
hindex = 3;
segmentWidth = canvas.width / triadicMiddleColors.length;
triadicMiddleColors.forEach((middleColor, rindex) => {
[r, g, b] = hexToRgb(middleColor.slice(1));
[h, s, v] = rgbToHsb(r, g, b);
[c, m, y, k] = rgbToCmyk(r, g, b);
ctx.fillStyle = `rgb(${r},${g},${b})`;
ctx.fillRect(segmentWidth * rindex, segmentHeight * hindex, segmentWidth, segmentHeight);
ctx.fillStyle = 'white';
ctx.font = '12px Arial';
ctx.fillText(`HEX: ${middleColor}`, segmentWidth * rindex + 10, segmentHeight * hindex + 20);
ctx.fillText(`RGB: ${r}, ${g}, ${b}`, segmentWidth * rindex + 10, segmentHeight * hindex + 40);
ctx.fillText(`HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%、${v.toFixed(2)}%`, segmentWidth * rindex + 10, segmentHeight * hindex + 60);
ctx.fillText(`CMYK: ${c.toFixed(2)}%、${m.toFixed(2)}%、${y.toFixed(2)}%、${k.toFixed(2)}%`, segmentWidth * rindex + 10, segmentHeight * hindex + 80);
});
hindex = 4;
segmentWidth = canvas.width / tetradicColors.length;
tetradicColors.forEach((tetradicColor, rindex) => {
[r, g, b] = hexToRgb(tetradicColor.slice(1));
[h, s, v] = rgbToHsb(r, g, b);
[c, m, y, k] = rgbToCmyk(r, g, b);
ctx.fillStyle = `rgb(${r},${g},${b})`;
ctx.fillRect(segmentWidth * rindex, segmentHeight * hindex, segmentWidth, segmentHeight);
ctx.fillStyle = 'white';
ctx.font = '12px Arial';
ctx.fillText(`HEX: ${tetradicColor}`, segmentWidth * rindex + 10, segmentHeight * hindex + 20);
ctx.fillText(`RGB: ${r}, ${g}, ${b}`, segmentWidth * rindex + 10, segmentHeight * hindex + 40);
ctx.fillText(`HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%、${v.toFixed(2)}%`, segmentWidth * rindex + 10, segmentHeight * hindex + 60);
ctx.fillText(`CMYK: ${c.toFixed(2)}%、${m.toFixed(2)}%、${y.toFixed(2)}%、${k.toFixed(2)}%`, segmentWidth * rindex + 10, segmentHeight * hindex + 80);
});
hindex = 5;
segmentWidth = canvas.width / tetradicMiddleColors.length;
tetradicMiddleColors.forEach((middleColor, rindex) => {
[r, g, b] = hexToRgb(middleColor.slice(1));
[h, s, v] = rgbToHsb(r, g, b);
[c, m, y, k] = rgbToCmyk(r, g, b);
ctx.fillStyle = `rgb(${r},${g},${b})`;
ctx.fillRect(segmentWidth * rindex, segmentHeight * hindex, segmentWidth, segmentHeight);
ctx.fillStyle = 'white';
ctx.font = '12px Arial';
ctx.fillText(`HEX: ${middleColor}`, segmentWidth * rindex + 10, segmentHeight * hindex + 20);
ctx.fillText(`RGB: ${r}, ${g}, ${b}`, segmentWidth * rindex + 10, segmentHeight * hindex + 40);
ctx.fillText(`HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%、${v.toFixed(2)}%`, segmentWidth * rindex + 10, segmentHeight * hindex + 60);
ctx.fillText(`CMYK: ${c.toFixed(2)}%、${m.toFixed(2)}%、${y.toFixed(2)}%、${k.toFixed(2)}%`, segmentWidth * rindex + 10, segmentHeight * hindex + 80);
});
}
function complementaryColor(hex) {
if (!/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(hex)) {
throw new Error('Invalid HEX format');
}
let red = 255 - parseInt(hex.slice(1, 3), 16);
let green = 255 - parseInt(hex.slice(3, 5), 16);
let blue = 255 - parseInt(hex.slice(5, 7), 16);
let compColor = `#${red.toString(16).padStart(2, '0')}${green.toString(16).padStart(2, '0')}${blue.toString(16).padStart(2, '0')}`;
return compColor.toUpperCase();
}
function triadicHarmony(hex) {
return [hex, rotateHue(hex, 120), rotateHue(hex, 240)];
}
function rotateHue(hex, degree) {
let [h, s, l] = hexToHSL(hex);
h = (h + degree) % 360;
return hslToHex(h, s, l);
}
function tetradicHarmony(hex) {
return [hex, rotateHue(hex, 90), rotateHue(hex, 180), rotateHue(hex, 270)];
}
</script>
</body>
</html>
![](https://assets.st-note.com/img/1718283200429-DjDXoRdc7x.png?width=1200)
この記事が気に入ったらサポートをしてみませんか?