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>

3
  • 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 :-) Commented Feb 25, 2015 at 0: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. Commented Feb 25, 2015 at 1:25
  • Working demo: jsfiddle.net/jfriend00/ysg4f870 Commented Feb 25, 2015 at 1:36

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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

1 Comment

Thanks for pointing that out. Had an error in reasoning there.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.