什么是从指定颜色获得高光颜色的合适算法?

时间:2015-08-21 13:35:42

标签: javascript

我有一个Javascript画布,我想在鼠标悬停时使用"突出显示"颜色。我的矩形具有动态颜色DC,因此它可以是从白色到黑色的任何颜色,甚至是具有透明度的颜色。我需要一个算法给我这个"突出显示"颜色从DC开始。

我想我必须测试光度L超过阈值T:

如果L < Ť     增加DC的光度  其他     降低DC的光度

这是一个好方法吗?

我不知道该怎么办白色和黑色。我应该选择合适的颜色吗?

2 个答案:

答案 0 :(得分:2)

您可以使用以下内容:

选中此示例:this question

// Get a contrasting Hex color value for a given color
// @param {String} hexColor: Hexadecimal color value (i.e. "#FF0000")
// @param {String} conversionType: Conversion type [YIQ|Opposite|50%]
// @return {String}
function getHighlightColor (hexColor, conversionType) {
    if (!isValidColor(hexColor)) return "#000000";  

    switch (conversionType){

        case "yiq":
            // YIQ (Based on luminosity)
            // *****************
            hexColor = hexColor.substr(1);
            if (hexColor.length == 3) {
                var r = parseInt(hexColor.substr(0,1) + hexColor.substr(0,1),16);
                var g = parseInt(hexColor.substr(1,1) + hexColor.substr(1,1),16);
                var b = parseInt(hexColor.substr(2,1) + hexColor.substr(2,1),16);           
            }
            else {      
                var r = parseInt(hexColor.substr(0,2),16);
                var g = parseInt(hexColor.substr(2,2),16);
                var b = parseInt(hexColor.substr(4,2),16);
            }
            var yiq = ((r*299)+(g*587)+(b*114))/1000;
            return (yiq >= 128) ? '#000000' : '#FFFFFF';

            break;

        case "opposite":
            // Opposite Color
            // *****************
            hexColor = hexColor.substring(1);
            colorLength =  hexColor.length;
            hexColor = parseInt(hexColor, 16);
            hexColor = 0xFFFFFF ^ hexColor;
            hexColor = hexColor.toString(16);

            if (colorLength == 6)
                hexColor = ("000000" + hexColor).slice(-6); 
            else if (colorLength == 3)
                hexColor = ("000" + hexColor).slice(-3);
            else
                hexColor = "000000";

            return "#" + hexColor;

            break;

        case "50%":         
            // 50% (Black / White)
            // *****************
            hexColor = hexColor.substring(1)
            if (hexColor.length == 4)
                hexColor = 
                    hexColor.substr(0,1) + hexColor.substr(0,1) +
                    hexColor.substr(1,1) + hexColor.substr(1,1) +
                    hexColor.substr(2,1) + hexColor.substr(2,1);

            return (parseInt(hexColor, 16) > (0xffffff/2)) ? '#000000':'#FFFFFF';
    }
}

// Validate the input value is a valid Hex color (i.e. Valid colors "#FF3400" or "#A9F". Invalid Colors "ASD102", "gray")
// @param {String} value: Value to test
// @return {Boolean}
function isValidColor(value){
    var hexColorRegExp = new RegExp(/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i);
    return hexColorRegExp.test(value);      
}

答案 1 :(得分:1)

我的解决方案如下:

function colorLuminance(color, lum) {
      var hex = colorToHex(color);
      // validate hex string
      hex = String(hex).replace(/[^0-9a-f]/gi, '');
      if (hex.length < 6) {
          hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
      }
      lum = lum || 0;
      // convert to decimal and change luminosity
      var rgb = "#", c, i;
      for (i = 0; i < 3; i++) {
           c = parseInt(hex.substr(i*2,2), 16);
           c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
           rgb += ("00"+c).substr(c.length);
      }
      return rgb;
}

function colorToHex(c) {
     var m = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/.exec(c);
     return m ? '#' + (1 << 24 | m[1] << 16 | m[2] << 8 | m[3]).toString(16).substr(1) : c;
}

//returns brightness value from 0 to 255
function get_brightness(hexCode) {
    // strip off any leading #
    hexCode = hexCode.replace('#', '');

    var c_r = parseInt(hexCode.substr(0, 2),16);
    var c_g = parseInt(hexCode.substr(2, 2),16);
    var c_b = parseInt(hexCode.substr(4, 2),16);

    return ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000;
}

function highlightColor(color, lum) {
    var hex = colorToHex(color);    
    if (get_brightness(hex) > 160) {
        // too bright, need to darken it
        if (lum > 0) {
            lum = -lum;
        }       
    } else {        
        if (lum < 0) {
            lum = -lum;
        }
    }   
    return colorLuminance(color, lum);
}