Javascript - 生成随机暗色

12

我有一种方法可以为字体生成随机颜色:

function getRandomRolor() {
     var letters = '0123456789ABCDEF'.split('');
     var color = '#';
     for (var i = 0; i < 6; i++) {
         color += letters[Math.round(Math.random() * 15)];
     }
     return color;
}  

问题是字体总是在白色背景上,我想生成深色。
这可能吗?
谢谢


将字母集合(对于每一对中的第一个字母)缩小,直到不再生成过亮的颜色?或者问题是您仍想能够生成“#0000FF”吗?无论如何 - 定义“过亮”的含义。 - John Dvorak
@JanDvorak - 我想生成一些可读的白色上方内容。我不理解你的例子,能否请您提供一个例子?谢谢。 - SexyMF
只需摆脱那个 0123 字符串的后半部分即可。 - Dagg Nabbit
5个回答

13

正如您所知道的,RGB 值在 0,0,0 时为黑色,最暗的颜色,向 (255,255,255) 越来越亮。因此,您可以阻止它超过 100,只获取深色或十六进制中的 9:

这里是 jsFiddle

function getDarkColor() {
    var color = '#';
    for (var i = 0; i < 6; i++) {
        color += Math.floor(Math.random() * 10);
    }
    return color;
}

3
有时候你会在颜色值中的一个数字上看到 'undefined',因为例如 Math.round(9.6) 会四舍五入成 '10',而这个下标超出了 letters 数组的范围。建议使用 Math.floor 来解决这个问题。此外,我认为使用 letters 数组没有任何意义,可以直接把数字附加到 color 字符串中。 - trungly
8
也许它不应该被称为 getRandomRolor() - Squirrl
同时它缺少A、B、C、D、E、F十六进制值。 - hellowill89

9

0-5 中随机选择一个数字作为颜色的第一位,然后使用上述代码选择其余的五位数字。

JS Fiddle: http://jsfiddle.net/xP5v8/

var color,
       letters = '0123456789ABCDEF'.split('')
function AddDigitToColor(limit)
{
    color += letters[Math.round(Math.random() * limit )]
}
function GetRandomColor() {
    color = '#'
    AddDigitToColor(5)
    for (var i = 0; i < 5; i++) {
        AddDigitToColor(15)
    }
    return color
}

5
这不只是让它变得不那么红吗? - trungly

5

您可以使用自定义函数,通过百分比 lum 使十六进制颜色变暗。您可以修改它以返回您想要的任何内容。

function ColorLuminance(hex, lum) {
  // 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;
}

你也可以使用 hsl (色相、饱和度、亮度或明度)。 hsl链接实际上通过上述代码。


谢谢。这正是我所需要的。 - Timothy

0
我认为我的解决方案在这里没有被提及,所以我会加上它(尽管我来晚了)。
我只是从每个值的255个随机范围中减去。似乎效果很好并且非常简单。如果您想要RandomColorLight,只需将偏移值添加到每个组件的随机结果中即可。
您还可以将两者合并为一个RandomColorRange方法,非常容易。
public static Color RandomColorDark(int offset)
{
    var maxValue = 256 - offset;
    return Color.FromArgb(_random.Next(maxValue), _random.Next(maxValue), _random.Next(maxValue));
}
public static Color RandomColorLight(int offset)
{
    var maxValue = 256 - offset;
    return Color.FromArgb(_random.Next(maxValue) + offset, _random.Next(maxValue) + offset, _random.Next(maxValue) + offset);
}

抱歉,我的解决方案不是JavaScript。它是C#,但逻辑应该很容易理解。


0
// seperate array by index
// [0, 1, 2, 3], 2 => [2, 3, 1, 0]
function tail(arr, ind){
    let mhs, lhs;
    if(arr.length / 2 > ind){
        mhs = arr.length - 1 - ind;
        lhs = ind;
    }else{
        mhs = ind;
        lhs = arr.length - 1 - ind;
    }
    let nd = [arr[ind]];
    for(let i = 0; i < lhs; i++){
        nd.push(arr[ind+i+1]);
        nd.push(arr[ind-i-1]);
    }
    for(let i = 0; i < mhs - lhs; i++){
        nd.push(arr[i]);
    }
    return nd;
}

// yield optimization
// 6=>6 6=>3
// 5=>5 5=>3
// 4=>4 4=>2
// 3=>3 3=>2
// 2=>2 2=>1
// 1=>1 1=>1
// 21   12
function dense(len, den){
    let st = Math.ceil(len / den);
    let nd = [];
    for(let i = 0; i < st; i++){
        for(let j = 0; j < den; j++){
            nd.push(st - i);
        }
    }
    if(len % 2 !== 0){
        nd.shift();
    }
    return nd;
}

// shift the weight to certain part of array by index
// de controls the rate of differing
function shift_weight(arr, ind, de){
    let ta = tail(arr, ind);
    let nd = [];
    let den = dense(arr.length, de)
    for(let i = 0; i < ta.length; i++){
        for(let j = 0; j < den[i]; j++){
            nd.push(ta[i]);
        }
    }
    return nd;
}

function parseDarkHex(den){
  let hexcode = '0123456789abcdef';
  let ocean = shift_weight(Array.from({length: 16}, (x, i) => hexcode[i]), 0, den);
  return '#' + Array.from({length: 6}).map(ud=>ocean[Math.floor(Math.random() * ocean.length)]).join('');
}

function parseLightHex(den){
  let hexcode = '0123456789abcdef';
  let ocean = shift_weight(Array.from({length: 16}, (x, i) => hexcode[i]), 16, den);
  return '#' + Array.from({length: 6}).map(ud=>ocean[Math.floor(Math.random() * ocean.length)]).join('');
}

// 2~8, the smaller the more accurate, the larger the faster
console.log(parseDarkHex(4))

// #51baaa
// #046d1c
// #003183

这允许存在大的十六进制值,例如f, c, b等,但出现频率较低。

对于您来说是1500字节。但效果非常棒!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接