A Gift of "Life" : The Document Object Model
Multimedia in Microsoft Internet Explorer
What is So Dynamic About Dynamic HTML?
You are here: irt.org | Articles | Dynamic HTML (DHTML) | Fancy Background Fader [ previous next ]
Published on: Sunday 7th June 1998 By: Keith Drakard
Here's a simple little script which cycles the background colour through various RGB values. Select two background colours and watch how different rates of change affect the shades that are displayed during the fade.
I've broken the script into three chunks - initialising the variables, starting and stopping the fade and utility functions used in the fade.
First, we need to parse our form and set the variables accordingly:
function init() { // parse the form, get the select menu options // (start and finish colours + loop method) tmp = document.fader.start.selectedIndex; start = document.fader.start.options[tmp].value; tmp = document.fader.finish.selectedIndex; finish= document.fader.finish.options[tmp].value; tmp = document.fader.loop.selectedIndex; loop = document.fader.loop.options[tmp].value; loopID= 0; // parse the text boxes and get the rates of change of // each of the different colour channels tmp= document.fader.d_r.value; if (tmp>=0 && tmp<=255) d_r= parseInt(tmp); tmp= document.fader.d_g.value; if (tmp>=0 && tmp<=255) d_g= parseInt(tmp); tmp= document.fader.d_b.value; if (tmp>=0 && tmp<=255) d_b= parseInt(tmp); // generate the starting RGB values s_r= split(start,0); s_g= split(start,1); s_b= split(start,2); // and do the same for the final RGB values f_r= split(finish,0); f_g= split(finish,1); f_b= split(finish,2); // work out the difference between the start and finish // colours of each channel l_r= s_r- f_r; l_g= s_g- f_g; l_b= s_b- f_b; // and set the current colour to the starting colour red= s_r; green= s_g; blue= s_b; }
Here's the important bit - the fade works by calculating the difference between the start and finish colours and then gradually reducing this difference by the rate of change for that colour channel (RGB). Large rates of change will therefore result in less of a fading effect.
The function checks to see if the difference is now zero across all channels, and if it is then the loop method determines if (and how) the fade continues.
function startFade() { // in case of multiple clicks on the start button, clear any // waiting loops so that this fade isn't affected clearTimeout(loopID); // create a fading effect by reducing the difference between the // current and final RGB channels (according to the rates of change) if (l_r< 0-d_r) l_r+=d_r; else { if (l_r> 0+d_r) l_r-=d_r; else l_r=0; } if (l_g< 0-d_g) l_g+=d_g; else { if (l_g> 0+d_g) l_g-=d_g; else l_g=0; } if (l_b< 0-d_b) l_b+=d_b; else { if (l_b> 0+d_b) l_b-=d_b; else l_b=0; } // have we closed the difference to zero? if (l_r== 0 && l_g== 0 && l_b== 0) { // what type of loop do we want to do? if (loop== 0) { // then stop fading about stopFade(); } else { // we're looping again, so reset the amount of each colour left l_r= f_r- s_r; l_g= f_g- s_g; l_b= f_b- s_b; if (loop== 1) { // two-way fade (swap start and finish colours) tmp= s_r; s_r= f_r; f_r= tmp; // swap red channel tmp= s_g; s_g= f_g; f_g= tmp; // swap green channel tmp= s_b; s_b= f_b; f_b= tmp; // swap blue channel } else { // one-way fade (do nothing, act naturally) } // and prepare to do it all again loopID= setTimeout("startFade()",1); } } else { // business as usual, update the current colour red= l_r+ f_r; green= l_g+ f_g; blue= l_b+ f_b; // set the background to this colour document.bgColor= getHex(red,green,blue); // and prepare to do it all again loopID= setTimeout("startFade()",1); } } function stopFade() { // set the background colour to the finish colour and end document.bgColor= '#'+DecToHex(f_r)+DecToHex(f_g)+DecToHex(f_b); clearTimeout(loopID); }
The last bits of JavaScript we need are the four utility functions which deal with parsing and creating colour values and converting between hexadecimal and decimal values:
function split(colour, which_pair) { // take a hex string and a string position and return the decimal // value of that pair (0xFF= 255 etc..) return HexToDec(colour.substring(0+ (which_pair* 2), 2+ (which_pair* 2))); } function getHex(r,g,b) { // convert 3 dec integers to hex strings and use as a colour value return '#'+DecToHex(r)+DecToHex(g)+DecToHex(b); } var hexbase="0123456789ABCDEF"; function DecToHex(number) { // take a decimal integer, return 2-digit hex string return hexbase.charAt((number>> 4)& 0xf)+ hexbase.charAt(number& 0xf); } function HexToDec(number) { // take a hex string, return decimal integer return parseInt(number.toUpperCase(), 16); }
This is only needed if you don't intend to hardwire the colour options:
<FORM NAME="fader"> <TABLE WIDTH=350 CELLSPACING=0 CELLPADDING=3 BORDER=0> <TR BGCOLOR="#cccccc"> <TD COLSPAN=3 ALIGN=right>Fade from: <SELECT NAME="start"> <OPTION VALUE="0000FF">Blue <OPTION VALUE="00FF00">Green <OPTION VALUE="FFA500">Orange <OPTION VALUE="FF0000">Red <OPTION VALUE="FFFF00">Yellow </SELECT></TD> <TD ALIGN=right>Loop: <SELECT NAME="loop"> <OPTION VALUE="0">Fade once <OPTION VALUE="1" SELECTED>2-way fade <OPTION VALUE="2">1-way fade </SELECT></TD> </TR> <TR BGCOLOR="#cccccc"> <TD COLSPAN=3 ALIGN=right>to: <SELECT NAME="finish"> <OPTION VALUE="0000FF">Blue <OPTION VALUE="00FF00">Green <OPTION VALUE="FFA500">Orange <OPTION VALUE="FF0000">Red <OPTION VALUE="FFFF00">Yellow </SELECT></TD> <TD ROWSPAN=3 VALIGN=middle ALIGN=center> <INPUT TYPE="button" onClick="init();startFade()" VALUE="Start"> <BR><INPUT TYPE="button" onClick="stopFade()" VALUE="Stop"></TD> </TR> <TR BGCOLOR="#cccccc"> <TD BGCOLOR="#333333" COLSPAN=3 ALIGN=center><FONT COLOR="#ffffff"> Rate of change in colour channel (0 to 255): </FONT></TD> </TR> <TR> <TD BGCOLOR="#cc6666" ALIGN=right><B>R</B> <INPUT TYPE="text" SIZE="2" NAME="d_r" VALUE="6"></TD> <TD BGCOLOR="#66cc66" ALIGN=right><B>G</B> <INPUT TYPE="text" SIZE="2" NAME="d_g" VALUE="4"></TD> <TD BGCOLOR="#6666cc" ALIGN=right><B>B</B> <INPUT TYPE="text" SIZE="2" NAME="d_b" VALUE="1"></TD> </TR> </TABLE> </FORM>
View the source code of the working script.
Further things you could do with this script:
A Gift of "Life" : The Document Object Model
Multimedia in Microsoft Internet Explorer
What is So Dynamic About Dynamic HTML?
Building a Dynamic Thank You Page