|
|
|
|
|
|
|
|
|
FADING BACKGROUND COLORS
|
|
A script to change objects background colors repeatedly
|
|
December 2001 |
|
{ @ }
|
|
|
|
|
The purpose and utility of the script
|
|
How it could be used
|
I do not believe or mean this script would be the best to accomplish our goal: I simply mean that, as far as I know, it is one of the rare scripts available out there that accomplish it. The reason I'm not confident on the way we chose to accomplish it doesn't not rely on the fact the script is broken into several subroutines: that is fine, in fact it was necessary to provide you with a way to invoke the script the simpler and more straightforward possible given its complexity (requires 6 arguments). The reason I'm not sure that it would be the best possible script is that I am entirely self-taught: no professors or courses around here to make things easier for me, so if I have a goal in my mind and it involves, this time, the inner workings of hexadecimal calculations, I have to fathom them on my own. So it is quite possible there could be a more plain calculation to achieve it. Whatever the case, the script works, and you're not to find since today many other scripts that would fade the background of a document or of a layer in a way which is cross browser.
What is it for? Well, to some degree it obviously just belong to the set of the fashionable stuff, like those scripts meant to keep a trailing string behind your mouse cursor. But when the problem raised to my mind, I had another purpose: I was thinking of online advertisements: if you dispatch before the user's eyes a layer which advertise some product, you may want to make it more appealing by making it fade and pulse. And, of course, it can be a way to catch the user's attention or to flag the coming to a close of, for instance, a timeout. Instance: what a bout a layer that has the same colour of the document background and on which it is written something with the same colour? You can dispatch it on the foreground and let it fade on so the text would slowly appear.
Of course, we assume you know that a way to store colours is the hexadecimal one, which means a set of three couples, each of which made up of numbers from 0 to 9 or letters from a to f.
So the hexadecimal code for blue is: 0000ff
For red is: ff0000. A darker red may be: cc0000. An even darker one: 550000.
Orange may be: ff6600. Black is: 000000. White is ffffff.
Well, no much sense going on like this, I deem you got it! Last but not least, the html language specifications require that upon passing an hexadecimal value to set a color, you have to pre pone to it a # sign.
Ok, here is your script:
var fadings= new Array()
function fadingOn(startColor, endColor, amount, timing, objDef, path, objectTimer){
//requires: fadingObject(), Array fadings
if(!objDef){ return false}
fadings[(++fadings. length)-1]=
new fadingObject(startColor, endColor, amount, timing, objDef, path, objectTimer);
fadings[fadings. length-1].objectTimer= setInterval("fadings[fadings. length-1].fade()",
fadings[fadings. length-1].timing)
}
/*----------------------------------------------*/
function fadingObject(startColor, endColor, amount, timing, objDef, path, objectTimer, originalCol, originalAmount, originalTime){
//arguments necessary only until PATH included (6 args.)
//path must be passed like a string: "123" or similar combinations
//path numbers not higher than 3, not lower than 1 (for a leading 0 causes problems)
//requires colorFader()
this.startColor=(startColor)?
startColor. replace(/#/,""):"000000";
this.endColor=(endColor&&endColor!="")?
endColor. replace(/#/,""):false;
this.amount=(!amount)?1:amount;
this.timing=(!timing||
isNaN( parseInt(timing)))?
250:
parseInt(timing);
this.object=(objDef)? objDef+"": "document.bgColor";
this.objectTimer=objectTimer;
this.originalCol=startColor;//unimportant
this.originalAmount=amount;//unimportant
this.originalTime=timing;//unimportant
this.fade=colorFader
this.path=(path)?(""+path):"012"
//prepare index for path:
var is3=( this.path.indexOf("3")!=-1)?1:0;
this.path= this.path.split("");
for(var p=0;p< this.path. length;p++){
this.path[p]=(is3)?
parseFloat( this.path[p])-1:
parseFloat( this.path[p])
}
//perform a few operations upon construction:
this.hex= new Array(
this.startColor. substring(0,2),
this.startColor. substring(2,4),
this.startColor. substring(4, this.startColor. length)
);
//
this.hexEnd=(endColor)? new Array(
parseInt( this.endColor. substring(0,2),16),
parseInt( this.endColor. substring(2,4),16),
parseInt( this.endColor. substring(4, this.endColor. length),16)
):false;
/*keep this comment to reuse freely
http://www.unitedscripters.com */}
/*----------------------------------------------*/
function changeHex(h,n){
// returns an hex or a false
h=( typeof(h)=="string")? parseInt(h,16):h;
if((h==0&&n<0)||(h==255&&n>0)){ return false}
//validated.
h+=n
h=(h>255)?255:
(h<0)?0:
h;
return (h<=15)?"0"+h. toString(16):
h. toString(16)
/*keep this comment to reuse freely
http://www.unitedscripters.com */}
/*----------------------------------------------*/
function colorFader(){
//requires: fadingObject(), changeHex()
for(var i=0;i< this.path. length;i++){
var change=changeHex( this.hex[ this.path[i]], this.amount)
if(!change){
if(i== this.path. length-1){//nothing to change
this.amount=-( this.amount)
}
continue};
this.hex[ this.path[i]]=change;break
}
var exit=0;
if( this.endColor){
for(var x=0;x< this.hexEnd. length;x++){
if( this.amount<0&& this.hexEnd[x]>= parseInt( this.hex[x],16)) {++exit}
else
if( this.amount>0&& this.hexEnd[x]<= parseInt( this.hex[x],16)) {++exit}
}
}
if(exit==3){
clearInterval( this.objectTimer);
//we reset to spare you possible surprises
this.startColor= this.originalCol
this.amount= this.originalAmount
this.timing= this.originalTime;
}
var hex= this.hex. join("")
this.startColor=hex
eval( this.object+"='#"+hex+"'");// ' apex ', and note the #
/*keep this comment to reuse freely
http://www.unitedscripters.com */}
How it works
|
|
Inner workings, invocations, and a TEST
|
Here is how it works and how should be used:
- We first build an array named fadings: we do this for we store there the objects to make the invocation of the script possible on multiple instances and as simple as possible. This means that all your active timeout (since fadings uses timeouts and crashes on whatever timeout set below 250, so do not use timeouts below that possibly- a NS6 issue) will be stored in the array, each entry of which will be an active object furnished with all the properties defined in the other subroutines. If you have more active objects and you want to selectively clear some timeouts, you'd probably store somewhere a reference to the current fadings.length upon assigning to it a new fading object instance; in such fashion whenever you want to clear a timeout you'd do:
clearInterval(fadings[myStoredIndex].objectTimer) for is the property name which stores a reference to the active timeout. Last but not least on this, we are using generation 4 browsers built-in method setInterval so you'd use clearInterval and NOT clearTimeout to deactivate a timer.
- fadingOn is just the subroutine which builds up the fadings array, so its importance is entirely functional to the other subroutines, and we go immediately to deal with them.
- fadingObject is your constructor: it makes the template for whatever fading object. it is structured as follows:
- startColor will store a reference to the starting color: you can set it to an hexadecimal in between quotes, or t an object reference (if you pass it as document.bgColor without quotes, for instance, it is ok).
- endColor sets a color that, when reached, would stop the timeout and the fading.
You must be aware of two things:- If you do not set it, you still have to pass it as 0 or as keyword false ir as an empty string, and in these cases the fadings will be continuous.
- If you set it, the script will check when it gets as close as possible to the desired color: beware, if you set other arguments such that when the color fades, a jump might oversize and over-jump so to say the given endColor, the script would stop as soon as a colour a bit darker (or brighter) than endColor is reached.
- amount is the amount that must be changed upon every timeout recurrence: you can set it to whatever value, and if negative it starts going backward (that is: darkening the color at the first round).
- Both startColor and endColor must be passed as and can be passed wither with or without the # symbol: the script will take care of that in each case.
- timing is your timeout. You can set whatever value: 1000 is a second, 10000 ten seconds, 250 a quarter of second, 100 even less although Netscape 4 can crash under 250 milliseconds.
- is a reference to the object which must be faded. If none defaults to the document background color.
- If you pass it, it must be a valid reference to your object but : for instance: document.bgColor
Would not be so, the argument would not pass an object to eval lately (eval means to use the built in method which transforms a string into a javaScript valid expression) but the of the object! (it means: you were not to include for instance document.bgColor in between quotes, it would pass the VALUE, the COLOR of the background, instead than a reference to the object, thus it could not manipulate the object at all!) - We assume you already have your subroutine which can detect a layer and the correct syntax which leads to its background. WE can tell you that
- IE4 and IE5++ and NS6++ use XXX.backgroundColor
- NS4 uses XXX.bgColor
- In examples above XXX. stands for a correct reference to the layer for the Document Object Model of the browsers: ya know, that meddled messed stuff like document.all or document.layers["layerName"].
If you don't have it, here is one for you:
function manageBackground
(layer){
var obj="";
if( document.getElementById ){obj= "document.getElementById('"+layer+"').style.backgroundColor"}
else if( document.all ){obj= "document.all['"+layer+"'].style.backgroundColor"}
else if( navigator.appName.indexOf("Netscape")!=-1 ){/* (!!) NS4 can fail checking if( document.layers ) */
obj= "document.layers['"+layer+"'].document.bgColor"}
else{return false}
return obj;
}
- path is the last argument you'd take care to set upon invoking the construction of a new object from this template: it must be either a number or a string, including only 1 2 3 and no zero: depending upon the order you pass them, the script uses this number to understand whether you mean to change first the first couple of the hexadecimal current colour value, or the second, or the third: so a number like 312 would mean: first fade by this couple (3rd), second fade by this couple (1st), third fade by this couple (2nd) as last: so 321 would mean: 3rd first, 1st second, 2nd third. Eventually, restart with the same order.
Since the script detects wether a couple is already at its maximum (FF) or at its minimum (00), if a starting couple is already there and the direction it should fade the couple (the amount value, that is, if positive or negative number) could not go further, it would grab the subsequent couple as dictated by the path argument.
- The other arguments just store references to the original status (upon invoking) of the layer/object, so upon clearing an interval it would restore the original values.
: if you clear an interval on your own as said above at the beginning, before restarting a fading on an already used object, we suggest you to reset the object background color to the desired value: this definitively means you'd have a small snippet of code of your own that can manipulate a layer background. I repeat, keep in mind:
- IE4:
document.all['layerName'].style.backgroundColor
- NS4:
document.layers['layerName'].document.bgColor
- IE5 and NS6:
document.getElementById('layerName').style.backgroundColor
There you go man!
- changeHex subroutine would get an hexadecimal couple and add to it the amount value only if the upper or lower limit has not reached yet (in which case doesn't return the updated value but false). It takes avail of parseInt and toString built in methods with an argument set to 16 (hexa-decimal) to transform an hexadecimal couple (which might include letters) into a number upon which calculations may be performed) so that when getting an hex couple, it transforms it into a number, then adds the amount, then turns it back into an hex and returns it.
- Finally, colorFader is the real engine: grabs the path (if n path argument is passed, path defaults to 123, a linear order of grabbing that is) and if a couple can be changed (change variable does not return false, that is), it updates it.
Note that the code after
if(!change){... means that if all the 3 couples of an hexadecimal value are already at the condition level where they cannot be updated any longer (bottom 00 or top FF, that is), it reverses the value of the amount argument so to let you go on fading, this time in the opposite direction.
It then checks if an endColor argument has been passed. If so and only if so, it checks wether it should stop fading, verifying if all the current hexadecimal couples ar at a value higher (if amount positive) or lower (if amount negative) with the respective endColor hexadecimal couple: if so turns off the interval, and resets the value to the original. The last statement evals the object so to assign to it the yielded hexadecimal value.
Here is a possible invocation of this script, considering each invocation is made using fadingOn:
fadingOn("#0000ff","",5,250,document.bgColor,132)
fadingOn("#0000ff","",15,500,document.bgColor,132)
fadingOn("#0000ff","#00ffff",5,250,document.bgColor,132)
Or, for a : pass the manageBackground
function itself as an argument with the name of the layer in between quotes; see:
fadingOn("#0000ff","",5,250,,132)
Whereas the first instance (while all instances are made to manipulate the document background) starts with a blue, jumps forward of an amount of 5, with an interval of 250 milliseconds, on the (between quotes!) document.bgColor object, with a path that is 132. The second does the same but goes backward (15) of a higher amount, with a 500 milliseconds interval. The third example just differs in this, includes an endColor argument.
|
|