Flex实现组件自定义倒影效果之二:继承于Effect

经过笔者现今总结发现制作自定义组件倒影效果可以继承于UIComponent,还有一种是继承于Effect。按照Flex 的实现机制,创建效果时需要同时创建工厂类和相应的实例类。工厂类用来控制动画播放,而实例类则用来实现动画效果。

工厂类ReflectEffect.as:

package myComponents
{
import mx.effects.Effect;
import mx.effects.IEffectInstance;
public class ReflectEffect extends Effect
{
public function ReflectEffect(target:Object=null)
{
super(target);
instanceClass=ReflectEffectInstance;
}
}
}



实例类ReflectEffectInstance.as:

package myComponents
{
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.GradientType;
import flash.events.Event;
import flash.geom.Matrix;

import mx.core.UIComponent;
import mx.effects.EffectInstance;
import mx.states.AddChild;


public class ReflectEffectInstance extends EffectInstance
{
private var _target:UIComponent;
//创建一个UIComponent对象来绘制倒影
private var uiRef:UIComponent;
//创建一个遮罩对象来实现倒影的渐隐
private var mask:UIComponent;
//创建一个容器以便添加uiRef和mask
private var uiContainer:UIComponent;
//是否创建完成
private var created:Boolean=false;
//创建一个BitmapData对象,以便保存组件的截图
private var bmpRefleData:BitmapData;
//构造函数
public function ReflectEffectInstance(target:Object)
{
super(target);
_target=target as UIComponent;

}
//初始化方法
public function initReflection():void
{
if(created)
return;
uiContainer=new UIComponent();
uiRef=new UIComponent();
mask=new UIComponent();

//使用位图缓存
mask.cacheAsBitmap=true;
uiRef.cacheAsBitmap=true;
_target.parent.addChild(uiContainer);
uiContainer.addChild(uiRef);
uiContainer.addChild(mask);
created=true;
}
//设置倒影位置和大小
private function setPosition():void
{
if(!uiContainer)
return;
var w:Number=_target.width;
var h:Number=_target.height;
uiContainer.x=_target.x;
uiContainer.y=_target.y+h;

}
//绘制倒影
private function drawRefelction(w:Number,h:Number):void
{
if(!uiRef)
return;
bmpRefleData=new BitmapData(w,h,true,0x00000000);
bmpRefleData.draw(_target as DisplayObject);
//创建转换矩阵
var matrix:Matrix=new Matrix(1,0,0,-1,0,h);
uiRef.graphics.clear();
uiRef.graphics.beginBitmapFill(bmpRefleData,matrix,false,true);
uiRef.graphics.drawRect(0,0,w,h);
uiRef.graphics.endFill();
uiRef.width=w;
uiRef.height=h;
}
//绘制遮罩
private function drawMask(w:Number,h:Number):void
{
if(!mask)
return;
//设置遮罩的起止颜色变化值的数组
var colors:Array=[0x989898,0x909090];
//设置透明度的起止值的数组  0为不透明,1为透明
var alphas:Array=[0.6,1];
//设置遮罩显示范围 值 0 表示渐变框中的左侧位置,255 表示渐变框中的右侧位置。 
var ratios:Array=[0,150];
var gmatrix:Matrix=new Matrix();
gmatrix.createGradientBox(w,h,Math.PI/2,0,0);
mask.graphics.clear();
mask.graphics.beginGradientFill(GradientType.LINEAR,colors,alphas,ratios,gmatrix);
mask.graphics.drawRect(0,0,w,h);
mask.graphics.endFill();
mask.width=w;
mask.height=h;
}
//enterFrame事件处理
private function enterFrame(e:Event):void
{
if(created)
{
var w:Number=_target.width;
var h:Number=_target.height;
drawRefelction(w,h);
drawMask(w,h);

}
else
{
initReflection();
}
}
public override function set target(value:Object):void
{
_target=value as UIComponent;
_target.addEventListener(Event.ENTER_FRAME,enterFrame,false,0,true);
}
public override function get target():Object
{
return _target;
}
public override function play():void
{
super.play();
}
public override function pause():void
{
super.pause();
}
public override function end():void
{
super.end();
}
}
}

这样我们实现倒影的类已经完成,最后就是将他显示出来,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
  xmlns:s="library://ns.adobe.com/flex/spark" 
  xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"xmlns:MyEffect="myComponents.*"
  xmlns:util="myComponents.*" backgroundColor="0x909090">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Declarations>
<!-- 将非可视元素(例如服务值对象)放在此处 -->
<MyEffect:ReflectEffect id="reflect"/>
</fx:Declarations>

<!-- 使用时应该在指定效果的组件外添加一个父容器,否则会出现错误 -->

<mx:VBox x="427" y="105">
<mx:Panel id="panel1" creationCompleteEffect="{reflect}" x="446" y="106">
<mx:TextInput>

</mx:TextInput>
<mx:Image source="images/3.png" width="173" height="172"/>
</mx:Panel>
</mx:VBox>
</s:Application>

完成后与使用继承于UIComponent的倒影效果对比图:



注:另外笔者在网上搜罗,发现一个利用swc文件导入直接使用的例子,链接:http://www.iteye.com/topic/1115866


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值