【问题标题】:Calculate color range for 1 color, from light color to dark(er) color计算一种颜色的颜色范围,从浅色到深(er)色
【发布时间】:2023-04-03 08:52:01
【问题描述】:

我发现了这个漂亮的调色板

我想用它让用户从这个调色板中选择一个调色板,它是前 8 种颜色(垂直)。所以我想我可以添加更多,当然不要输入所有的十六进制代码。

有没有办法计算这些值?

例如输入颜色 c6ff89(或任何其他颜色),然后以 498e00(即右列)结束。

所以根本问题是:这些颜色是否需要进行数学运算?

其次,现在我正在查看这些颜色:顶行的项目似乎都具有相同的“亮度”(不知道该使用什么术语)。我的意思是左边是蓝色的光,右边是绿色的光,所以同样的亮度(/黑暗)。这也可以计算,计算相同的亮度,比如红色或橙色?

【问题讨论】:

    标签: colors color-scheme


    【解决方案1】:

    是的,计算它们实际上非常简单!

    hsl 中,这些只是具有完全饱和度和每一步降低 7% 的亮度的颜色:

    #c6ff89 is hsl(89deg 100% 77%),
    #b5ff65 is hsl(89deg 100% 70%);
    #a3ff42 is hsl(89deg 100% 63%);
    ...
    #498e00 is hsl(89deg 100% 28%);
    

    要获得其他颜色渐变,您只需更改色调即可。

    这里有一个 sn-p 来试试看。

     function colorChanged(h) {
    
        let s = 100;
        let l = 77;
    
        document.getElementById('deg').innerText = h;
    
        for (let color of document.getElementsByClassName('color')) {
    
            color.style.backgroundColor = `hsl(${h}deg ${s}% ${l}%)`;
            color.innerText = HSLToRGB(h, s, l);
    
            l -= 7;
        }
    }
    
    function HSLToRGB(h, s, l) {
        s /= 100;
        l /= 100;
    
        let c = (1 - Math.abs(2 * l - 1)) * s,
            x = c * (1 - Math.abs((h / 60) % 2 - 1)),
            m = l - c / 2,
            r = 0,
            g = 0,
            b = 0;
    
        if (0 <= h && h < 60) {
            r = c; g = x; b = 0;
        } else if (60 <= h && h < 120) {
            r = x; g = c; b = 0;
        } else if (120 <= h && h < 180) {
            r = 0; g = c; b = x;
        } else if (180 <= h && h < 240) {
            r = 0; g = x; b = c;
        } else if (240 <= h && h < 300) {
            r = x; g = 0; b = c;
        } else if (300 <= h && h < 360) {
            r = c; g = 0; b = x;
        }
    
        return "#" + 
          Math.floor((r + m) * 255).toString(16).padStart(2, '0') + 
          Math.floor((g + m) * 255).toString(16).padStart(2, '0') + 
          Math.floor((b + m) * 255).toString(16).padStart(2, '0');
    }
    
    colorChanged(89);
    .color {
        width: 200px;
        height: 45px;
        background: black;
        margin-bottom: 8px;
    
        display: flex;
        align-items: center;
        justify-content: center;
    }
    <html>
    <body>
        <label>
            <input type="range" min="0" max="360" value="89" onchange="colorChanged(this.value)" />
            <span id="deg"></span>deg
        </label>
        <div class="color"></div>
        <div class="color"></div>
        <div class="color"></div>
        <div class="color"></div>
        <div class="color"></div>
        <div class="color"></div>
        <div class="color"></div>
        <div class="color"></div>
        <div class="color"></div>
        <div class="color"></div>
    </body>
    
    </html>

    从这里偷来的颜色转换: https://css-tricks.com/converting-color-spaces-in-javascript/

    【讨论】:

    • 这是很棒的东西。为时已晚,无法奖励您所有积分,对不起。指向 HSL 页面的链接很好,终于知道那是什么。
    【解决方案2】:

    是的,但这可能取决于您对哪种类型的色彩空间感兴趣。如果您想获得一堆具有相似感知亮度的颜色,我是HUSL 色彩空间。

    Seaborn 为 color picking 提供了一个不错的 API。要获得一堆具有不同亮度的颜色,请尝试dark_palettelight_palette。要获得起始颜色,您可以从 husl_palette 生成的颜色开始,这样所有凝视颜色都具有相同的感知亮度。

    把这些放在一起:

    x_colors = 10; y_colors=10
    husl_pal = sns.husl_palette(y_colors, l=0.8)
    fig, axs = plt.subplots(10,1)
    for i,color in enumerate(husl_pal):
        # cut off first color because it is extra dark
        my_palplot(sns.dark_palette(color, x_colors+1)[1:], ax=axs[i])
    

    我借用了一个自定义 sns.palplot() 函数,该函数允许从 this question 传递轴对象

    def my_palplot(pal, size=1, ax=None):
        """Plot the values in a color palette as a horizontal array.
        Parameters
        ----------
        pal : sequence of matplotlib colors
            colors, i.e. as returned by seaborn.color_palette()
        size :
            scaling factor for size of plot
        ax :
            an existing axes to use
        """
    
        import numpy as np
        import matplotlib as mpl
        import matplotlib.pyplot as plt
        import matplotlib.ticker as ticker
    
        n = len(pal)
        if ax is None:
            f, ax = plt.subplots(1, 1, figsize=(n * size, size))
        ax.imshow(np.arange(n).reshape(1, n),
                  cmap=mpl.colors.ListedColormap(list(pal)),
                  interpolation="nearest", aspect="auto")
        ax.set_xticks(np.arange(n) - .5)
        ax.set_yticks([-.5, .5])
        # Ensure nice border between colors
        ax.set_xticklabels(["" for _ in range(n)])
        # The proper way to set no ticks
        ax.yaxis.set_major_locator(ticker.NullLocator())
    

    【讨论】:

      猜你喜欢
      • 2012-09-26
      • 1970-01-01
      • 2014-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-02
      相关资源
      最近更新 更多