0

I'm building a blog theme for Anchor CMS and I have a question regarding randomly assigning background colors to divs.

I have a working script which assigns a color randomly to each div with the post class. What I'd like to know is if I can set the color once - say, when the post is published - and have it persist on each page load rather than resetting.

Here's my function:

$(".post").each(function randomColor() {
        var color = "#"+(Math.random()*0xFFFFFF<<0).toString(16);
        $(this).css("background-color", color)
      })

I'm thinking that I could create an array in the blog registry using PHP and pass values into it based on the post ID, but I don't want to overcomplicate the process if there's a simpler method.

A nice extension, but not necessary, would be to carry that color over to the post itself when the user visits it.

Any thoughts?

Edit - You can see my demo site to get an idea of what the theme looks like. The random color addition is not implemented there as of right now.

Brian
  • 4,274
  • 2
  • 27
  • 55
  • how unique shoud the color be? – Carlo Moretti Aug 29 '14 at 15:26
  • 2
    You could hash the color based on the content of the post, or seed your rng based on the time of the post. The possibilities are endless. – amphetamachine Aug 29 '14 at 15:26
  • Even if you created the array you would have to store it as well. If you already have a database you could store it there. However if you are storing colors that are going to be used for ever why not just pick the colors and hard code them – GifCo Aug 29 '14 at 15:26
  • Or you could just do a bunch of `:nth-child(387)` in a giant static CSS file with pre-selected random colors. – amphetamachine Aug 29 '14 at 15:27
  • do you have any track of the timestamp the post was published? – Carlo Moretti Aug 29 '14 at 15:28
  • I was going to suggest the hash and random seed ideas as well. Unfortunately you can't seed javascript's native rng - http://stackoverflow.com/questions/521295/javascript-random-seeds – CupawnTae Aug 29 '14 at 15:28
  • @amphetamachine I'm not too familiar with hashing, so I'll have to look into that. It's a pretty minimal theme, so there isn't much to pull from. – Brian Aug 29 '14 at 15:31
  • @Onheiron there is a PHP function for the article timestamp, so yes, I can get that info. How would you use it? – Brian Aug 29 '14 at 15:32
  • what about the ID? do they have a sequential post id? – Carlo Moretti Aug 29 '14 at 15:47
  • Yeah, it's sequential and has a PHP call as well, so I can append something to it. – Brian Aug 29 '14 at 15:49

3 Answers3

0

Some considerations at first:

  1. not all colours are worth using: all possible colours are a lot, but not all of them would look nice in the page (think at all the very dark ones, shades of grey etc.).

  2. even if you keep a certain brightness to them colours, it'd be a good idea to keep them distinguishable (e.g. 00FF00 and 00FE00 are very alike and one won't even notice)

  3. you need to create a subset of "worthy" colours. Let's say you want 25 different colours (which I think is fair given point 1 and 2). So 3 different picks for each RGB which is 3^3 = 27 minus two because when all three are at max and when all three are at min it's gonna be grey (not nice).

  4. so you need a parameter ranging from 1 to 25 sufficiently random among all posts OR a sequential parameter (an auto-incremental ID?) so that the whole set of possible colours is used before starting over again.


postID = /* get your post ID as int */

/* gets a number between 1 and 25 from your post ID */
colourID = (postID % 25) + 1 

/* this tells which "step" to use for each colour */
/* i.e. 20 in base 3 is "202" -> (2*9 + 0*3 + 2*1) = 18 + 2 = 20 */
/* so will keep "step 2" for red, "step 0" for green and "step 2" for blue */
base3ColourID = colourID.toString(3) 

/* this always returns 3 digits */
/* base3ColourID is 1 if ID is 1, we need "001" to have the colour "steps" */
niceB3CID = ("000").substring(base3ColourID.length) + base3ColourID 

/* calculate the actual colours */
red = 65 + 70*(parseInt(niceB3CID.charAt(0)))
green = 65 + 70*(parseInt(niceB3CID.charAt(1)))
blue = 65 + 70*(parseInt(niceB3CID.charAt(2)))

