CSS 样式,如何计算临近颜色值?

栏目: CSS · 发布时间: 5年前

内容简介:版权声明:版权归博主所有,转载请带上本文链接!联系方式:abel533@gmail.com https://blog.csdn.net/isea533/article/details/85860078

版权声明:版权归博主所有,转载请带上本文链接!联系方式:abel533@gmail.com https://blog.csdn.net/isea533/article/details/85860078

在有些场景下,有可能需要阶梯状的颜色展示,通过背景色对数据分组。或者就是自动生成某个颜色的临近值。如果颜色是固定的,直接计算好固定就行,如果是动态或者用户设置的颜色值,就需要一定的算法来计算临近的颜色。

我在看 MDN 时,发现了 RGB 和 HSL,发现 HSL 的值通过修改色调(hue)、饱和度(saturation)和明度(lightness)可以让颜色更有规律的进行渐变。

HSL简单介绍:

  1. 色调:颜色的底色调。这个值在0到360之间,表示色轮的角度。
  2. 饱和度:饱和度是多少?这需要一个从0-100%的值,其中0是没有颜色(它将显示为灰色),100%是全彩色饱和度。
  3. 明度:颜色有多亮或明亮?这需要一个从0-100%的值,其中0是无光(它会出现全黑的),100%是充满光的(它会出现全白)。

CSS 样式,如何计算临近颜色值?

图片出处: https://en.wikipedia.org/wiki/File:HSL_color_solid_cylinder_saturation_gray.png

通过 HSL 的值的逐渐变化,可以得到非常相近的颜色。

既然通过 HSL 很容易计算,就搜搜如何在 RGB 和 HSL 之间进行转换。很容易就搜到了下面的网站:

http://www.easyrgb.com/en/math.php

这个网站提供了多种颜色类型间的转换算法,这个算法基本上可以直接拿来当 JS 代码用,内部有些细节需要特殊处理。

针对颜色计算做了一个简单的封装,并且写了一些简单的方法来进行测试,下面是完整的代码,保存到 html 文件直接在浏览器打开即可。

直接访问: https://abel533.github.io/color_rgb_hsl/

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>
        var ColorUtil = (function () {
            function rgb2hsl({ R, G, B }) {
                var H, S, L;
                var var_R = (R / 255);
                var var_G = (G / 255);
                var var_B = (B / 255);

                var var_Min = Math.min(var_R, var_G, var_B)    //Min. value of RGB
                var var_Max = Math.max(var_R, var_G, var_B)    //Max. value of RGB
                var del_Max = var_Max - var_Min             //Delta RGB value

                var L = (var_Max + var_Min) / 2

                if (del_Max == 0)                     //This is a gray, no chroma...
                {
                    H = 0
                    S = 0
                }
                else                                    //Chromatic data...
                {
                    if (L < 0.5) S = del_Max / (var_Max + var_Min)
                    else S = del_Max / (2 - var_Max - var_Min)

                    var del_R = (((var_Max - var_R) / 6) + (del_Max / 2)) / del_Max
                    var del_G = (((var_Max - var_G) / 6) + (del_Max / 2)) / del_Max
                    var del_B = (((var_Max - var_B) / 6) + (del_Max / 2)) / del_Max

                    if (var_R == var_Max) H = del_B - del_G
                    else if (var_G == var_Max) H = (1 / 3) + del_R - del_B
                    else if (var_B == var_Max) H = (2 / 3) + del_G - del_R

                    if (H < 0) H += 1
                    if (H > 1) H -= 1
                }
                return { H, S, L };
            }

            function Hue_2_RGB(v1, v2, vH) {
                if (vH < 0) vH += 1;
                if (vH > 1) vH -= 1;
                if ((6 * vH) < 1) return (v1 + (v2 - v1) * 6 * vH);
                if ((2 * vH) < 1) return (v2);
                if ((3 * vH) < 2) return (v1 + (v2 - v1) * ((2 / 3) - vH) * 6);
                return v1;
            }

            function hsl2rgb({ H, S, L }) {
                var R, G, B;
                if (S == 0) {
                    R = L * 255;
                    G = L * 255;
                    B = L * 255;
                }
                else {
                    var var_2, var_1;
                    if (L < 0.5) var_2 = L * (1 + S);
                    else var_2 = (L + S) - (S * L);

                    var_1 = 2 * L - var_2;

                    R = Math.round(255 * Hue_2_RGB(var_1, var_2, H + (1 / 3)));
                    G = Math.round(255 * Hue_2_RGB(var_1, var_2, H));
                    B = Math.round(255 * Hue_2_RGB(var_1, var_2, H - (1 / 3)));
                }
                return { R, G, B };
            }

            function hex2rgb(hex) {
                if (hex.indexOf('#') != -1) {
                    hex = hex.substr(1, 6);
                }
                var R = parseInt(hex.substr(0, 2), 16);
                var G = parseInt(hex.substr(2, 2), 16);
                var B = parseInt(hex.substr(4, 2), 16);
                return { R, G, B };
            }

            function rgb2hex({ R, G, B }) {
                return '#' + dec2hex(R) + dec2hex(G) + dec2hex(B);
            }

            function dec2hex(dec) {
                return (dec + 0x100).toString(16).substr(1, 2).toUpperCase();
            }

            return {
                rgb2hsl,
                hsl2rgb,
                hex2rgb,
                rgb2hex
            }
        })();
    </script>
