如何编写javascript为具有背景颜色的独特彩色文本列表

时间:2017-01-25 03:26:45

标签: javascript jquery colors

我需要生成一个有色标签的列表(尽可能多)。只要文字清晰,它们应该是不同的颜色与自己的背景颜色相结合。 (没有背景可以,但文字应该在白色和灰色背景画布上清晰)

我一直在硬编码。但这不是一个好主意。有使用jQuery颜色插件生成随机颜色的解决方案。但我需要的不是随意的,以避免任何可能的重复甚至亲密。

我目前的想法是硬编码“足够”,所以它不会用完“预算”。业务案例是在日历中表示来自不同类别的类似数据,颜色将指示不同的类别。

我很感激解决这个问题的真正解决方案。

我当前的硬编码功能

calendar.color = function (site) {
    switch(site) {

        case "abcae": return {color: 'yellow', textColor: 'black'};
        case "abcca": return {color: 'rosybrown', textColor: 'white'};
        case "abcbr": return {color: 'lightpink', textColor: 'black'};
        case 'abccn': return {color: 'crimson', textColor: 'yellow'};
        case "abccom": return {color: 'deeppink', textColor: 'yellow'};
        case "abcde": return {color: 'darkmagenta', textColor: 'yellow'};
        case "abceu": return {color: 'indigo', textColor: 'yellow'};
        case "abcfr": return {color: 'darkslateblue', textColor: 'white'};
        case "abchk": return {color: 'blue', textColor: 'white'};
        case "abchu": return {color: 'lightsteelblue', textColor: 'black'};
        case "abcin": return {color: 'skyblue', textColor: 'darkmagenta'};
        case "abcit": return {color: 'darkturquoise', textColor: 'black'};
        case "abcro": return {color: 'aqua', textColor: 'black'};
        case "abcru": return {color: 'darkcyan', textColor: 'white'};
        case "abcnl": return {color: 'seagreen', textColor: 'white'};
        case "abcmx": return {color: 'lightgreen', textColor: 'black'};
        case "abces": return {color: 'lime', textColor: 'black'};
        case "abcpl": return {color: 'gray', textColor: 'white'};
        case "abcuk": return {color: 'olive', textColor: 'white'};
        case "abcus": return {color: 'orange', textColor: 'darkblue'};

        default: return {color: 'cadetblue', textColor: 'white'};
    }
}; 

1 个答案:

答案 0 :(得分:0)

