我想展示一些像这个例子的图片

填充颜色由数据库中颜色为十六进制的字段决定(例如:ClassX -> color: #66FFFF)。 现在,我想显示上面的数据与所选的颜色填充(如上图),但我需要知道如果颜色是暗或光,所以我知道如果文字应该在白色或黑色。 有办法吗?谢谢大家


当前回答

以防有人关心Mark Ransom回答的SCSS版本:

@use 'sass:color' as *;
@use 'sass:math' as *;

@function col_r($color) {
    @if $color <= 0.03928 {
        @return $color / 12.92;
    } @else {
        @return pow((($color + 0.055) / 1.055), (2.4));
    }
}

@function pickTextColorBasedOnBgColorAdvanced(
  $bgColor,
  $lightColor,
  $darkColor
) {
  $r: red($bgColor);
  $g: green($bgColor);
  $b: blue($bgColor);
  $ui_r: $r / 255;
  $ui_g: $g / 255;
  $ui_b: $b / 255;

  $ui_r_c: col_r($ui_r);
  $ui_g_c: col_r($ui_g);
  $ui_b_c: col_r($ui_b);

  $L: (0.2126 * $ui_r_c) + (0.7152 * $ui_g_c) + (0.0722 * $ui_b_c);
  @if ($L > 0.179) {
    @return $darkColor;
  } @else {
    @return $lightColor;
  }
}

其他回答

我在@SudoPlz提出的高级函数的基础上做了一个函数,它也考虑了浅色和深色:

function getTextColor (bgColor, lightColor = '#FFFFFF', darkColor = '#000000') {

  const getLuminance = function (hexColor) {
    var color = (hexColor.charAt(0) === '#') ? hexColor.substring(1, 7) : hexColor
    var r = parseInt(color.substring(0, 2), 16) // hexToR
    var g = parseInt(color.substring(2, 4), 16) // hexToG
    var b = parseInt(color.substring(4, 6), 16) // hexToB
    var uicolors = [r / 255, g / 255, b / 255]
    var c = uicolors.map(col => col <= 0.03928 ? col / 12.92 : ((col + 0.055) / 1.055) ** 2.4)

    return (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]);
  }

  var L = getLuminance(bgColor)
  var L1 = getLuminance(lightColor)
  var L2 = getLuminance(darkColor)

  return (L > Math.sqrt((L1 + 0.05) * (L2 + 0.05)) - 0.05) ? darkColor : lightColor;
}

因此,如果深色文本不是黑色而是栗色,灰色背景上的推荐文本颜色会变成白色:

getTextColor('#808080')
"#000000"
getTextColor('#808080', '#FFFFFF', '#800000')
"#FFFFFF"

这个(JavaScript代码)怎么样?

/**
 * Get color (black/white) depending on bgColor so it would be clearly seen.
 * @param bgColor
 * @returns {string}
 */
getColorByBgColor(bgColor) {
    if (!bgColor) { return ''; }
    return (parseInt(bgColor.replace('#', ''), 16) > 0xffffff / 2) ? '#000' : '#fff';
}

这只是一个示例,它将在单击元素时更改SVG复选标记的颜色。它将根据所单击元素的背景色将复选标记颜色设置为黑色或白色。

checkmarkColor: function(el) {
    var self = el;
    var contrast = function checkContrast(rgb) {
        // @TODO check for HEX value

        // Get RGB value between parenthesis, and remove any whitespace
        rgb = rgb.split(/\(([^)]+)\)/)[1].replace(/ /g, '');

        // map RGB values to variables
        var r = parseInt(rgb.split(',')[0], 10),
            g = parseInt(rgb.split(',')[1], 10),
            b = parseInt(rgb.split(',')[2], 10),
            a;

        // if RGBA, map alpha to variable (not currently in use)
        if (rgb.split(',')[3] !== null) {
            a = parseInt(rgb.split(',')[3], 10);
        }

        // calculate contrast of color (standard grayscale algorithmic formula)
        var contrast = (Math.round(r * 299) + Math.round(g * 587) + Math.round(b * 114)) / 1000;

        return (contrast >= 128) ? 'black' : 'white';
    };

    $('#steps .step.color .color-item .icon-ui-checkmark-shadow svg').css({
        'fill': contrast($(self).css('background-color'))
    });
}

onClickExtColor: function(evt) {
    var self = this;

    self.checkmarkColor(evt.currentTarget);
}

https://gist.github.com/dcondrey/183971f17808e9277572

根据@MarkRansom的答案,我创建了一个PHP脚本,你可以在这里找到:

function calcC($c) {
    if ($c <= 0.03928) {
        return $c / 12.92;
    }
    else {
        return pow(($c + 0.055) / 1.055, 2.4);
    }
}

function cutHex($h) {
    return ($h[0] == "#") ? substr($h, 1, 7) : $h;
}

function hexToR($h) {
    return hexdec(substr(cutHex($h), 0, 2));
}

function hexToG($h) {
    return hexdec(substr(cutHex($h), 2, 2)); // Edited
}

function hexToB($h) {
    return hexdec(substr(cutHex($h), 4, 2)); // Edited
}

function computeTextColor($color) {
    $r = hexToR($color);
    $g = hexToG($color);
    $b = hexToB($color);
    $uicolors = [$r / 255, $g / 255, $b / 255];


    $c = array_map("calcC", $uicolors);

    $l = 0.2126 * $c[0] + 0.7152 * $c[1] + 0.0722 * $c[2];
    return ($l > 0.179) ? '#000000' : '#ffffff';
}

以防有人关心Mark Ransom回答的SCSS版本:

@use 'sass:color' as *;
@use 'sass:math' as *;

@function col_r($color) {
    @if $color <= 0.03928 {
        @return $color / 12.92;
    } @else {
        @return pow((($color + 0.055) / 1.055), (2.4));
    }
}

@function pickTextColorBasedOnBgColorAdvanced(
  $bgColor,
  $lightColor,
  $darkColor
) {
  $r: red($bgColor);
  $g: green($bgColor);
  $b: blue($bgColor);
  $ui_r: $r / 255;
  $ui_g: $g / 255;
  $ui_b: $b / 255;

  $ui_r_c: col_r($ui_r);
  $ui_g_c: col_r($ui_g);
  $ui_b_c: col_r($ui_b);

  $L: (0.2126 * $ui_r_c) + (0.7152 * $ui_g_c) + (0.0722 * $ui_b_c);
  @if ($L > 0.179) {
    @return $darkColor;
  } @else {
    @return $lightColor;
  }
}