This user is yet to take control of their account and provide a biography. If you are the author of this article, please contact us via [email:support@actionscript.org]. STEP 1) Include or copy and paste the following prototypes into your ActionScript code:
[as]//// FIGLEAF SOFTWARE RGB to Hex
Math.rgbToHex = function(r,g,b){
return(r<<16 | g<<8 | b);
}
// PiXELWiT REVERSE ENGINEERING
Math.hexToRGB = function(hex){
var red = hex>>16;
var grnBlu = hex-(red<<16)
var grn = grnBlu>>8;
var blu = grnBlu-(grn<<8);
return({r:red, g:grn, b:blu});
}
//
//
// Check to see if an object2 has the same properties
// with the same values as those in object1
Color.prototype.transObjSame = function (obj1, obj2){
for(var i in obj1){
if(obj1[i] != obj2[i]){
return false;
}
}
return true;
}
//
// PiXELWiT Color Prototypes
// http://www.pixelwit.com
//
// Just like setTransform but over a period of time
// func is called when desired transformation is reached
Color.prototype.fadeTransform = function(goalTrans, milSecs, func){
if(this.v){
if( this.transObjSame(goalTrans, this.v.goalTrans) ){
trace("Already going there");
return;// already heading to that trans obj so just wait
}else{
clearInterval(this.v.intrvl);
}
}
var getTrans = this.getTransform();
if(this.transObjSame(goalTrans, getTrans)){
trace("already there");
return;// already at that trans obj so don't bother
}
this.v = {};
this.v.goalTrans = goalTrans;
this.v.milSecs = milSecs;
if(typeof func == "function")this.v.func = func;
this.v.startTime = getTimer();
this.v.startTrans = getTrans;
this.v.change = {};
for(var i in goalTrans){
this.v.change[i] = goalTrans[i]-this.v.startTrans[i];
}
this.transShift();
if(milSecs){
this.v.intrvl = setinterval(this, "transShift", 1);
}
}
Color.prototype.transShift = function(){
//trace("Running");
var ratio = (getTimer()-this.v.startTime)/this.v.milSecs;
if(ratio<1){
var newTrans = {};
for(var i in this.v.change){
newTrans[i] = this.v.startTrans[i]+ratio*this.v.change[i];
}
this.setTransform(newTrans);
}else{
this.setTransform(this.v.goalTrans);
clearInterval(this.v.intrvl);
var myFunc = this.v.func;
delete(this.v);
if(myFunc)myFunc();
}
}
Color.prototype.fadeRGB = function(r, g, b, milSecs, func){
var goalTrans = {ra:0, ga:0, ba:0, rb:r, gb:g, bb:b, aa:100, ab:0};
this.fadeTransform(goalTrans, milSecs, func);
}
Color.prototype.fadeHex = function(goalHex, milSecs, func){
var goalRGB = Math.hexToRGB(goalHex);
this.fadeRGB(goalRGB.r, goalRGB.g, goalRGB.b, milSecs, func);
}
Color.prototype.fadeClearTrans = function(milSecs, func){
var goalTrans = {ra:100, rb:0, ga:100, gb:0, ba:100, bb:0, aa:100, ab:0};
this.fadeTransform(goalTrans, milSecs, func);
}
[/as]
STEP2) Create a Color object referencing the clip you want to have change colors.
[as]var myColorObj = new Color(SomeClip);
[/as]
STEP3) Do either of the following if you want your clip to fade to orange over a 2 second time period:
[as]A) myColorObj.fadeRGB(255, 128, 0, 2000);
B) myColorObj.fadeHex(0xFF8000, 2000);
C) myColorObj.fadeTransform({ra:0, rb:255, ga:0, bg:128, ba:0, bb:0, aa:100, ab:0}, 2000);
[/as]
STEP4) Then if you'd like your target clip to return to it's initial state just do this:
[as]myColorObj.fadeClearTrans(2000);
[/as]
That shouldn't be so tough. Paste prototypes; make a color object; pick a color and time; then kick back and relax while your colors fade smooth and trouble free. Yay prototypes!
While this may be enough information to satisfy some ActionScripters, others might like a more detailed explanation. If you're one of those people I encourage you to read on.
[as]//// FIGLEAF SOFTWARE RGB to Hex
Math.rgbToHex = function(r,g,b){
return(r<<16 | g<<8 | b);}
[/as]
Purpose:
Converts three separate integers representing the rgb values of a color to a hexadecimal representation of the same color.
Explanation:
Any one color is composed of 3 color components; red, green and blue. Each color component can hold a value from 0 to 255. When working with color, a component's value can generally be written 3 different ways. For example's sake, let's assume we are working with an ORANGE color with the values listed in the example below. The green component of our orange color is at 50% of its maximum brightness. In a base ten system ORANGE's green component is written as 128 (half of 256). Very simple. In a base 16 number system 128 is written as 80 which means 8 sets of 16 which is, you guessed it, 128. The third way to write 128 is to use binary (base 2 system). In binary the number 128 is represented as 10000000 which is another way of saying 1 times 2 to the 7th power. Where this is all heading..
Example:
| [as] Format = Red : Green : Blue |
Let's say we want to convert our three ORANGE color components (Red=255, Green=128, Blue=0) to one hexadecimal (base 16) value (0xFF8000). The "rgbToHex" function first converts all the RGB values to binary numbers. This happens automatically whenever the bitwise << operator is used. Since our ORANGE color has a red value of 255 the red component is converted to 11111111 binary. The green value of 128 is converted to 10000000 binary and the blue value of 0 is essentially unchanged or converted to 00000000. That gives us {r:11111111, g:10000000, b:00000000}. Now that we have the binary equivalents of our RGB values we can start manipulating them. The R<<16 part of the function shifts the red value 16 places to the left and fills in the blank spaces with zeros giving us 111111110000000000000000. The G<<8 part of the function shifts the green value 8 places to the left 1000000000000000. The blue value does not shift (there's no << after the b). The "|" operator then tallies the column of numbers, similar to adding them but not quite the same. If any column of numbers has a 1 in it the result for that column is a 1.
| [as]111111110000000000000000 |
The resulting binary number 111111111000000000000000 is equivalent to the hexadecimal number 0xFF8000 and the base 10 number 16744448.
And that's how you get from RGB notation to a hexadecimal color value.
Are we having fun yet? Good, I knew we were.
(hexToRGB)
[as]// PiXELWiT REVERSE ENGINEERING
Math.hexToRGB = function(hex){
var red = hex>>16;
var grnBlu = hex-(red<<16);
var grn = grnBlu>>8;
var blu = grnBlu-(grn<<8);
return({r:red, g:grn, b:blu});
}
[/as]
Purpose:
Breaks a hexadecimal representation of a color into its three color components.
Explanation:
[as]Math.hexToRGB = function(hex){
[/as]
In keeping with our ORANGE example lets say we pass our hexToRGB function the hexadecimal color 0xFF8000.
[as]var red = hex>>16;
[/as]
[as]var grnBlu = hex-(red<<16);
[/as]
This adds 16 zeros to the end of red then subtracts that value from hex (111111110000000000000000-111111111000000000000000) leaving grnBlu with a value of 1000000000000000.
[as]var grn = grnBlu>>8;
[/as]
The green value is extracted from grnBlu by chopping the last 8 digits off grnBlu which leaves green with a value of 10000000.
[as]var blu = grnBlu-(grn<<8);
[/as]
This adds 8 zeros to the end of grn and subtracts grn from grnBlu (1000000000000000-1000000000000000) leaving blu with a value of 0 or 00000000.
[as]return({r:red, g:grn, b:blu});
[/as]
The final line returns a generic object with three properties called r, g, and b which hold their respective numeric color values.
A Color Transformation Object is merely a way to store related pieces of color information. A Color Transform Object generally contains 8 pieces of information; an A and B value for red, an A and B for green, an A and B for blue and an A and B for alpha. They are referred to as ra, rb, ga, gb, ba, bb, aa and ab. The A Group of variables generally go from -100% to 100% but can go beyond those limits if desired. The A Group variables are multiplied by the pixels initial color value. The B Group of variables usually range from -255 to 255 but can also go beyond these limits. The B Group is added to the initial value which was multiplied by the A Group.
Imagine you are transforming the color of a single pixel image. Imagine this single pixel's initial color is our familiar friend ORANGE (r:255, g:128, b:0). Imagine we are going to use the following transformation object to change our single pixel image {ra:50, rb:-100, ga:25, gb:100, ba:100, bb:200, aa:100, ab:0}. This is how you can calculate the final color of your pixel:
| [as] <<A>> <<B>> |
So our ORANGE {r:255, g:128, b:0, a:255} will now be show up as what I'd call a light pink {r:227, g:132, b:200, a:255} after applying the Color Transform Object. Just remember A Group multiplies, B Group adds.
(transObjSame)
[as]Color.prototype.transObjSame = function (obj1, obj2){
for(var i in obj1){
if(obj1[i] != obj2[i]){
return false;
}
}
return true;
}
[/as]
Purpose:
The transObjSame function is used to make sure we don't try to fade from one color to the same color. It's like fading from red to the exact same shade of red, there's not much point to it.
Explanation:
TransObjSame compares two different objects to see if all the properties within the first object are reflected in the second object.
[as]Color.prototype.fadeTransform = function(goalTrans, milSecs, func){
if(this.v){
if( this.transObjSame(goalTrans, this.v.goalTrans) ){
trace("Already going there");
return;// already heading to that trans obj so just wait
}else{
clearInterval(this.v.intrvl);
}
}
var getTrans = this.getTransform();
if(this.transObjSame(goalTrans, getTrans)){
trace("already there");
return;// already at that trans obj so don't bother
} this.v = {};
this.v.goalTrans = goalTrans;
this.v.milSecs = milSecs;
if(typeof func == "function")this.v.func = func;
this.v.startTime = getTimer();
this.v.startTrans = getTrans;
this.v.change = {};
for(var i in goalTrans){
this.v.change[i] = goalTrans[i]-this.v.startTrans[i];
}
this.transShift();
if(milSecs){
this.v.intrvl = setinterval(this, "transShift", 1);
}
}
[/as]
Purpose:
FadeTransform STARTS Fading from one color transformation to another over a set period of time and specifies a function to call when finished. This function doesn't do the actual fading, it just sets everything up and stores some variables.
Explanation:
[as]Color.prototype.fadeTransform = function(goalTrans, milSecs, func){
[/as]
FadeTransform accepts 3 arguments:
goalTrans = a color transformation object containing any of the following properties {ra, rb, ga, gb, ba, bb, aa, ab}
milSecs = the total amount of time it takes for the color transformation to be fully applied in milliseconds (1000 ms = 1 second).
func = a reference to a function which will be called when the color transformation is complete.
Out of the three arguments, only goalTrans is required.
[as]if(this.v){
[/as]
Essentially asking if the color object is currently fading from one color to another. V is only created when fading colors and then deleted when fading is complete so if V exists that means you're fading colors.
[as]if( this.transObjSame(goalTrans, this.v.goalTrans) ){
trace("Already going there");
return;// already heading to that trans obj so just wait
[/as]
If all the properties in the new goal transformation object are the same as those contained within the transformation object we're currently fading to (remember we know we're currently fading to a trans obj because we checked to see that V exists) we can bail out (return) and let the current color fade finish as intended without interruption. No need to recalculate a new transformation object because we already have it and are headed that way right now.
[as]}else{ clearInterval(this.v.intrvl);}
[/as]
If any property in the new goal transformation object is different from the transformation object we're currently fading to, stop fading to the now obsolete color trans obj because we're going to start fading to a new color trans obj. Stop the presses we're heading to a new destination.
[as]var getTrans = this.getTransform();
[/as]
Stores a snapshot of all the color transformations "currently" applied to our color object. We need this so we can determine how much we need to change in order to reach our new goal color.
[as]if(this.transObjSame(goalTrans, getTrans)){
trace("already there");
return;// already at that trans obj so don't bother
}
[/as]
Although we may not be fading colors we may already be at the goal color trans obj (If we want to fade to red it makes sense to check that we're not already red). If we're already at the goal color trans then bail out (return) and save the processor for other things.
[as]this.v = {};
[/as]
"V" is an object used to store "V"ariables related to the color fading functions. Storing all the variables within an object within the color object keeps all necessary variables local to each individual color object and allows one-step deletion of multiple variables in the future.
[as]this.v.goalTrans = goalTrans;
[/as]
Stores a reference to the desired end transformation object.
[as]this.v.milSecs = milSecs;
[/as]
Stores the amount of time required to complete a color fade.
[as]if(typeof func == "function")this.v.func = func;
[/as]
Stores a reference to the function which will be executed when the color fade is complete. Checking to make sure func is a function prevents us from trying to call a function that doesn't exist.
[as]this.v.startTime = getTimer();
[/as]
Records when the color fade started.
[as]this.v.startTrans = getTrans;
[/as]
Stores a snapshot of the color transformation in effect when the color fade is started.
[as]this.v.change = {};
[/as]
An object used to store the differences between the goal trans obj and the current trans obj.
[as]for(var i in goalTrans){
this.v.change[i] = goalTrans[i]-this.v.startTrans[i];
}
[/as]
Goes through all variables in the goal trans obj and calculates the difference between itself and the start trans obj and stores the result in the change object. If goalTrans.ra=60 and startTrans.ra=50 then change.ra=10.
[as]this.transShift();
[/as]
Calls the color object's method which will do the grunt work of fading the color based on the information we just saved within the color object's "V"ariable object.
[as]if(milSecs){
this.v.intrvl = setinterval(this, "transShift", 1);
}
[/as]
If the milSecs variable exists SetInterval calls the color object's transShift method. The interval identifier is stored in the "V"ariables object so it can be stopped at a later time, like when a fade is complete.
[as]Color.prototype.transShift = function(){
//trace("Running");
var ratio = (getTimer()-this.v.startTime)/this.v.milSecs;
if(ratio<1){
var newTrans = {};
for(var i in this.v.change){
newTrans[i] = this.v.startTrans[i]+ratio*this.v.change[i];
}
this.setTransform(newTrans);
}else{
this.setTransform(this.v.goalTrans);
clearInterval(this.v.intrvl);
var myFunc = this.v.func;
delete(this.v);
if(myFunc)myFunc();
}
}
[/as]
Purpose:
TransShift creates a transformation object with values between the startTans and goalTrans objects. In other words it's responsible for making the gradual color change.
Explanation:
[as]Color.prototype.transShift = function(){
[/as]
This function accepts no arguments since all necessary information is stored within the "V"ariables object inside each instance of the Color object.
[as]//trace("Running");
[/as]
You can remove the comment marks from this line to see when the Color object is fading in the testing environment.
[as]var ratio = (getTimer()-this.v.startTime)/this.v.milSecs;
[/as]
The ratio is used as a way of determining how far along you are in the fading process. A ratio with a value of 0 means you have just started the fade while a value of 1 means you are at the very end of a fade. If you started the fade 5 seconds into the SWF's life span, startTime will hold a value of 5000. If your color fade lasts 1 second then milSecs will hold a value of 1000. If the current time is 5 and a half seconds into the SWF's life span then getTimer() will return a value of 5500. This leaves the equation of (5500-5000)/1000 which equals 500/1000 which equals 1/2. This means the color fade is 50% complete.
[as]if(ratio<1){
[/as]
If the ratio is less than 1 then there is still some color fading left to do so don't slack-off just yet.
[as]var newTrans = {};
[/as]
NewTrans is used to store the color transformation information which the setTransform method will use to apply the color fade based on the current ratio.
[as]for(var i in this.v.change){ newTrans[i] = this.v.startTrans[i]+ratio*this.v.change[i];}
[/as]
This for loop goes through all the properties of the Change color trans obj (remember the Change object stores the difference in values between the goaltTrans obj and the startTrans object so if goalTrans.ra=60 and startTrans.ra=50 then change.ra=10) and multiplies the values in the change object by the ratio and adds that value to the startTrans object. If startTrans.ra=50, change.ra=10 and ratio=.5 then newTrans.ra will equal 50+(10*.5) which equals 55.
[as]this.setTransform(newTrans);
[/as]
Now that you know the color transformation which lies between the goalTrans and the startTrans, apply it to the target of the color object so it actually changes colors.
[as]}else{
[/as]
This next code block will only be executed if the color fade is complete.
[as]this.setTransform(this.v.goalTrans);
[/as]
Set the target of the Color object to it's final destination color.
[as]clearInterval(this.v.intrvl);
[/as]
Since we have arrived at the destination color there's no need to do anymore fading. Clearinterval removes the function we're currently working with from setinterval's list of functions to execute.
[as]var myFunc = this.v.func;
[/as]
Stores a reference to the function which is supposed to execute when the color fade is finished as a local variable. We store it as a local variable because we are about to remove the "V"ariable object which stores its current reference.
[as]delete(this.v);
[/as]
Removes ALL the variables which were stored in the "V"ariable object and the "V"ariable object itself. This also lets the fadeTrans function know that the color fade is complete and that there is no color fade currently taking place.
[as]if(myFunc)myFunc();
[/as]
Now that everything is all buttoned up call the function specified in the func argument of the fadeTrans function.
So far so good. We now have all the functions we need to complete a color fade from one transformation object to the next, everything else is just gravy.
[as]Color.prototype.fadeRGB = function(r, g, b, milSecs, func){
var goalTrans = {};
goalTrans.ra = goalTrans.ga = goalTrans.ba = goalTrans.ab = 0;
goalTrans.aa = 100;
goalTrans.rb = r;
goalTrans.gb = g;
goalTrans.bb = b;
this.fadeTransform(goalTrans, milSecs, func);
}
[/as]
Purpose:
Just an alternate way to call the fadeTransform method. This method doesn't require an in-depth knowledge of the color transform object, instead all you need to know are the Red, Green and Blue values of your final color. Compared to our previous functions this is a breeze.
Explanation:
[as]Color.prototype.fadeRGB = function(r, g, b, milSecs, func){
[/as]
Accepts 5 possible arguments.
R = the final color's red color value.
G = the final color's green color value.
B = the final color's blue color value.
MilSecs = the number of milliseconds it will take for the color fade to reach completion.
Func = A function to call when the color fade is complete.
Only the R, G and B arguments are required.
[as]var goalTrans = {};
[/as]
Create a new blank object to hold variables related the color transformations we wish to apply.
[as]goalTrans.ra = goalTrans.ga = goalTrans.ba = goalTrans.ab = 0;
[/as]
When applying a transformation which sets the Color object's target to a solid color, all these variables should be set to 0. This essentially turns the Color object's target Black and leaves it's original transparency.
[as]goalTrans.aa = 100;
[/as]
Makes sure the transparency of all pixels in the Color object's target hold their original values.
[as]goalTrans.rb = r;
goalTrans.gb = g;
goalTrans.bb = b;
[/as]
After turning the Color object's target black these lines of code increase the r, g and b values until our Color object's target clip is the desired color.
[as]this.fadeTransform(goalTrans, milSecs, func);
[/as]
Calls the FadeTransform prototype we made earlier and creates a smooth color fade from our startTrans obj to our goalTrans obj over the specified period of time then calls func when complete.
(fadeHex)
[as]Color.prototype.fadeHex = function(goalHex, milSecs, func){
var goalRGB = Math.hexToRGB(goalHex);
this.fadeRGB(goalRGB.r, goalRGB.g, goalRGB.b, milSecs, func);
}
[/as]
Purpose:
Another way to call the fadeTransform method. All you need to know is the hexadecimal representation of your final color.
Explanation:
[as]Color.prototype.fadeHex = function(goalHex, milSecs, func){
[/as]
Accepts 3 arguments.
GoalHex is a hexadecimal number specifying the goal color. If it were our ORANGE color it would be in this format 0xFF8000.
Milsecs is the standard argument specifying the duration of the color fade in milliseconds.
Func is called when the color fade is complete.
Only goalHex is required.
[as]var goalRGB = Math.hexToRGB(goalHex);
[/as]
You remember the handy hexToRGB function we discussed earlier right? Well we're using it to extract the r, g and b values from the hexadecimal number and storing them in an object called goalRGB.
[as]this.fadeRGB(goalRGB.r, goalRGB.g, goalRGB.b, milSecs, func);
[/as]
Uses the rgb values stored in the GoalRGB object to call the fadeRGB function we defined earlier.
(fadeClearTrans)
[as]Color.prototype.fadeClearTrans = function(milSecs, func){
var goalTrans = {ra:100, rb:0, ga:100, gb:0, ba:100, bb:0, aa:100, ab:0};
this.fadeTransform(goalTrans, milSecs, func);
}
[/as]
Purpose:
Removes any applied color transformations and resets the target of the color object to its default settings.
Explanation:
[as]Color.prototype.fadeClearTrans = function(milSecs, func){
[/as]
This function accepts 2 arguments yet neither are required.
MilSecs specifies the length of time required to transition to the default settings.
Func is a reference to a function which will be called when the color transition is complete.
[as]var goalTrans = {ra:100, rb:0, ga:100, gb:0, ba:100, bb:0, aa:100, ab:0};
[/as]
This line creates a color transformation object with all its values set to their defaults.
[as]this.fadeTransform(goalTrans, milSecs, func)
[/as]
This line calls our handy dandy fadeTransform function with the newly created goalTrans object as an argument. It passes the milSecs and func variables along as well.
[as]myCO = new Color(SomeImageClip);
[/as]
Create a Color object to play with and specify which clip it will act upon.
[as]function traceDone(){ trace("DONE FADING!");}
[/as]
A general function we can execute to show that everything is working.
[as]function fadeRandHex(){
var randHex = Math.floor(Math.random()*0xFFFFFF);
myCO.fadeHex(randHex, Math.floor(Math.random()*1000+100), fadeRandHex)
}
[/as]
FadeRandHex generates a random hexadecimal representation of a color, fades to that color over a random period of time, then when the color fade is complete fadeRandHex is called again thus repeating the process.
[as]function fadeRandTransform(){
var o = {}; o.ra = Math.floor(Math.random()*200-100);
o.ga = Math.floor(Math.random()*200-100);
o.ba = Math.floor(Math.random()*200-100);
o.rb = Math.floor(Math.random()*512-256);
o.gb = Math.floor(Math.random()*512-256);
o.bb = Math.floor(Math.random()*512-256);
myCO.fadeTransform(o, 3000, fadeRandTransform);
}
[/as]
FadeRandTransform generates a color transformation object with random values, fades to that randomly generated color trans obj and then when complete fadeRandTransform is called again.
[as]transArray = [];
transArray[0]={ra:-100, rb:255, ga:-100, gb:150, ba:0, bb:0, aa:100, ab:0};
transArray[1]={ra:100, rb:-61, ga:-100, gb:120, ba:-100, bb:255, aa:100, ab:0};
transArray[2]={ra:-100, rb:139, ga:10, gb:0, ba:-100, bb:255, aa:100, ab:0};
transArray[3]={ra:100, rb:255, ga:100, gb:0, ba:-100, bb:255, aa:100, ab:0};
lastTransArray = 0;
function fadeArrayTrans(){
myCO.fadeTransform(transArray[lastTransArray], 2000, fadeArrayTrans)
lastTransArray++; lastTransArray%=transArray.length;
}
[/as]
This block of code creates an array of four predefined color transformation objects. LastTransArray is used to track which transformation object was last applied. FadeArrayTrans selects a color trans obj from the array, fades to that color trans obj then when complete fadeRandTrans is called again. The lastTransArray variable is incremented and modulated so as to cycle through the objects in the array.
[as]CLEAR.onRelease = function(){
myCO.fadeClearTrans(1000);
}
RED.onRelease = function(){
myCO.fadeRGB(255, 0, 0, 1000, traceDone);
}
ORANGIFY.onRelease = function(){
myCO.fadeTransform(transArray[0], 1000, traceDone);
}
RANDHEX.onRelease = fadeRandHex;
ARRAYTRANS.onRelease = fadeArrayTrans;
RANDTRANS.onRelease = fadeRandTransform;
[/as]