Automatically change text color to assure readability

前端 未结 8 2017
生来不讨喜
生来不讨喜 2020-12-08 00:42

Users can set the background-color of a button through a textbox that accept RGB hexadecimal notation: ff00ff, ccaa22, etc. So I need to set the te

相关标签:
8条回答
  • 2020-12-08 01:23

    var getContrastYIQ = function(color) {
      var hex = '#';
      var r, g, b;
      if (color.indexOf(hex) > -1) {
        r = parseInt(color.substr(1, 2), 16);
        g = parseInt(color.substr(3, 2), 16);
        b = parseInt(color.substr(5, 2), 16);
      } else {
        color = color.match(/\d+/g);
        r = color[0];
        g = color[1];
        b = color[2];
      }
    
      var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
      return (yiq >= 128) ? 'black' : 'white';
    }

    Thanks for the post ZetCoby! Had to adjust your "color.substr(" array position to account for the initial '#'; then it worked great! you could also use a color.replace('#',''); within the if block...

    0 讨论(0)
  • 2020-12-08 01:34

    Salaman's code is good but sometimes his inversion is not readable enough. I use YCbCr and just change gray scale.

    function invertColor(rgb) {
        var yuv = rgb2yuv(rgb);
        var factor = 180;
        var threshold = 100;
        yuv.y = clamp(yuv.y + (yuv.y > threshold ? -factor : factor));
        return yuv2rgb(yuv);
    }
    

    jsfiddle demo

    0 讨论(0)
  • 2020-12-08 01:41

    Here is a very small way to complement the hex value //hex value like "aa00cc"

    function complementHex(hexValue){
        var reqHex = "";
        for(var i=0;i<6;i++){
            reqHex = reqHex + (15-parseInt(hexValue[i],16)).toString(16);
        }
        return reqHex;
    }
    
    0 讨论(0)
  • 2020-12-08 01:44

    I linked another Question to this topic in the comments.
    JS function to calculate complementary colour?

    As Tejasva said you need to need to convert RGB to HSL, complement the Hue and convert it back.

    I implemented the linked answer as a sample. Please upvote the original poster if this was helpful for you, because they provided the solution in fact.

    Sample
    http://jsfiddle.net/pLZ89/2/

    0 讨论(0)
  • 2020-12-08 01:45

    You can invert the background color and use it as foreground color. The following algorithm produces results identical to the "Image > Adjustments > Invert" color command in Photoshop:

    function invertColor(hexTripletColor) {
        var color = hexTripletColor;
        color = color.substring(1);           // remove #
        color = parseInt(color, 16);          // convert to integer
        color = 0xFFFFFF ^ color;             // invert three bytes
        color = color.toString(16);           // convert to hex
        color = ("000000" + color).slice(-6); // pad with leading zeros
        color = "#" + color;                  // prepend #
        return color;
    }
    /*
     * Demonstration
     */
    function randomColor() {
        var color;
        color = Math.floor(Math.random() * 0x1000000); // integer between 0x0 and 0xFFFFFF
        color = color.toString(16);                    // convert to hex
        color = ("000000" + color).slice(-6);          // pad with leading zeros
        color = "#" + color;                           // prepend #
        return color;
    }
    $(function() {
        $(".demolist li").each(function() {
            var c1 = randomColor();
            var c2 = invertColor(c1);
            $(this).text(c1 + " " + c2).css({
                "color": c1,
                "background-color": c2
            });
        });
    });
    body { font: bold medium monospace; }
    .demolist { margin: 0; padding: 0; list-style-type: none; overflow: hidden; }
    .demolist li { float: left; width: 5em; height: 5em; text-align: center; }
    <ul class="demolist">
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    Note that this is not a bullet-proof solution. Colors that are close to 50% brightness and/or saturation will not produce sufficient contrast.

    Demo on jsFiddle

    0 讨论(0)
  • 2020-12-08 01:45

    I had the same issue once, and gathered information all over the internet also using Salman A answer, I came up with this function, it supports hex, rgb and rgba

    var invertColor = function (color) {
                var hex   = '#';
                if(color.indexOf(hex) > -1){
                    color = color.substring(1);           
                    color = parseInt(color, 16);         
                    color = 0xFFFFFF ^ color;            
                    color = color.toString(16);           
                    color = ("000000" + color).slice(-6); 
                    color = "#" + color; 
                }else{
                    color = Array.prototype.join.call(arguments).match(/(-?[0-9\.]+)/g);
                    for (var i = 0; i < color.length; i++) {
                        color[i] = (i === 3 ? 1 : 255) - color[i];
                    }
                    if(color.length === 4){
                        color = "rgba("+color[0]+","+color[1]+","+color[2]+","+color[3]+")";
                    }else{
                        color = "rgb("+color[0]+","+color[1]+","+color[2]+")";
                    }
                }         
                return color;
            }
    

    but I don't think this is what you need, I found something more interesting, the below function will return white or black, it will decide witch one is more readable on the given color.

    var getContrastYIQ = function (color){
                var hex   = '#';
                var r,g,b;
                if(color.indexOf(hex) > -1){
                    r = parseInt(color.substr(0,2),16);
                    g = parseInt(color.substr(2,2),16);
                    b = parseInt(color.substr(4,2),16);
                }else{
                    color = color.match(/\d+/g);
                    r = color[0];
                    g = color[1];
                    b = color[2];
                }
    
                var yiq = ((r*299)+(g*587)+(b*114))/1000;
                return (yiq >= 128) ? 'black' : 'white';
            }
    

    I don't take credit for any of this, I just got inspired and modified to my needs.

    Sources: YIQ function explained

    0 讨论(0)
提交回复
热议问题