$('.post').css('background-color', "rgb("+red+","+green+","+blue+")")

HERE A FIDDLE IF YOU WANT TO PLAY WITH THEM COLOURS

Edit

edited colour ranges for better colours.

Carlo Moretti
  • 2,213
  • 2
  • 27
  • 41
  • I like this, and I appreciate the explanation. I can't, for the life of me, figure out how to get the post ID programatically. Any pointers on that? – Brian Sep 07 '14 at 02:13
  • you mean how to get the postID from PHP variable to JS? If so in your post tag you can echo the id as an attribute like this `
    ` and then in js `$('.post').each()` and `$(this).attr('data-id')`
    – Carlo Moretti Sep 07 '14 at 09:36
0

You can use the day of the year (0 - 365) the post was published as the first value in an hsl color (0 - 360, you can pick a random number for the 5 days after 360).

I think using hsl() would be a much safer bet as well. You'll know you won't get something completely terrible and the colors will be sort of similar. Here's a small demo...

http://jsbin.com/kagube/1/edit?html,css,output

Bill Criswell
  • 32,161
  • 7
  • 75
  • 66
0

Note, There may be "bug" at

(Math.random()*0xFFFFFF<<0).toString(16)

where , occasionally , the length of the string generated may be 5 , instead of 6 , resulting in an element without a background-color being applied to the elements' style ; i.e.g.,

var arr = [], res = []; 
for (i = 0; i < 100; i++) {
  arr.push((Math.random()*0xFFFFFF<<0).toString(16));
};

$.each(arr, function(k, v) {
  if (v.length < 6) {
    res.push(v);
  }
});

console.log(res.length);

a quick-fix solution is included within piece below

Try

html

<!-- 
     given each "inner-container" element 
     within `.post` "outer-container"
     has some form of `unique-id` -->
<div class="post">
    <span id="a"></span>
    <span id="b"></span>
    <span id="c"></span>
    <span id="d"></span>
    <span id="e"></span>
    <span id="f"></span>
    <span id="g"></span>
    <span id="h"></span>
</div>

js

// this piece could actually be run when the "post" ,
// or element , is generated , instead of each occasion
// the document is loaded .
// the `colors` array could be stored at server , 
// as `json` object ,e.g., "colors.json", or other preferred format ,
// updating when new "post" is created / generated .
// the array generated could contain two members :
// the unique "id" of the "post" , and the color
// associated with that `unique-id`
// the data could then be posted to server
// which updates `colors.json` file with
// new entries
var colors = [];
    $(".post span").each(function(i, el) {
        // `bug` : occasionally returns string having 
        // `length` of `5` , instead of `6`
        var r = ((Math.random()*0xFFFFFF<<0).toString(16));
        // _quickix_ : check `length` of `r` string ,
        // if `< 6` , generate random "number" between 0-9 ,
        // concat to `r`
        r = r.length < 6 ? r + (1 + Math.floor(Math.random() * 9)) : r;
        var color = "#" + r ;

        // apply `color` to `background-color` , here ,
        // if desired
        // $(el).css("background-color", color);

        // push `unique-id , color` pair to `colors` array
        colors.push([el.id, color]);

        // optional , `POST` new `colors` array to server ,
        // adding new entry to `colors.json` ,
        // unique for each `unique-id`
        // $.post("colors.php", {"data" : colors});
      });

// when loading "template" of `html` `.post` "posts" ,
// having unique id's , or , being generated dynamically
// and given `unique-id`'s , apply `color` to each element
// based on `unique-id` and `color` generated for it
// when created

// optional : `$.getJSON("colors.json", function(colors) {});`
// having `$.each()` function at `complete` callback 
// reassembly `colors` associated with `unique-id`'s
$.each(colors, function(k, v) {
   $(".post span[id="+v[0]+"]").css("background-color", v[1])
});

jsfiddle http://jsfiddle.net/guest271314/f895bh53/

guest271314
  • 1
  • 15
  • 104
  • 177