JavaScript: Color changing page elements - animated

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

Post Reply
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

JavaScript: Color changing page elements - animated

Post by Chris Corbyn »

Not really for critique, just thought someone might use it somewhere.

Code: Select all

/**
 * Fade the background-color of an object from one to another
 * @param {Element} The target element
 * @param {Array} The starting (Red, Green, Blue) as decimal 0-255
 * @param {Array} The wanted (Red, Green, Blue) as decimal 0-255
 * @param {Integer} The amount to adjust each color by at each frame (default to 3)
 * @param {Integer} The number of milliseconds between each frame (default to 100)
 * @return void
 */
function colorTransition(obj, start, end, increment, interval)
{
	//Set some defaults
	if (!increment) increment = 3;
	if (!interval) interval = 100;
	var R = 0, G = 1, B = 2;
	
	//End recursion if all end values reached
	if (start[R] == end[R] && start[G] == end[G] && start[B] == end[B]) return;
	
	//Adjust values for each color
	for (var color = R; color < B; color++) {
		if (start[color] < end[color]) {
			start[color] += parseInt(increment);
			if (start[color] > end[color]) { start[color] = end[color]; } //Fix if out of bounds
		}
		else {
			start[color] -= parseInt(increment);
			if (start[color] < end[color]) { start[color] = end[color]; }
		}
	}
	
	//Set the element's style to the requested color
	var rgb = "rgb(" + start[R].toString() + "," + start[G].toString() + "," + start[B].toString() + ")";
	obj.style.backgroundColor = rgb;
	
	//Wait for the interval, then change the color again
	window.setTimeout(function() { colorTransition(obj, start, end, parseInt(increment), parseInt(interval)); }, parseInt(interval));
}
I use it to draw attention to messages such as "Message successfully submitted" etc like what happens in WordPress.

Usage:

Code: Select all

<div id="foo">Some text</div>
<script type="text/javascript"><!--

//fade from white to black
colorTransition(document.getElementById("foo"), new Array(255,255,255), new Array(0,0,0));

//fade from red to blue
colorTransition(document.getElementById("foo"), new Array(255,0,0), new Array(0,0,255));

//fade from yellow to green, with a 50ms interval and a transition of 10 shades-per-frame
colorTransition(document.getElementById("foo"), new Array(255,255,0), new Array(0,255,0), 10, 50);

// --></script>
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

That's pretty cool.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

Something strange. Your "fade from white to black" goes from white to blue, and your "fade from red to blue" goes from red to black (Firefox).
(#10850)
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

arborint wrote:Something strange. Your "fade from white to black" goes from white to blue, and your "fade from red to blue" goes from red to black (Firefox).
Obviously I can't copy&paste :P

Code: Select all

/**
 * Fade the background-color of an object from one to another
 * @param {Element} The target element
 * @param {Array} The starting (Red, Green, Blue) as decimal 0-255
 * @param {Array} The wanted (Red, Green, Blue) as decimal 0-255
 * @param {Integer} The amount to adjust each color by at each frame (default to 3)
 * @param {Integer} The number of milliseconds between each frame (default to 100)
 * @return void
 */
function colorTransition(obj, start, end, increment, interval)
{
        //Set some defaults
        if (!increment) increment = 3;
        if (!interval) interval = 100;
        var R = 0, G = 1, B = 2;
       
        //End recursion if all end values reached
        if (start[R] == end[R] && start[G] == end[G] && start[B] == end[B]) return;
       
        //Adjust values for each color
        for (var color = R; color <= B; color++) {
                if (start[color] < end[color]) {
                        start[color] += parseInt(increment);
                        if (start[color] > end[color]) { start[color] = end[color]; } //Fix if out of bounds
                }
                else {
                        start[color] -= parseInt(increment);
                        if (start[color] < end[color]) { start[color] = end[color]; }
                }
        }
       
        //Set the element's style to the requested color
        var rgb = "rgb(" + start[R].toString() + "," + start[G].toString() + "," + start[B].toString() + ")";
        obj.style.backgroundColor = rgb;
       
        //Wait for the interval, then change the color again
        window.setTimeout(function() { colorTransition(obj, start, end, parseInt(increment), parseInt(interval)); }, parseInt(interval));
}
The line I changed was :

Code: Select all

//from
for (var color = R; color < B; color++) {

//to
for (var color = R; color <= B; color++) {
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Ok, now check out this simple modification: added a chain parameter so you can fade from color-to-color-to-color-to-color etc.

Code: Select all

/**
 * Fade the background-color of an object from one to another
 * @param {Element} The target element
 * @param {Array} The starting (Red, Green, Blue) as decimal 0-255
 * @param {Array} The wanted (Red, Green, Blue) as decimal 0-255
 * @param {Integer} The amount to adjust each color by at each frame (default to 3)
 * @param {Integer} The number of milliseconds between each frame (default to 100)
 * @param {Function} A callback to chain to the next tranisition
 * @return void
 */
function colorTransition(obj, start, end, increment, interval, chainTo)
{
        //Set some defaults
        if (!increment) increment = 3;
        if (!interval) interval = 100;
        var R = 0, G = 1, B = 2;
       
        //End recursion if all end values reached
        if (start[R] == end[R] && start[G] == end[G] && start[B] == end[B])
        {
            if (chainTo) { chainTo(); } //Chain if wanted
            return;
        }
       
        //Adjust values for each color
        for (var color = R; color <= B; color++) {
                if (start[color] < end[color]) {
                        start[color] += parseInt(increment);
                        if (start[color] > end[color]) { start[color] = end[color]; } //Fix if out of bounds
                }
                else {
                        start[color] -= parseInt(increment);
                        if (start[color] < end[color]) { start[color] = end[color]; }
                }
        }
       
        //Set the element's style to the requested color
        var rgb = "rgb(" + start[R].toString() + "," + start[G].toString() + "," + start[B].toString() + ")";
        obj.style.backgroundColor = rgb;
       
        //Wait for the interval, then change the color again
        window.setTimeout(function() { colorTransition(obj, start, end, parseInt(increment), parseInt(interval)); }, parseInt(interval));
}
Example of using a chained transition:

Code: Select all

<div id="foo">Color Transition Demo</div>
<script type="text/javascript">

var el = document.getElementById("foo");

colorTransition(el, new Array(255, 255, 0), new Array(0, 255, 0), 3, 50,
        function() {
                colorTransition(el, new Array(0, 255, 0), new Array(255, 0, 0), 3, 50,
                        function() {
                                colorTransition(el, new Array(255, 0, 0), new Array(0, 255, 255), 3, 50);
                        });
        });

</script>
Demo: http://www.w3style.co.uk/~d11wtq/testcolor.html
Post Reply