ウェブカラー

基本的にChatGPT4くんまかせです。


前回


表示用プログラム

16進数で入力すると表示してくれるやつ。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>16進数色変換ツール</title>
</head>
<body>
    <label for="colorInput">16進数色: #</label>
    <input type="text" id="colorInput" placeholder="例:ff5733" oninput="updateColor()">
    <div id="colorDisplay" style="width:300px; height:100px;"></div>
    <div id="rgb"></div>
    <div id="hsb"></div>
    <!-- 注意: CMYK変換は近似的です -->
    <div id="cmyk"></div>
    <canvas id="colorCanvas" width="600" height="200"></canvas>
</body>
<script src="main.js"></script>
</html>

main.js

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 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)}%`;
        
        displayColorImage(r, g, b, h, s, v, c, m, y, k);
    }
}

function displayColorImage(r, g, b, h, s, v, c, m, y, k) {
    const canvas = document.getElementById('colorCanvas');
    const ctx = canvas.getContext('2d');

    // 背景色の設定
    ctx.fillStyle = `rgb(${r},${g},${b})`;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // テキストの設定
    ctx.fillStyle = 'white'; // or any contrasting color to the chosen color
    ctx.font = '20px Arial';
    ctx.fillText(`RGB: ${r}, ${g}, ${b}`, 10, 30);    
    ctx.fillText(`HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%, ${v.toFixed(2)}%`, 10, 60);
    ctx.fillText(`CMYK: ${c.toFixed(2)}%, ${m.toFixed(2)}%, ${y.toFixed(2)}%, ${k.toFixed(2)}%`, 10, 90);
}


Google Colab(htmlそのままver)

from IPython.core.display import display, HTML

html_code = """
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>16進数色変換ツール</title>
</head>
<body>
    <label for="colorInput">16進数色: #</label>
    <input type="text" id="colorInput" placeholder="例:ff5733" oninput="updateColor()">
    <div id="colorDisplay" style="width:300px; height:100px;"></div>
    <div id="rgb"></div>
    <div id="hsb"></div>
    <!-- 注意: CMYK変換は近似的です -->
    <div id="cmyk"></div>
    <canvas id="colorCanvas" width="600" height="200"></canvas>
    <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 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)}%`;

                displayColorImage(r, g, b, h, s, v, c, m, y, k);
            }
        }

        function displayColorImage(r, g, b, h, s, v, c, m, y, k) {
            const canvas = document.getElementById('colorCanvas');
            const ctx = canvas.getContext('2d');

            // 背景色の設定
            ctx.fillStyle = `rgb(${r},${g},${b})`;
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            // テキストの設定
            ctx.fillStyle = 'white'; // or any contrasting color to the chosen color
            ctx.font = '20px Arial';
            ctx.fillText(`RGB: ${r}, ${g}, ${b}`, 10, 30);    
            ctx.fillText(`HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%, ${v.toFixed(2)}%`, 10, 60);
            ctx.fillText(`CMYK: ${c.toFixed(2)}%, ${m.toFixed(2)}%, ${y.toFixed(2)}%, ${k.toFixed(2)}%`, 10, 90);
        }
    </script>
