Need Flex Migration Help?
- Adobe ends Flash player support in 2020
- Flex apps will no longer function
- We can help migrate your app
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,);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: