2

I am working on a job board with an always changing quantity of job postings. However each job posting should have a tiered shade of one base color: #219BBE. Here is a sketch of what I am trying to achieve:

Sketch of the shading concept

What I need is a javascript function which changes the shade of a color depending on the number of job_boxes.

So far I found a javascript snippet for generating the shades of #219BBE.

function calculateShades(colorValue) {
  "#219BBE" = colorValue;

// break the hexadecimal color value into R, G, B one-byte components
// and parse into decimal values.
// calculate a decrement value for R, G, and B based on 10% of their
// original values.
var red = parseInt(colorValue.substr(0, 2), 16);
var redDecrement = Math.round(red*0.1);

var green = parseInt(colorValue.substr(2, 2), 16);
var greenDecrement = Math.round(green*0.1);

var blue = parseInt(colorValue.substr(4, 2), 16);
var blueDecrement = Math.round(blue*0.1);

var shadeValues = [];
var redString = null;
var greenString = null;
var blueString = null;

for (var i = 0; i < 10; i++) {
  redString = red.toString(16); // convert red to hexadecimal string
  redString = pad(redString, 2); // pad the string if needed
  greenString = green.toString(16); // convert green to hexadecimal string
  greenString = pad(greenString, 2); // pad the string if needed
  blueString = blue.toString(16); // convert blue to hexadecimal string
  blueString = pad(blueString, 2); // pad the string if needed
  shadeValues[i] = redString + greenString + blueString;

// reduce the shade towards black
  red = red - redDecrement;
  if (red <= 0) {
    red = 0;
  }

  green = green - greenDecrement;
  if (green <= 0) {
    green = 0;
  }

  blue = blue - blueDecrement;
  if (blue <= 0) {
    blue = 0;
  }

}

shadeValues[10] = "000000";
return shadeValues;
}

I simplified the output for this problem: HTML

<!-- Instead of 4 boxes we could also have n boxes -->
<div class="job_box"></div>
<div class="job_box"></div>
<div class="job_box"></div>
<div class="job_box"></div>

CSS

.job_box {
  width: 100%;
  height: 50px;

  /* The dynamic background-color */
  background-color: #219BBE;
}

To count the quantity of job_boxes I would use jQuery:

var numBoxes = $('.job_box').length

And here is the point where I am stuck. I know that I need a loop but that's it. Can you please push me in the right direction?

Fiddle

Retador
  • 223
  • 1
  • 3
  • 11

3 Answers3

5

That is my solution: DEMO

var n = 0;

$('.job_box').each(function() {
    n++;
    lighten($(this), n);
});

function lighten(that, n) {
    var lightenPercent = 15 / n;
    var rgb = that.css('background-color');
    rgb = rgb.replace('rgb(', '').replace(')', '').split(',');
    var red = $.trim(rgb[0]);
    var green = $.trim(rgb[1]);
    var blue = $.trim(rgb[2]);

    red = parseInt(red * (100 - lightenPercent) / 100);
    green = parseInt(green * (100 - lightenPercent) / 100);
    blue = parseInt(blue * (100 - lightenPercent) / 100);

    rgb = 'rgb(' + red + ', ' + green + ', ' + blue + ')';

    that.css('background-color', rgb);
}

You can, on the other hand, darken your base color by changing the / to * when setting the var for percent.

DonJuwe
  • 4,477
  • 3
  • 34
  • 59
3

Looking at your design, there should only be a limited number of divs (say 4-8) and so I would personally try to keep it simple and pre-calculate the background colours and implement it in 8 lines of CSS rather than loads of JavaScript.

e.g.

DIV.job_box:nth-child(0) { background-color: #219BBE; }
DIV.job_box:nth-child(1) { background-color: <nextcol>; }
DIV.job_box:nth-child(2) { background-color: <nextcol>; }
DIV.job_box:nth-child(3) { background-color: <nextcol>; }
DIV.job_box:nth-child(4) { background-color: <nextcol>; }
DIV.job_box:nth-child(5) { background-color: <nextcol>; }
DIV.job_box:nth-child(6) { background-color: <nextcol>; }

I know this isn't the answer to your specific approach but often we go down paths that are much more complicated than they need to be.

Chris Walsh
  • 3,423
  • 2
  • 42
  • 62
  • But what will you do when 4 has more jobs than 1? Edit: When the jobs are always sorted, this sure is the better idea. – Nico O Mar 13 '14 at 10:28
  • Very good idea – I was highly focused on scalibility but probably we will never have like 999 job offers. :D – Retador Mar 13 '14 at 10:29
  • Even the original poster's work in progress isn't scalable because colour changes using such a formula cannot go on forever. Either that or the 'i' loop will run out (say, at 10 as per the code sample). – Chris Walsh Mar 13 '14 at 10:45
1

Try to append the job-count to the objects.

Like this:

<div class="job_box" data-count="22"></div>
<div class="job_box" data-count="12"></div>
<div class="job_box" data-count="5"></div>
<div class="job_box" data-count="1000"></div>

Then get all boxes:

var numBoxes = $('.job_box');

And Loop through them:

numBoxes.each(function(){
    var jobCount = $(this).data("count");
    $(this).css("background-color",'#'+calculateShades(jobCount)); 
});
Nico O
  • 13,762
  • 9
  • 54
  • 69
  • True, this would be a good application for data-count. Tried your code in the fiddle but it didn't work: http://jsfiddle.net/uAW2q/3/ – Retador Mar 13 '14 at 10:38
  • your javascript is not valid. There is no `pad()` in Javscript. But that was not part of the question. Here you can see that `calculateShades` is not working correct. http://jsfiddle.net/uAW2q/4/ – Nico O Mar 13 '14 at 10:43