这是参考一个老外写的Flex倒影特效,相当的方便。
// Reflector,by Narciso Jaramillo,nj_flex@rictus.com // copyright 2006 Narciso Jaramillo // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License,or (at your option) any later version. // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or fitness FOR A PARTIculaR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not,write to the Free Software // Foundation,Inc.,51 Franklin Street,Fifth Floor,Boston,MA 02110-1301,USA. // Partly based on ReflectFilter.as by Trey Long,trey@humanwasteland.com. package tools { import flash.display.BitmapData; import flash.display.GradientType; import flash.display.Sprite; import flash.events.Event; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; import mx.core.UIComponent; import mx.events.FlexEvent; import mx.events.MoveEvent; import mx.events.ResizeEvent; // imports for handling blur import flash.filters.BitmapFilter; import flash.filters.BitmapFilterQuality; import flash.filters.BlurFilter; /** * A component that displays a reflection below another component. * The reflection is "live"--as the other component's display updates,* the reflection updates as well. The reflection automatically positions * itself below the target component (so it only works if the target * component's container is absolutely positioned,like a Canvas or a * Panel with layout="absolute"). * * Typically,you'll want to set a low alpha on the Reflector component (0.3 * would be a good default). * * Author: Narciso Jaramillo,nj_flex@rictus.com */ public class Reflector extends UIComponent { // The component we're reflecting. private var _target: UIComponent; // Cached bitmap data objects. We store these to avoid reallocating // bitmap data every time the target redraws. private var _alphaGradientBitmap: BitmapData; private var _targetBitmap: BitmapData; private var _resultBitmap: BitmapData; // The current falloff value (see the description of the falloff property). private var _falloff: Number = 0.6; // the current blur value private var _blurAmount:Number = 0.5; /** * The UIComponent that you want to reflect. Should be in an absolutely- * positioned container. The reflector will automatically position itself * beneath the target. */ [Bindable] public function get target(): UIComponent { return _target; } public function set target(value: UIComponent): void { if (_target != null) { // Remove our listeners from the prevIoUs target. _target.removeEventListener(FlexEvent.UPDATE_COMPLETE,handleTargetUpdate,true); _target.removeEventListener(MoveEvent.MOVE,handleTargetMove); _target.removeEventListener(ResizeEvent.RESIZE,handleTargetResize); // Clear our bitmaps,so we regenerate them next time a component is targeted. clearCachedBitmaps(); } _target = value; if (_target != null) { // Register to get notified whenever the target is redrawn. We pass "true" // for useCapture here so we can detect when any descendants of the target are // redrawn as well. _target.addEventListener(FlexEvent.UPDATE_COMPLETE,true); // Register to get notified whenever the target moves or resizes. _target.addEventListener(MoveEvent.MOVE,handleTargetMove); _target.addEventListener(ResizeEvent.RESIZE,handleTargetResize); // Mark ourselves dirty so we get redrawn at the next opportunity. invalidatedisplayList(); } } /** * How much of the component to reflect,between 0 and 1; 0 means not to * reflect any of the component,while 1 means to reflect the entire * component. The default is 0.6. */ [Bindable] public function get falloff(): Number { return _falloff; } public function set falloff(value: Number): void { _falloff = value; // Clear the cached gradient bitmap,since we need to regenerate it to // reflect the new falloff value. _alphaGradientBitmap = null; invalidatedisplayList(); } [Bindable] public function get blurAmount(): Number { return _blurAmount; } public function set blurAmount(value: Number): void { _blurAmount = value; // Clear the cached gradient bitmap,since we need to regenerate it to // reflect the new falloff value. _alphaGradientBitmap = null; invalidatedisplayList(); } private function handleTargetUpdate(event: FlexEvent): void { // The target has been redrawn,so mark ourselves for redraw. invalidatedisplayList(); } private function handleTargetMove(event: MoveEvent): void { // Move to be immediately below the target. We don't need to // redraw ourselves in this case. move(_target.x,_target.y + _target.height); } private function handleTargetResize(event: ResizeEvent): void { // Since the target is resizing,we have to recreate our bitmaps // in addition to redrawing and resizing ourselves. clearCachedBitmaps(); width = _target.width; height = _target.height; invalidatedisplayList(); } override protected function updatedisplayList(unscaledWidth: Number,unscaledHeight: Number): void { // This function is called by the framework at some point after invalidatedisplayList() is called. if (_target != null) { // Create our cached bitmap data objects if they haven't been created already. createBitmaps(_target); var rect: Rectangle = new Rectangle(0,_target.width,_target.height); // Draw the image of the target component into the target bitmap. _targetBitmap.fillRect(rect,0x00000000); _targetBitmap.draw(_target,new Matrix()); // Combine the target image with the alpha gradient to produce the reflection image. _resultBitmap.fillRect(rect,0x00000000); _resultBitmap.copyPixels(_targetBitmap,rect,new Point(),_alphaGradientBitmap); // Flip the image upside down. var transform: Matrix = new Matrix(); transform.scale(1,-1); transform.translate(0,_target.height); // And blur it graphics.beginFill(0xFFCC00); graphics.drawRect(0,_target.height); graphics.endFill(); var filter:BitmapFilter = new BlurFilter(_blurAmount*5,_blurAmount*10,BitmapFilterQuality.HIGH); var myFilters:Array = new Array(); myFilters.push(filter); filters = myFilters; // Finally,copy the resulting bitmap into our own graphic context. graphics.clear(); graphics.beginBitmapFill(_resultBitmap,transform,false); graphics.drawRect(0,unscaledWidth,unscaledHeight); } } private function clearCachedBitmaps(): void { _alphaGradientBitmap = null; _targetBitmap = null; _resultBitmap = null; } private function createBitmaps(target: UIComponent): void { if (_alphaGradientBitmap == null) { // Create and store an alpha gradient. Whenever we redraw,this will be combined // with an image of the target component to create the "fadeout" effect. _alphaGradientBitmap = new BitmapData(target.width,target.height,true,0x00000000); var gradientMatrix: Matrix = new Matrix(); var gradientSprite: Sprite = new Sprite(); gradientMatrix.createGradientBox(target.width,target.height * _falloff,Math.PI/2,target.height * (1.0 - _falloff)); gradientSprite.graphics.beginGradientFill(GradientType.LINEAR,[0xFFFFFF,0xFFFFFF],[0,1],255],gradientMatrix); gradientSprite.graphics.drawRect(0,target.height * (1.0 - _falloff),target.width,target.height * _falloff); gradientSprite.graphics.endFill(); _alphaGradientBitmap.draw(gradientSprite,new Matrix()); } if (_targetBitmap == null) { // Create a bitmap to hold the target's image. This is updated every time // we're redrawn in updatedisplayList(). _targetBitmap = new BitmapData(target.width,0x00000000); } if (_resultBitmap == null) { // Create a bitmap to hold the reflected image. This is updated every time // we're redrawn in updatedisplayList(). _resultBitmap = new BitmapData(target.width,0x00000000); } } } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。