SexyMF
SexyMF

Reputation: 11185

Javascript - Generate random dark color

I have this method to generate me random colors for font:

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

The problem is that the font is always on white background, I want to generate dark colors.
Is it possible?
Thanks

Upvotes: 13

Views: 24078

Answers (5)

mjnewsum
mjnewsum

Reputation: 1

I don't think my solution is represented here, so I will add it in (even though I am very late to the game).

I am just subtracting from the 255 random range on each value. Seems to work well and is very simple. If you wanted RandomColorLight, just add the offset value to the random result of each component.

You can also combine the two into one RandomColorRange method very easily.

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);
}

Sorry, my solution is not javascript. It is C#, but the logic should be easy enough to understand.

Upvotes: 0

Zaheer Ahmed
Zaheer Ahmed

Reputation: 28588

As you know RGB at 0,0,0 is black the darkest and it goes toward getting light until (255,255,255) so you can stop it to go above 100, to get only dark colors or say 9 in hex:

Here is jsFiddle

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

Upvotes: 15

Weilory
Weilory

Reputation: 3121

// 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

This allows the existence of large hex value such as f, c, b, etc, but at a low occurrence.

1500 bytes for you. But works awesome!

Upvotes: 0

Ganesh Jadhav
Ganesh Jadhav

Reputation: 2848

Take any random digit from 0-5 as the first digit of your color and then choose the rest of the five digits using your above code.

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
}

Upvotes: 9

Tom Prats
Tom Prats

Reputation: 7931

You could use a custom function that takes a hex and darkens it by the percent lum. You can modify it to return whatever you want back

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;
}

You could also just use hsl (Hugh, Saturation, Luminosity or Lightness). The hsl link actually goes through the above code.

Upvotes: 5

Related Questions