Tweening a Color Transform

I’ve been working with the Tween and Transition classes a lot lately, and was recently tasked with fading a tint over a movieClip. My fisrt instinct was to draw a colored square over the clip, with the alpha of the square set to something less than 100%, like this:

function drawOverlayColor(color:Number, mc:MovieClip){
  var bounds:Object = mc.getBounds(mc._parent);
  var left = bounds.xMin;
  var right =  bounds.xMax;
  var top = bounds.yMin;
  var bottom = bounds.yMax;
  overlayColor = this.createEmptyMovieClip("overlayColor",getNextHighestDepth());
  overlayColor.lineStyle(0,color,0);
  overlayColor.moveTo(left,top)
  overlayColor.beginFill(color,60);
  overlayColor.lineTo(left,bottom);
  overlayColor.lineTo(right,bottom);
  overlayColor.lineTo(right,top);
  overlayColor.lineTo(left,top);
  overlayColor.endFill()
 } 

I could then fade in and out the the overlay color using the tween classes

var at:Tween = new Tween(overlayColor,"_alpha",null,0,100,duration,true);

I ran into problems with this approach when the movieclips i needed overlays on were not simple rectangles, but instead odd shapes. This seemed like a better job for the setTransform method of the Color object., which handles odd shapes well. While the tween classes can be used to change properties of a colorTransform object over time, the properties of that object are only applied when the setTransform method of the color is called. In order to have a dynamically changing color transform object constantly applied, I created this ColorTransformTween class

import mx.transitions.Tween;
import mx.events.EventDispatcher;
class ColorTransformTween {
 var startObject:Object
 var endObject:Object;
 var mc:MovieClip;
 var seconds:Number;
 var interval;
 var numTweensRunning:Number=0;
 // mixins from EventDispatcher
 var addEventListener:Function;
 var dispatchEvent:Function;
 function ColorTransformTween(mc:MovieClip,startObject:Object,endObject:Object,seconds:Number,startNow:Boolean){
  EventDispatcher.initialize(this);
  setStartingObject(startObject);
  setEndingObject(endObject);
  this.mc = mc;
  this.seconds = seconds;
  if(startNow){
   doTween(seconds);
  }
 }
 function setColor(startOrEnd:String,r:Number,g:Number,b:Number,a:Number,useHex:Boolean){
  if(startOrEnd.toLowerCase() != "start" && startOrEnd.toLowerCase() != "end"){
   throw "Invalid startOrEnd param sent to setColor";
  }
  var o:Object = new Object();
  if(useHex){
   o.rb = r;
   o.gb = g;
   o.bb = b;
   o.ab = a;
  } else {
   o.ra = r;
   o.ga = g;
   o.ba = b;
   o.aa = a;
  }
  if(startOrEnd.toLowerCase() == "start"){
   setStartingObject(o);
  } else {
   setEndingObject(o);
  }
 }
 function setStartingObject(o:Object){
  startObject = o;
 }
 function setEndingObject(o:Object){
  endObject = o;
 }
 function doTween(seconds:Number){
  var ct:Object = new Object();
  for(var i in startObject){
   var tween:Tween = new Tween(ct,i,null,startObject[i],endObject[i],seconds, true);
   numTweensRunning++;
   tween.addListener(this);
  }
  interval=setInterval(applyColor,10,this,mc,ct,seconds,getTimer());
 }
 function onMotionFinished(item){
  
  numTweensRunning–;
  
  if(numTweensRunning ==0){
   this.dispatchEvent({type:’ColorTransformTween Done’})
  }
  delete item;
 }
 function applyColor(owner:Object, targetClip:MovieClip, obj:Object, time:Number, startTime:Number){
  
  var c:Color = new Color(targetClip);
  c.setTransform(obj);
  var now = getTimer();
  if(startTime+time*1000 <= now){
   clearInterval(owner.interval);
  }
 }

}

To test, create a movieClip on the stage (i imported a jpg of my daughter, but any movieClip will do), give it the instancename mcTest, and try this code:

var ct:Object = {rb:0,gb:0,bb:0};
var rt:Object = {rb:100,gb:0,bb:200};
var colTween=new ColorTransformTween(mcTest,ct,rt,4,true);

Over 4 seconds, your movie should have a lavender tint faded in over it.

If you aren’t already familiar with the Tween classes, Jen deHaan covers them well in an artice here

There are no comments.

Leave a Reply