|
Increasingly, clients have been asking for a "reflection" effect, showing a vertically flipped image of a component next to the actual component. After reinventing the wheel on this several times, I came up with this simple reusable component:
package com.tappernimer.components{import mx.containers.Canvas;import mx.core.UIComponent;import flash.display.BitmapData;import flash.geom.Matrix;import flash.display.IBitmapDrawable;public class VerticalReflection extends Canvas{private var _component:UIComponent;public var trans:Number=.5;public var filterArray:Array=new Array();public var skewY:Number=0;public var skewX:Number=0;public function get component():UIComponent{return _component;}
public function set component(c:UIComponent):void{this._component = c;// hack to work around issue with component being// a dynamically loaded image its possible for the// image to be fully loaded, but its height or width// not yet set this call later, keeps retrying until// the values are set.if(c.width ==0 || c.height==0){callLater(resetComponent,[c]);return;}doReflection();}
private function resetComponent(c:UIComponent):void{this.component = c;}
private function doReflection():void {// create bitmap objectvar bmpData:BitmapData = new BitmapData(component.width,component.height);// create matrixvar invertMatrix:Matrix = new Matrix(1,skewY,skewX);// set matrix to invert vertically, but normal horizontallyinvertMatrix.scale(1, -1);// move matrix, so top is at bottom, and vice versainvertMatrix.translate(0, component.height);// draw component flippedbmpData.draw(component as IBitmapDrawable,invertMatrix);// create a new holder for the imagevar ref:UIComponent = new UIComponent();// match new holders size to the originalref.setActualSize(component.width,component.height);// fill the new component with the imageref.graphics.beginBitmapFill(bmpData);ref.graphics.drawRect(0, 0,component.width, component.height);ref.graphics.endFill();// set the transparencyref.alpha = trans;// apply any filtersref.filters = filterArray;// add image to stageaddChild(ref);}
}
}
This component can then be passed any other component to reflect, accepting filters (filterArray), alpha value (trans), and arguments to allow you to skew the reflection. In fact, using it can be as simple as this:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx=http://www.adobe.com/2006/mxml
xmlns:c="com.tappernimer.components.*"layout="absolute">
<mx:Image id="image" source="images/tn_logo_full.jpg"/><c:VerticalReflection id="ref"component="{image}"x="{image.x}" y="{image.height}"filterArray="{new Array(new BlurFilter())}"/>
</mx:Application>
Here is the code running:
nice post, but could you use some normal readable font colors, please! I
can't see almost nothing...
Nice effect, having the reflection alpha fade out to the back ground would
look great. Your code is kinda hard to read ( I had to change the CSS so I
could read it )