3

I've been trying to create a JavaScript function which loops fast through all the 24bit of the rgb-values and displays them in form of a dynamiclly changing div-background

In order to slow the process down enough to see something I was thinking of using the setTimeout method. I did some research on using setTimeout in loops and found this.

setTimeout in for-loop does not print consecutive values

Seems to be describing my problem perfectly. I tried to use the solutions given there. But for some reason it does not work.

Edit: It works now (It uses setInterval, because that makes probably more sense here)

<script> 

function setColor(i) {
   var c = i.toString(16);
   
   switch(c.length) {
   case 1:
    c = "00000" + c;
    break;
   case 2:
    c = "0000" + c;
    break;
   case 3:
    c = "000" + c;
    break;
   case 4:
    c = "00" + c;
    break;
   case 5:
    c = "0" + c;
    break;
   default:
      c;
 }
   document.getElementById("colorContainer").style.background = "#" + c;
   
   
}

function loopThroughColors() {
 var i = 0x000000;
 setInterval(function(intervalId) {
   setColor(i);
   i += 1;
   if (i >= 0xffffff) {
  clearInterval(intervalId);
   }
 }, 100);
}


 </script>
Community
  • 1
  • 1
BigGrin
  • 33
  • 4
  • 1
    You need to pass a function to `setTimeout`. The call to `setColor` doesn't return one. Try adding a function expression closure. Look more closely at those answers :-) – Bergi Feb 25 '15 at 00:37
  • Several problems. First off, you're firing ALL the `setTimeout()` requests at once. Second off, in this `setTimeout(setColor(i), 100);`, you're calling `setColor(i)` immediately and then passing the return value from that to `setTimeout()`. So, all your `setColor(i)` calls happen immediately. – jfriend00 Feb 25 '15 at 01:25
  • Working demo: http://jsfiddle.net/jfriend00/ysg4f870/ – jfriend00 Feb 25 '15 at 01:36

2 Answers2

1

Your problem is that you can't pass parameters in the call to setTimeout.

Try this instead:

function loopThroughColors() {
    for (var i = 0x000000; i <= 0xffffff; i++) {
        setTimeout(function() {
            setColor(i); 
        }, i); 
    }
}

This way you are giving an anonymous function with no parameters to setTimeout, but that function happens to have the parameter that you want.

As Bergi said, when you try to pass the parameter i to setColor, you're really just evaluating the statement setColor(i). Instead you need to give the name itself of a function.

Zach Sadler
  • 570
  • 3
  • 11
1

I would take a different approach, using setInterval instead of setTimeout, something like:

function setColor(i) {
  var c = i.toString(16);
  document.getElementById("colorContainer").style.background = "#" + c;
}

var i = 0x100;
setInterval(function(intervalId) {
  setColor(i);
  i += 1;
  if (i >= 0xfff) {
    clearInterval(intervalId);
  }
}, 100);
#colorContainer {
  width: 100px;
  height: 100px;
}
<div id="colorContainer"></div>

Note that there is a bug in setColor - it's not prepending 0s to the string, so all colors before #100000 will not work correctly. I've cheated by only going through colours between #100 and #fff to show that the setInterval can work.

rjmunro
  • 27,203
  • 20
  • 110
  • 132
  • This approach makes so much more sense, I feel stupid :) Thanks a lot! Also, prepended the 0s now, forgot that in the heat of the moment. – BigGrin Feb 25 '15 at 01:31