Page 1 of 1

JavaScript: Color changing page elements - animated

Posted: Fri Jan 12, 2007 9:25 am
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>

Posted: Fri Jan 12, 2007 12:00 pm
by matthijs
That's pretty cool.

Posted: Fri Jan 12, 2007 5:16 pm
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).

Posted: Sat Jan 13, 2007 8:20 am
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++) {

Posted: Sat Jan 13, 2007 8:36 am
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