</body>
</html>
"""

display(HTML(html_code))

%%html

%%html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>16進数色変換ツール</title>
</head>
<body>
    <label for="colorInput">16進数色: #</label>
    <input type="text" id="colorInput" placeholder="例:ff5733" oninput="updateColor()">
    <div id="colorDisplay" style="width:300px; height:100px;"></div>
    <div id="rgb"></div>
    <div id="hsb"></div>
    <!-- 注意: CMYK変換は近似的です -->
    <div id="cmyk"></div>
    <canvas id="colorCanvas" width="600" height="200"></canvas>
    <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 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)}%`;

                displayColorImage(r, g, b, h, s, v, c, m, y, k);
            }
        }

        function displayColorImage(r, g, b, h, s, v, c, m, y, k) {
            const canvas = document.getElementById('colorCanvas');
            const ctx = canvas.getContext('2d');

            // 背景色の設定
            ctx.fillStyle = `rgb(${r},${g},${b})`;
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            // テキストの設定
            ctx.fillStyle = 'white'; // or any contrasting color to the chosen color
            ctx.font = '20px Arial';
            ctx.fillText(`RGB: ${r}, ${g}, ${b}`, 10, 30);    
            ctx.fillText(`HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%, ${v.toFixed(2)}%`, 10, 60);
            ctx.fillText(`CMYK: ${c.toFixed(2)}%, ${m.toFixed(2)}%, ${y.toFixed(2)}%, ${k.toFixed(2)}%`, 10, 90);
        }
    </script>
</body>
</html>

Google Colab(Python移植)

!pip install ipywidgets
import ipywidgets as widgets
from IPython.display import display, HTML
import matplotlib.pyplot as plt
import numpy as np




def hex_to_rgb(hex):
    hex = hex.lstrip('#')
    return tuple(int(hex[i:i+2], 16) for i in (0, 2, 4))

def rgb_to_hsb(r, g, b):
    r, g, b = r / 255.0, g / 255.0, b / 255.0
    max_c = max(r, g, b)
    min_c = min(r, g, b)
    delta = max_c - min_c
    h = s = v = max_c

    if max_c != min_c:
        if max_c == r:
            h = (g - b) / delta + (6 if g < b else 0)
        elif max_c == g:
            h = (b - r) / delta + 2
        elif max_c == b:
            h = (r - g) / delta + 4
        h /= 6
    s = 0 if max_c == 0 else delta / max_c
    v = max_c

    return h * 360, s * 100, v * 100

def rgb_to_cmyk(r, g, b):
    if (r == 0) and (g == 0) and (b == 0):
        return 0, 0, 0, 100

    c = 1 - r / 255
    m = 1 - g / 255
    y = 1 - b / 255
    k = min(c, m, y)
    c = (c - k) / (1 - k) * 100
    m = (m - k) / (1 - k) * 100
    y = (y - k) / (1 - k) * 100
    k = k * 100

    return c, m, y, k


color_input = widgets.Text(
    value='ff5733',
    placeholder='例:ff5733',
    description='16進数色: #',
)

rgb_output = widgets.Label(value="")
hsb_output = widgets.Label(value="")
cmyk_output = widgets.Label(value="")

def update_color(change):
    hex_color = color_input.value
    if len(hex_color) == 6:
        r, g, b = hex_to_rgb(hex_color)
        h, s, v = rgb_to_hsb(r, g, b)
        c, m, y, k = rgb_to_cmyk(r, g, b)

        rgb_output.value = f"RGB: {r}, {g}, {b}"
        hsb_output.value = f"HSB: {h:.2f}°, {s:.2f}%, {v:.2f}%"
        cmyk_output.value = f"CMYK: {c:.2f}%, {m:.2f}%, {y:.2f}%, {k:.2f}%"

        plt.figure(figsize=(6, 2))
        plt.imshow([[(r/255, g/255, b/255)]])
        plt.axis('off')
        plt.show()

color_input.observe(update_color, names='value')

display(color_input, rgb_output, hsb_output, cmyk_output)

このコードスニペットは、Google Colab上でインタラクティブな色変換ツールを実装するためのものです。以下は、それぞれの部分に対する詳細な解説です。

ウィジェットの作成

color_input = widgets.Text(
    value='ff5733',
    placeholder='例:ff5733',
    description='16進数色: #',
)
  • `color_input`:テキスト入力ウィジェットを作成します。

    • `value`:初期値として 'ff5733' を設定。

    • `placeholder`:入力欄に表示されるプレースホルダーテキスト。

    • `description`:ウィジェットのラベルを '16進数色: #' として表示。

rgb_output = widgets.Label(value="")
hsb_output = widgets.Label(value="")
cmyk_output = widgets.Label(value="")
  • `rgb_output`、`hsb_output`、`cmyk_output`:それぞれの色モデルの結果を表示するためのラベルウィジェットを作成します。初期値は空文字列です。

色変換と表示の更新

def update_color(change):
    hex_color = color_input.value
    if len(hex_color) == 6:
        r, g, b = hex_to_rgb(hex_color)
        h, s, v = rgb_to_hsb(r, g, b)
        c, m, y, k = rgb_to_cmyk(r, g, b)

        rgb_output.value = f"RGB: {r}, {g}, {b}"
        hsb_output.value = f"HSB: {h:.2f}°, {s:.2f}%, {v:.2f}%"
        cmyk_output.value = f"CMYK: {c:.2f}%, {m:.2f}%, {y:.2f}%, {k:.2f}%"

        plt.figure(figsize=(6, 2))
        plt.imshow([[(r/255, g/255, b/255)]])
        plt.axis('off')
        plt.show()
  • `update_color`:テキスト入力ウィジェットの値が変更されたときに呼び出されるコールバック関数。

    • `hex_color`:テキスト入力ウィジェットから取得した16進数の色コード。

    • `hex_to_rgb`、`rgb_to_hsb`、`rgb_to_cmyk`:16進数の色をそれぞれRGB、HSB、CMYKに変換する関数。

    • 各色モデルのラベルウィジェットの値を更新します。

    • `plt.figure`と`plt.imshow`:指定したRGB色で画像を表示します。

イベントリスナーの設定と表示

color_input.observe(update_color, names='value')
  • `observe`:テキスト入力ウィジェットの `value` プロパティが変更されたときに `update_color` 関数を呼び出すように設定します。

display(color_input, rgb_output, hsb_output, cmyk_output)
  • `display`:テキスト入力ウィジェットと3つのラベルウィジェットをインターフェースに表示します。

このコードを実行すると、ユーザーは16進数の色コードを入力し、その色がRGB、HSB、およびCMYKの各モデルに変換されて表示されます。さらに、その色が画像として表示されます。



補色、トライアド、スクエア

16進数が記入されなかったり、YMCKが切れてたりするところは
ChatGPT4君に聞きながら好きに直してください。

ここでいう補色はRGB空間上の補色。
色相環上の補色を見る時はスクエアの色で見てください。

  1. RGB空間の補色: RGB色空間での補色を計算する場合、明度や彩度も変化することがあります。RGBの各成分を反転させる操作(すなわち、255 - R, 255 - G, 255 - Bという計算)は、色の明るさや彩度にも影響を与えるためです。

  2. 色相環上の補色: 色相環では、色相の反対側の色を取得するだけで、明度や彩度は考慮されません。したがって、色相環上での補色の取得は、色相のみを反転させ、明度や彩度はそのままの値を維持します。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>16進数色変換ツール</title>
</head>
<body>
    <script src="main.js"></script>

    <label for="colorInput">16進数色: #</label>
    <input type="text" id="colorInput" placeholder="例:ff5733" oninput="updateColor()">
    <div id="colorDisplay" style="width:300px; height:100px;"></div>
    <div id="rgb"></div>
    <div id="hsb"></div>
    <!-- 注意: CMYK変換は近似的です -->
    <div id="cmyk"></div>
    <canvas id="colorCanvas" width="1000" height="100"></canvas><br>
    <canvas id="complementaryColorCanvas" width="1000" height="100"></canvas><br>
    <canvas id="triadicHarmonyCanvas" width="1000" height="100"></canvas><br>
    <canvas id="tetradicHarmonyCanvas" width="1000" height="100"></canvas><br>
</body>

</html>

main.js

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)}%`;
        
        displayColorOnCanvas('colorCanvas', [r, g, b], [h, s, v], [c, m, y, k]);

        const compColorHex = complementaryColor(`#${hex}`);
        const [compR, compG, compB] = hexToRgb(compColorHex.slice(1));
        const [compH, compS, compV] = rgbToHsb(compR, compG, compB);
        const [compC, compM, compY, compK] = rgbToCmyk(compR, compG, compB);
        displayColorOnCanvas('complementaryColorCanvas', [compR, compG, compB], [compH, compS, compV], [compC, compM, compY, compK]);

        const triadicColors = triadicHarmony(`#${hex}`);
        displayMultipleColorsOnCanvas('triadicHarmonyCanvas', triadicColors);

        const tetradicColors = tetradicHarmony(`#${hex}`);
        displayMultipleColorsOnCanvas('tetradicHarmonyCanvas', tetradicColors);
    }
}

function displayColorOnCanvas(canvasId, rgb, hsb, cmyk) {
    const canvas = document.getElementById(canvasId);
    const ctx = canvas.getContext('2d');

    ctx.fillStyle = `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    ctx.fillStyle = 'white';
    ctx.font = '20px Arial';
    ctx.fillText(`RGB: ${rgb[0]}, ${rgb[1]}, ${rgb[2]}`, 10, 30);    
    ctx.fillText(`HSB: ${hsb[0].toFixed(2)}°, ${hsb[1].toFixed(2)}%, ${hsb[2].toFixed(2)}%`, 10, 60);
    ctx.fillText(`CMYK: ${cmyk[0].toFixed(2)}%, ${cmyk[1].toFixed(2)}%, ${cmyk[2].toFixed(2)}%, ${cmyk[3].toFixed(2)}%`, 10, 90);
}

function displayMultipleColorsOnCanvas(canvasId, hexColors) {
    const canvas = document.getElementById(canvasId);
    const ctx = canvas.getContext('2d');
    const segmentWidth = canvas.width / hexColors.length;

    hexColors.forEach((color, index) => {
        let [r, g, b] = hexToRgb(color.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(segmentWidth * index, 0, segmentWidth, canvas.height);
        
        ctx.fillStyle = 'white';
        ctx.font = '12px Arial';
        ctx.fillText(`#${color.slice(1)}`, segmentWidth * index + 10, 30);
        ctx.fillText(`RGB: ${r}, ${g}, ${b}`, segmentWidth * index + 10, 60);    
        ctx.fillText(`HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%, ${v.toFixed(2)}%`, segmentWidth * index + 10, 90);
        ctx.fillText(`CMYK: ${c.toFixed(2)}%, ${m.toFixed(2)}%, ${y.toFixed(2)}%, ${k.toFixed(2)}%`, segmentWidth * index + 10, 120);
    });
}


function drawColorSection(ctx, sectionIndex, hex, r, g, b, h, s, v, c, m, y, k) {
    const sectionWidth = ctx.canvas.width / 8;  // canvas is divided into 8 sections
    const x = sectionWidth * sectionIndex;
    
    ctx.fillStyle = hex;
    ctx.fillRect(x, 0, sectionWidth, ctx.canvas.height);
    
    // Add text details
    ctx.fillStyle = 'white'; // or any contrasting color to the chosen color
    ctx.font = '10px Arial';
    ctx.fillText(hex, x + 5, 15);
    ctx.fillText(`RGB: ${r}, ${g}, ${b}`, x + 5, 30);    
    ctx.fillText(`HSV: ${h.toFixed(2)}°, ${s.toFixed(2)}%, ${v.toFixed(2)}%`, x + 5, 45);
    ctx.fillText(`CMYK: ${c.toFixed(2)}%, ${m.toFixed(2)}%, ${y.toFixed(2)}%, ${k.toFixed(2)}%`, x + 5, 60);
}


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)];
}


Google Colab(IPython)

from IPython.display import display, HTML, Javascript

html_content = """
<!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="colorCanvas" width="1000" height="100"></canvas><br>
    <canvas id="complementaryColorCanvas" width="1000" height="100"></canvas><br>
    <canvas id="triadicHarmonyCanvas" width="1000" height="100"></canvas><br>
    <canvas id="tetradicHarmonyCanvas" width="1000" height="100"></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)}%`;

                displayColorOnCanvas('colorCanvas', [r, g, b], [h, s, v], [c, m, y, k]);

                const compColorHex = complementaryColor(`#${hex}`);
                const [compR, compG, compB] = hexToRgb(compColorHex.slice(1));
                const [compH, compS, compV] = rgbToHsb(compR, compG, compB);
                const [compC, compM, compY, compK] = rgbToCmyk(compR, compG, compB);
                displayColorOnCanvas('complementaryColorCanvas', [compR, compG, compB], [compH, compS, compV], [compC, compM, compY, compK]);

                const triadicColors = triadicHarmony(`#${hex}`);
                displayMultipleColorsOnCanvas('triadicHarmonyCanvas', triadicColors);

                const tetradicColors = tetradicHarmony(`#${hex}`);
                displayMultipleColorsOnCanvas('tetradicHarmonyCanvas', tetradicColors);
            }
        }

        function displayColorOnCanvas(canvasId, rgb, hsb, cmyk) {
            const canvas = document.getElementById(canvasId);
            const ctx = canvas.getContext('2d');

            ctx.fillStyle = `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`;
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            ctx.fillStyle = 'white';
            ctx.font = '20px Arial';
            ctx.fillText(`RGB: ${rgb[0]}, ${rgb[1]}, ${rgb[2]}`, 10, 30);    
            ctx.fillText(`HSB: ${hsb[0].toFixed(2)}°, ${hsb[1].toFixed(2)}%、${hsb[2].toFixed(2)}%`, 10, 60);
            ctx.fillText(`CMYK: ${cmyk[0].toFixed(2)}%、${cmyk[1].toFixed(2)}%、${cmyk[2].toFixed(2)}%、${cmyk[3].toFixed(2)}%`, 10, 90);
        }

        function displayMultipleColorsOnCanvas(canvasId, hexColors) {
            const canvas = document.getElementById(canvasId);
            const ctx = canvas.getContext('2d');
            const segmentWidth = canvas.width / hexColors.length;

            hexColors.forEach((color, index) => {
                let [r, g, b] = hexToRgb(color.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(segmentWidth * index, 0, segmentWidth, canvas.height);

                ctx.fillStyle = 'white';
                ctx.font = '12px Arial';
                ctx.fillText(`#${color.slice(1)}`, segmentWidth * index + 10, 30);
                ctx.fillText(`RGB: ${r}, ${g}, ${b}`, segmentWidth * index + 10, 60);    
                ctx.fillText(`HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%、${v.toFixed(2)}%`, segmentWidth * index + 10, 90);
                ctx.fillText(`CMYK: ${c.toFixed(2)}%、${m.toFixed(2)}%、${y.toFixed(2)}%、${k.toFixed(2)}%`, segmentWidth * index + 10, 120);
            });
        }

        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>
"""

# HTMLとJSを表示
display(HTML(html_content))

Google Colab(%%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="colorCanvas" width="1000" height="100"></canvas><br>
    <canvas id="complementaryColorCanvas" width="1000" height="100"></canvas><br>
    <canvas id="triadicHarmonyCanvas" width="1000" height="100"></canvas><br>
    <canvas id="tetradicHarmonyCanvas" width="1000" height="100"></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)}%`;

                displayColorOnCanvas('colorCanvas', [r, g, b], [h, s, v], [c, m, y, k]);

                const compColorHex = complementaryColor(`#${hex}`);
                const [compR, compG, compB] = hexToRgb(compColorHex.slice(1));
                const [compH, compS, compV] = rgbToHsb(compR, compG, compB);
                const [compC, compM, compY, compK] = rgbToCmyk(compR, compG, compB);
                displayColorOnCanvas('complementaryColorCanvas', [compR, compG, compB], [compH, compS, compV], [compC, compM, compY, compK]);

                const triadicColors = triadicHarmony(`#${hex}`);
                displayMultipleColorsOnCanvas('triadicHarmonyCanvas', triadicColors);

                const tetradicColors = tetradicHarmony(`#${hex}`);
                displayMultipleColorsOnCanvas('tetradicHarmonyCanvas', tetradicColors);
            }
        }

        function displayColorOnCanvas(canvasId, rgb, hsb, cmyk) {
            const canvas = document.getElementById(canvasId);
            const ctx = canvas.getContext('2d');

            ctx.fillStyle = `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`;
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            ctx.fillStyle = 'white';
            ctx.font = '20px Arial';
            ctx.fillText(`RGB: ${rgb[0]}, ${rgb[1]}, ${rgb[2]}`, 10, 30);    
            ctx.fillText(`HSB: ${hsb[0].toFixed(2)}°, ${hsb[1].toFixed(2)}%、${hsb[2].toFixed(2)}%`, 10, 60);
            ctx.fillText(`CMYK: ${cmyk[0].toFixed(2)}%、${cmyk[1].toFixed(2)}%、${cmyk[2].toFixed(2)}%、${cmyk[3].toFixed(2)}%`, 10, 90);
        }

        function displayMultipleColorsOnCanvas(canvasId, hexColors) {
            const canvas = document.getElementById(canvasId);
            const ctx = canvas.getContext('2d');
            const segmentWidth = canvas.width / hexColors.length;

            hexColors.forEach((color, index) => {
                let [r, g, b] = hexToRgb(color.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(segmentWidth * index, 0, segmentWidth, canvas.height);

                ctx.fillStyle = 'white';
                ctx.font = '12px Arial';
                ctx.fillText(`#${color.slice(1)}`, segmentWidth * index + 10, 30);
                ctx.fillText(`RGB: ${r}, ${g}, ${b}`, segmentWidth * index + 10, 60);    
                ctx.fillText(`HSB: ${h.toFixed(2)}°, ${s.toFixed(2)}%、${v.toFixed(2)}%`, segmentWidth * index + 10, 90);
                ctx.fillText(`CMYK: ${c.toFixed(2)}%、${m.toFixed(2)}%、${y.toFixed(2)}%、${k.toFixed(2)}%`, segmentWidth * index + 10, 120);
            });
        }

        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>


出力統合用

%%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="400"></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}`);
                
                displayAllColorsOnCanvas(`#${hex}`, compColorHex, triadicColors, tetradicColors);
            }
        }

        function displayAllColorsOnCanvas(hex, compColorHex, triadicColors, tetradicColors) {
            const canvas = document.getElementById('combinedCanvas');
            const ctx = canvas.getContext('2d');
            const segmentHeight = canvas.height / 4;

            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 / 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);
            });            
        }

        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>


緋色 #E54848

茜(あかね)#B13546

RGB: 177, 53, 70
HSB: 171.06°, 70.06%, 69.41%
CMYK: 0.00%, 70.06%, 60.45%, 30.59%

クリムソン (crimson)



蘇芳(すおう)#973C3F

RGB: 151, 60, 63
HSB: 127.76°, 60.26%, 59.22%
CMYK: 0.00%, 60.26%, 58.28%, 40.78%

ピュース (puce)
#CC8899

血を吸ったノミの腹の色。

RGB: 204, 136, 153
HSB: 92.00°, 33.33%, 80.00%
CMYK: 0.00%, 33.33%, 25.00%, 20.00%

マルーン(maroon)#800000

栗。

RGB: 128, 0, 0
HSB: 0.00°, 100.00%, 50.20%
CMYK: 0.00%, 100.00%, 100.00%, 49.80%

ワインレッド(wine red)#633142

RGB: 99, 49, 66
HSB: 66.59°, 50.51%, 38.82%
CMYK: 0.00%, 50.51%, 33.33%, 61.18%

葡萄色(えびいろ)#640125

伊勢海老の殻の色。

RGB: 100, 1, 37
HSB: 131.29°, 99.00%, 39.22%
CMYK: 0.00%, 99.00%, 63.00%, 60.78%

海老茶(えびちゃ)#6c2c2f

女学生の袴の色。

RGB: 108, 44, 47
HSB: 89.65°, 59.26%, 42.35%
CMYK: 0.00%, 59.26%, 56.48%, 57.65%

ぶどう色2号#413027

国鉄の電車の色。

RGB: 65, 48, 39
HSB: 2.12°, 40.00%, 25.49%
CMYK: 0.00%, 26.15%, 40.00%, 74.51%


スカーレット(scarlet)#FF2400

カーマイン (carmine) #960018


緑 (Green) - #008000

ライム (Lime) - #00FF00

フォレストグリーン (ForestGreen) - #228B22

シーグリーン (SeaGreen) - #2E8B57

ダークグリーン (DarkGreen) - #006400

ペールグリーン (PaleGreen) - #98FB98

ミディアムシーグリーン (MediumSeaGreen) - #3CB371

スプリンググリーン (SpringGreen) - #00FF7F

ダークシーグリーン (DarkSeaGreen) - #8FBC8F

ライトシーグリーン (LightSeaGreen) - #20B2AA

イエローグリーン (YellowGreen) - #9ACD32

オリーブドラブ (OliveDrab) - #6B8E23

ミディアムアクアマリン (MediumAquamarine) - #66CDAA

青 (Blue) - #0000FF

ライトブルー (LightBlue) - #ADD8E6

スカイブルー(SkyBlue) - #87CEEB

空色#90D7EC
アジュール#007FFF

セレステなど

ネイビー (Navy) - #000080

navy blue#1f2f54
紺色#233B6C

鴨の羽色 (Teal) - #008080

teal blue#367588
teal green#264B56
duck blue#005E7E


オレンジ

黄色


この記事が気に入ったらサポートをしてみませんか?