</head>

<body>
    <div class="main">
        <div class="form">
            <label for="hex">请输入 Hex 值: </label>
            <input type="text" id="hex">
            <button onclick="genColor()">生成</button>
        </div>
        <div class="title">改变色调H</div>
        <div class="container H">

        </div>
        <div class="title">改变饱和度S</div>
        <div class="container S">

        </div>
        <div class="title">改变明度L</div>
        <div class="container L">

        </div>
    </div>
    <script>

        function genColor(){
            document.querySelector('.H').innerHTML = genColorHtml('H', 0, 360);
            document.querySelector('.S').innerHTML = genColorHtml('S', 0, 100);
            document.querySelector('.L').innerHTML= genColorHtml('L', 0, 100);
        }

        function genColorHtml(type, min, max){
            var hex = document.getElementById('hex').value;
            var hsl = ColorUtil.rgb2hsl(ColorUtil.hex2rgb(hex));
            var hexArray = [];
            for (let i = min; i < max; i++) {
                hsl[type] = i/max;
                hexArray.push(ColorUtil.rgb2hex(ColorUtil.hsl2rgb(hsl)));
            }
            if (hex[0] != '#') {
                hex = '#' + hex;
            }
            hex = hex.toUpperCase();
            var html = '';
            for (let i = 0; i < hexArray.length; i++) {
                html += '<div class="item ' + (hexArray[i] == hex ? 'current' : '') + '" style="background-color:' + hexArray[i] + '"></div>';
            }
            return html;
        }
    </script>
    <style>
        .main {
            display: flex;
            flex-flow: column wrap;
            justify-content: space-between;
        }

        .container {
            display: flex;
        }

        .item {
            height: 50px;
            width: 50px;
        }

        .current {
            margin: 0 1px;
        }
    </style>
</body>

</html>

在该页面可以输入不同的颜色预览效果,并且展示了分别修改 H,S,L 三种值的不同效果,例如输入 ff00ff ,结果如下:

CSS 样式,如何计算临近颜色值?

上面的所有变化值都是1,所以颜色特别的接近,在实际使用中,为了更好的区分,可以增加变化值,例如 5 时的效果:

CSS 样式,如何计算临近颜色值?

上述图片中,有白色边框的颜色是输入的 hex 值对应的颜色。

通过上面的算法根据自己的实际情况进行修改,就可以得到符合要求的临近色了。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Head First Mobile Web

Head First Mobile Web

Lyza Danger Gardner、Jason Grigsby / O'Reilly Media / 2011-12 / $ 50.84

Despite the huge number of mobile devices and apps in use today, your business still needs a website. You just need it to be mobile. Head First Mobile Web walks you through the process of making a con......一起来看看 《Head First Mobile Web》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具