在这里我先介l一下Flex里面的动L果机Ӟ在Flex里面要用动L果的话,先要创徏一个效果标{,之后在组仉Q如TextInputQ写上效果触发器Q但可能?x)有人问Q如果程序里我就只定义一个移动效?br />
<mx:Move>Q之后我E序里面?个组Ӟ每个lg的动L果都指向q个Move效果Q那么它是不是组件一q行了效果后Q组件二再触发效果,是不是组件一的效果会(x)消失才会(x)到组件二里播放?其它不是Q虽然我们只定义了一个MoveQ但我们定义的只是Move效果的工厂,q里qC设计模式中的“工厂Ҏ(gu)”模式Q其?个组仉可以同时q行效果Q?个效果都是不同的一个实例,彼此独立。所谓工厂方法模式,好比是一家衣服制造工厂,A走进q家工厂说要一件衣服,工厂制作一件合适A的Size的衣服,Bq去Q就?x)生产合适B的衣服,但A与B的衣服都是一L(fng)。就好等于面向对象中的类与对象的关系一栗(我可能说多了-_-Q?br />
效果q行的时候,其实q行的不是Moveq个对象Q而是MoveInstanceq个对象QMove只是工厂Q既然一个动L果就主要分这两大部䆾Q我们就先徏造一个工厂吧Q?br />
在Flex里面所有的效果的工厂都是承自 mx.effects.Effect q个c,我们也不能搞Ҏ(gu)Q我们自定义的效果也要扉K个类Q先看以下整个工厂类的代码:(x)
1 package com.jiangzone.flex.effects {
2 import mx.effects.Effect;
3 import mx.effects.EffectInstance;
4
5 public class MyEffect extends Effect {
6 private var _color:Number = 0xFF0000 ;
7
8 public function set color(value:Number): void {
9 _color = value;
10 }
11
12 public function MyEffect(newTarget:Object = null ) {
13 super (newTarget);
14 instanceClass = MyEffectInstance;
15 }
16
17 override public function getAffectedProperties( ):Array {
18 return [];
19 }
20
21 override protected function initInstance(instance:EffectInstance): void {
22 super .initInstance(instance);
23 MyEffectInstance(instance).color = _color;
24 }
25 }
26 }
大家看看上面的代码,其中先看构造函敎ͼ构造函数要接收一个默认ؓ(f)I的Object对象
public function MyEffect(newTarget:Object = null)
之后在该构造函数里面调用父cȝ构造函敎ͼq且instanceClassq个属性设|ؓ(f)你的该效果的实例c,因ؓ(f)q个cL工厂c,所以要知道你这个工厂生产什么品,即上面说?#8220;衣服”Q所以这里我们将其命名ؓ(f)MyEffectInstanceQ注意:(x)在Flex中的所有效果实例类都是在工厂类后面加InstanceQ也不是一定,只是规范而已。还有注意,下面一?x)定义的实例cȝcd一定要跟这里的一致?br />
大家q会(x)看到Q上面的代码中,复写QoverrideQ了二个Ҏ(gu)QgetAffectedProperties( )与initInstance(instance:EffectInstance)
q两个方法都是要复写的,先说说getAffectedProperties( )q个Ҏ(gu)Q这个方法是获取被改变的属性|怎么说呢Q比如说Q你做的动画效果如果要用到组件对象的一些属性的话,pq回q些属性的名字Q如Q你的效果是对组件做旋{的话Q则Q?br />
1 override public function getAffectedProperties( ):Array {
2 return [ " rotation " ];
3 }
反正你做的效果需要对lg修改什么属性的话,都在q个Ҏ(gu)里返回名字,修改多个属性的话就往数组里加是了?br />
后面是q个Ҏ(gu)了initInstanceQ该Ҏ(gu)接收一个instance:EffectInstance参数Q也是效果实例cdQ因为每个效果实例类都要l承EffectInstancec,所以这个方法里的参数写的是父类Q在里面要做其它的话Q需要将 instance 转换Z相应的效果类。在q个Ҏ(gu)里面Q也是要调用父类的同名方法:(x)super.initInstance(instance);
基本上,一个工厂类写好了Q但q样只是最单的写法Q试xQ每个hI衣服的Size不同Q喜Ƣ的颜色也不同,所以,是不是可以由用户来定义他们想要的效果的颜色等属性呢Q当Ӟ你对衣服有什么要求,都是向工厂提出的Q没有h?x)对衣服说吧Q所以,q些可设|的属性也是定义在工厂c里面,所以下面,我们衣服可定刉色ؓ(f)例,在工厂类里面加入如下代码Q?br />
1 private var _color:Number = 0xFF0000 ;
2 public function set color(value:Number): void {
3 _color = value;
4 }
你想q行时的效果可以讄不同的颜色的话,可以直接设|MyEffect的color属性,之后这个属性传l效果实例类Q?br />
1 override protected function initInstance(instance:EffectInstance): void {
2 super .initInstance(instance);
3 MyEffectInstance(instance).color = _color;
4 }
q些Ҏ(gu)果实例类的设|,都是要定在initInstanceҎ(gu)里了Q你惛_q行时的效果讄什么属性的话,都要先告诉工厂类Q之后工厂类在这个方法里面{嫁给实例c,q样Q同一个效果,可以q行不同的颜艌Ӏ但前提是你后面要写的实例类要有colorq个属性?br />
现在已做好了工厂cMQ下面要做效果实例类了,先脓(chung)出完整代码:(x)
1 package com.jiangzone.flex.effects {
2 import mx.effects.EffectInstance;
3 import flash.display.Shape;
4 import flash.events.Event;
5
6 public class MyEffectInstance extends EffectInstance {
7
8 private var _color:Number;
9 private var shape:Shape;
10
11 public function set color(value:Number): void {
12 _color = value;
13 }
14
15 public function MyEffectInstance(newTarget:Object) {
16 super (newTarget);
17 }
18
19 override public function play( ): void {
20 super .play( );
21 drawShape();
22 }
23
24 private function drawShape(): void {
25 shape = new Shape();
26 shape.graphics.beginFill(_color);
27 shape.graphics.drawRect(target.width * - 0.5 ,target.height * - 0.5 ,target.width,target.height);
28 shape.graphics.endFill();
29 shape.x = target.x + target.width * 0.5 ;
30 shape.y = target.y + target.height * 0.5 ;
31 target.parent.rawChildren.addChild(shape);
32 target.addEventListener(Event.ENTER_FRAME,onEnterFrame);
33 }
34
35 private function onEnterFrame(e:Event): void {
36 shape.scaleX += 0.1 ;
37 shape.scaleY += 0.1 ;
38 shape.alpha -= 0.05 ;
39 if (shape.alpha <= 0 ){
40 target.parent.rawChildren.removeChild(shape);
41 target.removeEventListener(Event.ENTER_FRAME,onEnterFrame);
42 }
43 }
44 }
45 }
我们看到Q每一个动L果实例类Q都要承自EffectInstanceq个c,构造函C是需要接收一个ObjectQ这个Object其实是你要应用到的lg对象Q这个会(x)是系l自动传递的Q接收了Object后还要用该Object 调用父类的构造函敎ͼ(x)super(newTarget);
之后q有一件必做的事,是重写play()q个Ҏ(gu)Qoverride public function play( ):void
是不是对play()很熟(zhn)?因ؓ(f)W一文章中Q就用到q个Ҏ(gu)来发动效果的播放的,所以,你需要做的动ȝE都是在q个Ҏ(gu)里。但q是要先调用父类的同名方法,super.play();之后的,是你想怎么d怎么d。我画一个与要应用效果的lg一样大的矩型Q之后该矩Ş?x)放大ƈ透明Q效果都写在drawShape()Ҏ(gu)里了。看到这个方法里面的代码Q是不是跟Flash里的一样了Q?br />
q里再脓(chung)上MXML代码Q?br />
1 <? xml version="1.0" encoding="utf-8" ?>
2 < mx:Application layout ="absolute" xmlns:mx ="http://www.adobe.com/2006/mxml"
3 xmlns:pf ="com.jiangzone.flex.effects.*" >
4 < pf:MyEffect id ="myEffect" color ="0xFFFFFF" />
5 < mx:VBox x ="100" y ="43" >
6 < mx:TextInput focusInEffect ="{myEffect}" />
7 < mx:TextInput focusInEffect ="{myEffect}" />
8 < mx:TextInput focusInEffect ="{myEffect}" />
9 < mx:TextInput focusInEffect ="{myEffect}" />
10 </ mx:VBox >
11 </ mx:Application >
q里先看看最l效果:(x)
在这里,我用了ENTER_FRAME的写法,但是如果不用ENTER_FRAME方式制作动画的话Q还有另外一U方法的Q那是Tween了,Tween是以“旉”为准Q而ENTER_FRAME是以“?#8221;为准Q其实到q里Q一个基本的Flex自定义动L果就完成了,但扩展一下的Q还可以用Tween来实玎ͼ而且用Tween来写动画效果Q易控制Q清淅一炏V用Tween实现的话Q效果与写法都是差不多的Q要用Tweenp效果实例类l承自TweenEffectInstanceq个c,q写它的onTweenUpdate( )Ҏ(gu)与onTweenEnd( )Ҏ(gu)Q这UTween效果的写法,会(x)比ENTER_FRAME的写法方便,因ؓ(f)它根据的是时_(d)所以,你可以指定效果播攄旉Qƈ且当播放完毕?x)自动调用onTweenEnd()Ҏ(gu)Q你可以在该Ҏ(gu)里写一些处理操作,如释放资源等{?br />
׃~幅关系Q就不在q里详细介绍TweenEffectInstence了,q单脓(chung)cȝ写法与注释吧Q?br />
1 package com.jiangzone.flex.effects {
2 import mx.effects.effectClasses.TweenEffectInstance;
3 import flash.display.Shape;
4 import flash.events.Event;
5 import mx.effects.Tween;
6
7 public class MyEffectInstance extends TweenEffectInstance {
8
9 private var _color:Number;
10 private var shape:Shape;
11
12 public function set color(value:Number): void {
13 _color = value;
14 }
15
16 // 构造函?/span>
17 public function MyEffectInstance(newTarget:Object) {
18 super (newTarget);
19 }
20
21 // 同样的要重写play()Ҏ(gu)与调用父cd名方?/span>
22 override public function play( ): void {
23 super .play();
24 drawShape(); // 先创Z个矩?/span>
25 /* 注意Q用Tween效果写法的话Q就一定要创徏一个Tween对象
26 W一个参数是侦听器,即侦听Update与End的,q两个方法都在这个类里,
27 所以这里就写this,W二和第三个参数都是一个数l?br />
28 W二个参数是初始值数l,W三个是l果值数l,都要一一对应Q第四个是变化时?br />
29 q里的是[1,1]分别是初始时的scale比例与alphaQ[3,0]是最l结果数?br />
30 pȝ?x)自动?000毫秒里^分这些值来得到渐变效果
31 q将每一ơ数值的改变时调用UpdateҎ(gu)Q结束后调用EndҎ(gu)
32 你也可以时间的参数发布到工厂类属性里Q可以方便设|播放时_(d)像Flex自带效果一?br />
33 */
34 new Tween( this ,[ 1 , 1 ],[ 3 , 0 ], 1000 );
35 }
36
37 override public function onTweenUpdate(value:Object): void {
38 // q里改变的数值应用到lg对象中。注意:(x)也要与上面的数值数l相对应?/span>
39 shape.scaleX = Number(value[ 0 ]);
40 shape.scaleY = Number(value[ 0 ]);
41 shape.alpha = Number(value[ 1 ]);
42 }
43
44 override public function onTweenEnd(value:Object): void {
45 // 当播攑֮时会(x)自动调用该方法,q里做删除该矩形的操作?/span>
46 target.parent.rawChildren.removeChild(shape);
47 }
48
49 private function drawShape(): void {
50 shape = new Shape();
51 shape.graphics.beginFill(_color);
52 shape.graphics.drawRect(target.width * - 0.5 ,target.height * - 0.5 ,target.width,target.height);
53 shape.graphics.endFill();
54 shape.x = target.x + target.width * 0.5 ;
55 shape.y = target.y + target.height * 0.5 ;
56 target.parent.rawChildren.addChild(shape);
57 }
58 }
59 }
写到这里吧Q关于Tween其它的,q作ؓ(f)作业Q让大家思考与探烦吧!之后如果有时间的话,会(x)写完下篇文章介绍Flex?#8220;变面”动画Q即状态变换!q里先谢谢大家支持!
]]>