使用此js插件(https://github.com/davidmerfield/randomColor),您可以生成背景颜色,然后使用https://24ways.org/2010/calculating-color-contrast/中的对比插件选择合适的文本颜色。

// https://24ways.org/2010/calculating-color-contrast/
function getContrast(hexcolor){
    hexcolor = hexcolor.replace('#', '');
    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';
}

function genColors(num) {
    var color, bg, text, colorset, colors = [];
    for (var i = 0; i <= num; i++) {
        color = randomColor();
        text = getContrast(color);
        bg = color;
        colorset = text+','+bg;
        colors.push(colorset);
    }
    return colors;
}

然后迭代遍历数组;

var colors = genColors(256);

for (var i = 0; i < colors.length; i++) {
    var set = colors[i].split(',');
    var text = set[0];
    var bg = set[1];
    console.log(set);
}

它有点混搭,但希望它能满足您的需求。

或者,我为你做了一个pastebin http://pastebin.com/aLRHMwTG

这是一个小测试,向您展示它的工作原理

// randomColor by David Merfield under the CC0 license
// https://github.com/davidmerfield/randomColor/

;
(function(root, factory) {

  // Support AMD
  if (typeof define === 'function' && define.amd) {
    define([], factory);

    // Support CommonJS
  } else if (typeof exports === 'object') {
    var randomColor = factory();

    // Support NodeJS & Component, which allow module.exports to be a function
    if (typeof module === 'object' && module && module.exports) {
      exports = module.exports = randomColor;
    }

    // Support CommonJS 1.1.1 spec
    exports.randomColor = randomColor;

    // Support vanilla script loading
  } else {
    root.randomColor = factory();
  }

}(this, function() {

  // Seed to get repeatable colors
  var seed = null;

  // Shared color dictionary
  var colorDictionary = {};

  // Populate the color dictionary
  loadColorBounds();

  var randomColor = function(options) {

    options = options || {};

    // Check if there is a seed and ensure it's an
    // integer. Otherwise, reset the seed value.
    if (options.seed !== undefined && options.seed !== null && options.seed === parseInt(options.seed, 10)) {
      seed = options.seed;

      // A string was passed as a seed
    } else if (typeof options.seed === 'string') {
      seed = stringToInteger(options.seed);

      // Something was passed as a seed but it wasn't an integer or string
    } else if (options.seed !== undefined && options.seed !== null) {
      throw new TypeError('The seed value must be an integer or string');

      // No seed, reset the value outside.
    } else {
      seed = null;
    }

    var H, S, B;

    // Check if we need to generate multiple colors
    if (options.count !== null && options.count !== undefined) {

      var totalColors = options.count,
        colors = [];

      options.count = null;

      while (totalColors > colors.length) {

        // Since we're generating multiple colors,
        // incremement the seed. Otherwise we'd just
        // generate the same color each time...
        if (seed && options.seed) options.seed += 1;

        colors.push(randomColor(options));
      }

      options.count = totalColors;

      return colors;
    }

    // First we pick a hue (H)
    H = pickHue(options);

    // Then use H to determine saturation (S)
    S = pickSaturation(H, options);

    // Then use S and H to determine brightness (B).
    B = pickBrightness(H, S, options);

    // Then we return the HSB color in the desired format
    return setFormat([H, S, B], options);
  };

  function pickHue(options) {

    var hueRange = getHueRange(options.hue),
      hue = randomWithin(hueRange);

    // Instead of storing red as two seperate ranges,
    // we group them, using negative numbers
    if (hue < 0) {
      hue = 360 + hue;
    }

    return hue;

  }

  function pickSaturation(hue, options) {

    if (options.luminosity === 'random') {
      return randomWithin([0, 100]);
    }

    if (options.hue === 'monochrome') {
      return 0;
    }

    var saturationRange = getSaturationRange(hue);

    var sMin = saturationRange[0],
      sMax = saturationRange[1];

    switch (options.luminosity) {

      case 'bright':
        sMin = 55;
        break;

      case 'dark':
        sMin = sMax - 10;
        break;

      case 'light':
        sMax = 55;
        break;
    }

    return randomWithin([sMin, sMax]);

  }

  function pickBrightness(H, S, options) {

    var bMin = getMinimumBrightness(H, S),
      bMax = 100;

    switch (options.luminosity) {

      case 'dark':
        bMax = bMin + 20;
        break;

      case 'light':
        bMin = (bMax + bMin) / 2;
        break;

      case 'random':
        bMin = 0;
        bMax = 100;
        break;
    }

    return randomWithin([bMin, bMax]);
  }

  function setFormat(hsv, options) {

    switch (options.format) {

      case 'hsvArray':
        return hsv;

      case 'hslArray':
        return HSVtoHSL(hsv);

      case 'hsl':
        var hsl = HSVtoHSL(hsv);
        return 'hsl(' + hsl[0] + ', ' + hsl[1] + '%, ' + hsl[2] + '%)';

      case 'hsla':
        var hslColor = HSVtoHSL(hsv);
        var alpha = options.alpha || Math.random();
        return 'hsla(' + hslColor[0] + ', ' + hslColor[1] + '%, ' + hslColor[2] + '%, ' + alpha + ')';

      case 'rgbArray':
        return HSVtoRGB(hsv);

      case 'rgb':
        var rgb = HSVtoRGB(hsv);
        return 'rgb(' + rgb.join(', ') + ')';

      case 'rgba':
        var rgbColor = HSVtoRGB(hsv);
        var alpha = options.alpha || Math.random();
        return 'rgba(' + rgbColor.join(', ') + ', ' + alpha + ')';

      default:
        return HSVtoHex(hsv);
    }

  }

  function getMinimumBrightness(H, S) {

    var lowerBounds = getColorInfo(H).lowerBounds;

    for (var i = 0; i < lowerBounds.length - 1; i++) {

      var s1 = lowerBounds[i][0],
        v1 = lowerBounds[i][1];

      var s2 = lowerBounds[i + 1][0],
        v2 = lowerBounds[i + 1][1];

      if (S >= s1 && S <= s2) {

        var m = (v2 - v1) / (s2 - s1),
          b = v1 - m * s1;

        return m * S + b;
      }

    }

    return 0;
  }

  function getHueRange(colorInput) {

    if (typeof parseInt(colorInput) === 'number') {

      var number = parseInt(colorInput);

      if (number < 360 && number > 0) {
        return [number, number];
      }

    }

    if (typeof colorInput === 'string') {

      if (colorDictionary[colorInput]) {
        var color = colorDictionary[colorInput];
        if (color.hueRange) {
          return color.hueRange;
        }
      }
    }

    return [0, 360];

  }

  function getSaturationRange(hue) {
    return getColorInfo(hue).saturationRange;
  }

  function getColorInfo(hue) {

    // Maps red colors to make picking hue easier
    if (hue >= 334 && hue <= 360) {
      hue -= 360;
    }

    for (var colorName in colorDictionary) {
      var color = colorDictionary[colorName];
      if (color.hueRange &&
        hue >= color.hueRange[0] &&
        hue <= color.hueRange[1]) {
        return colorDictionary[colorName];
      }
    }
    return 'Color not found';
  }

  function randomWithin(range) {
    if (seed === null) {
      return Math.floor(range[0] + Math.random() * (range[1] + 1 - range[0]));
    } else {
      //Seeded random algorithm from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
      var max = range[1] || 1;
      var min = range[0] || 0;
      seed = (seed * 9301 + 49297) % 233280;
      var rnd = seed / 233280.0;
      return Math.floor(min + rnd * (max - min));
    }
  }

  function HSVtoHex(hsv) {

    var rgb = HSVtoRGB(hsv);

    function componentToHex(c) {
      var hex = c.toString(16);
      return hex.length == 1 ? '0' + hex : hex;
    }

    var hex = '#' + componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);

    return hex;

  }

  function defineColor(name, hueRange, lowerBounds) {

    var sMin = lowerBounds[0][0],
      sMax = lowerBounds[lowerBounds.length - 1][0],

      bMin = lowerBounds[lowerBounds.length - 1][1],
      bMax = lowerBounds[0][1];

    colorDictionary[name] = {
      hueRange: hueRange,
      lowerBounds: lowerBounds,
      saturationRange: [sMin, sMax],
      brightnessRange: [bMin, bMax]
    };

  }

  function loadColorBounds() {

    defineColor(
      'monochrome',
      null, [
        [0, 0],
        [100, 0]
      ]
    );

    defineColor(
      'red', [-26, 18], [
        [20, 100],
        [30, 92],
        [40, 89],
        [50, 85],
        [60, 78],
        [70, 70],
        [80, 60],
        [90, 55],
        [100, 50]
      ]
    );

    defineColor(
      'orange', [19, 46], [
        [20, 100],
        [30, 93],
        [40, 88],
        [50, 86],
        [60, 85],
        [70, 70],
        [100, 70]
      ]
    );

    defineColor(
      'yellow', [47, 62], [
        [25, 100],
        [40, 94],
        [50, 89],
        [60, 86],
        [70, 84],
        [80, 82],
        [90, 80],
        [100, 75]
      ]
    );

    defineColor(
      'green', [63, 178], [
        [30, 100],
        [40, 90],
        [50, 85],
        [60, 81],
        [70, 74],
        [80, 64],
        [90, 50],
        [100, 40]
      ]
    );

    defineColor(
      'blue', [179, 257], [
        [20, 100],
        [30, 86],
        [40, 80],
        [50, 74],
        [60, 60],
        [70, 52],
        [80, 44],
        [90, 39],
        [100, 35]
      ]
    );

    defineColor(
      'purple', [258, 282], [
        [20, 100],
        [30, 87],
        [40, 79],
        [50, 70],
        [60, 65],
        [70, 59],
        [80, 52],
        [90, 45],
        [100, 42]
      ]
    );

    defineColor(
      'pink', [283, 334], [
        [20, 100],
        [30, 90],
        [40, 86],
        [60, 84],
        [80, 80],
        [90, 75],
        [100, 73]
      ]
    );

  }

  function HSVtoRGB(hsv) {

    // this doesn't work for the values of 0 and 360
    // here's the hacky fix
    var h = hsv[0];
    if (h === 0) {
      h = 1;
    }
    if (h === 360) {
      h = 359;
    }

    // Rebase the h,s,v values
    h = h / 360;
    var s = hsv[1] / 100,
      v = hsv[2] / 100;

    var h_i = Math.floor(h * 6),
      f = h * 6 - h_i,
      p = v * (1 - s),
      q = v * (1 - f * s),
      t = v * (1 - (1 - f) * s),
      r = 256,
      g = 256,
      b = 256;

    switch (h_i) {
      case 0:
        r = v;
        g = t;
        b = p;
        break;
      case 1:
        r = q;
        g = v;
        b = p;
        break;
      case 2:
        r = p;
        g = v;
        b = t;
        break;
      case 3:
        r = p;
        g = q;
        b = v;
        break;
      case 4:
        r = t;
        g = p;
        b = v;
        break;
      case 5:
        r = v;
        g = p;
        b = q;
        break;
    }

    var result = [Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)];
    return result;
  }

  function HSVtoHSL(hsv) {
    var h = hsv[0],
      s = hsv[1] / 100,
      v = hsv[2] / 100,
      k = (2 - s) * v;

    return [
      h,
      Math.round(s * v / (k < 1 ? k : 2 - k) * 10000) / 100,
      k / 2 * 100
    ];
  }

  function stringToInteger(string) {
    var total = 0
    for (var i = 0; i !== string.length; i++) {
      if (total >= Number.MAX_SAFE_INTEGER) break;
      total += string.charCodeAt(i)
    }
    return total
  }

  return randomColor;
}));


// https://24ways.org/2010/calculating-color-contrast/
function getContrast(hexcolor) {
  hexcolor = hexcolor.replace('#', '');
  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';
}

function genColors(num) {
  var color, bg, text, colorset, colors = [];
  for (var i = 0; i <= num; i++) {
    color = randomColor();
    text = getContrast(color);
    bg = color;
    colorset = text + ',' + bg;
    colors.push(colorset);
  }
  return colors;
}

var colors = genColors(256);

for (var i = 0; i < colors.length; i++) {
  var set = colors[i].split(',');
  var text = set [0];
  var bg = set [1];
  var holdyDiv = $('<div style=" color:' + text + '; background-color:' + bg + '; display:inline-block; padding:25px;">test</div>').attr('id', 'holdy');
  holdyDiv.appendTo('body');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>