javascript, math, and color

in my previous article about the crazy squares i showed you how i do the mousemove() triggered, random square manipulation using JQuery and a bit of raw javascript.

in this entry, i’ll talk about how we can manipulate colors as numbers.

step 1: draw the squares

i’ve stolen my square-filled <div> from the previous demo, but this time the squares start out black.

.demo-square {
   float:left;
   width:28px;
   height:28px;
   background:#000;
   margin:1px;
}

the javascript that creates them:

var cols = 10;
var rows = 6;
for(x=0; x<(cols * rows); x++) {
  $("<div>")
  .clone(false)
  .appendTo("#demo")
  .addClass("demo-square")
}
<div id="demo"></div>

pretty boring.

step 2: alter the colors

notice we make a loop to create the squares. loops are great for incrementally doing math ($something++).

also, colors can be expressed not only in the hexadecimal #AABBCC, but also numerically from 0-225, e.g. rgb(000,120,255)

so if we wanted the squares to fade slowly from black to white, we need to take the number of squares, divide 255 by that number, and add that amount to each of the r,g,b values on every loop. (here i’m manipulating all r,g,b values equally – if you want to play with color, you can change them separately)

that loop looks like this:

var increment = 255 / ((cols * rows)-2);
var current = 0;
for(x=0; x<(cols * rows); x++) {
   rounded = Math.round(current);
   $("<div>")
   .clone(false)
   .appendTo("#demo")
   .addClass("demo-square")
   .css("background","rgb("+rounded+","+rounded+","+rounded+")");
   current += increment;
}

notes:

  • rounding – CSS doesn’t like decimals in rgb() values)
  • for the increment value, i subtract two from cols * rows, because we want the first one fully black, and the last one fully white.

step 3: random, and other uses

i know, i don’t have a big sweeping gradient in the back. i have random shades. the theory is the same, to loop through every square and alter it’s rgb() value, but instead of incrementing it, we pick a (rounded) random value every time.

var rand = 0;
for(x=0; x<(cols * rows); x++) {
  rand = Math.round(Math.random()*255);
  $("<div>")
  .clone(false)
  .appendTo("#demo")
  .addClass("demo-square")
  .css("background","rgb("+rand+","+rand+","+rand+")");
}

my last demo showed how random things could happen with mousemove(). do you want the squares to react to user input as they mouse over them individually? we’ll tie the change to the hover() event on each square.

for(x=0; x<(cols * rows); x++) {
   $("<div>")
   .clone(false)
   .appendTo("#demo")
   .addClass("demo-square")
   .css("background","#000000")
   .hover(function() {
      rand = Math.round(Math.random()*255);
   $(this).css("background","rgb("+rand+","+rand+","+rand+")")
  })
}

(mouse over the div below to see it in action)

you could do something interesting with opacity and images (for browsers that support it):

add an image to the background of the container with CSS:

#demo {
  background:url('/images/demo.jpg') top left no-repeat;
}

and adjust the opacity of each square to a random value (divided by two here to make it reveal more of the image)

for(x=0; x<(cols * rows); x++) {
  $("<div>")
  .clone(false)
  .appendTo("#demo")
  .addClass("demo-square")
  .css("background","#000000")
  .css("opacity",Math.random()/2)
}

is there any practical usage for this? i think so. creating an appealing or joyful experience is practical because it makes the user happy. a happy user will read/learn/buy/share.

i hope you’ll consider using clever technology to make fun and functional designs for your users. if you do, please contact me and let me know how this inspired your own creations!