Flex的动画效果与变换(二)

本文出自http://www.jiangzone.com.cn/,如需转载,请注明出处!

原文地址:http://www.jiangzone.com.cn/article.asp?id=46

在上篇文章《Flex的动画效果与变换(一)》中讲到了使用Flex系统里面自带的一些动来效果的使用,但很多开发者都并不满足Flex里提供的简单的渐变大小,透明,移动,遮罩等的效果,如果是Flash的开发者的话,更不用说了,在Flash,多数人都是随意的制作一些动画效果等,而且形态多变。但是不是Flex里就不能实现呢?肯定不是,在Flex里也可以自定义动画效果,只不过就是没有Flash里面那么简单随意了。不过熟悉了之后,也会觉得在Flex里制作动画也不是什么难事,不多说了,转入正题!

在这里我先介绍一下Flex里面的动画效果机制,在Flex里面要使用动画效果的话,先要创建一个效果标签,之后在组件里(如TextInput)写上效果触发器,但可能会有人问,如果程序里我就只定义一个移动效果

<mx:Move>,之后我程序里面有5个组件,每个组件的动画效果都指向这个Move效果,那么它是不是组件一运行了效果后,组件二再触发效果,是不是组件一的效果会消失才会到组件二里播放?其它不是,虽然我们只定义了一个Move,但我们定义的只是Move效果的工厂,这里就用到了设计模式中的“工厂方法”模式,其实5个组件都可以同时运行效果,而5个效果都是不同的一个实例,彼此独立。所谓工厂方法模式,就好比是一家衣服制造工厂,A走进这家工厂说要一件衣服,工厂就制作一件合适A的Size的衣服,B进去,就会生产合适B的衣服,但A与B的衣服都是一样的。就好等于面向对象中的类与对象的关系一样。(我可能说多了-_-)

效果运行的时候,其实运行的不是Move这个对象,而是MoveInstance这个对象,Move只是工厂,既然一个动画效果就主要分这两大部份,我们就先建造一个工厂吧!

在Flex里面所有的效果的工厂都是继承自 mx.effects.Effect 这个类,我们也不能搞特殊,我们自定义的效果也要继承那个类,先看以下整个工厂类的代码:

[复制到剪贴板]

CODE:

package com.jiangzone.flex.effects {

import mx.effects.Effect;

import mx.effects.EffectInstance;

public class MyEffect extends Effect {

private var _color:Number = 0xFF0000;

public function set color(value:Number):void {

_color = value;

}

public function MyEffect(newTarget:Object = null) {

super(newTarget);

instanceClass = MyEffectInstance;

}

override public function getAffectedProperties( ):Array {

return [];

}

override protected function initInstance(instance:EffectInstance):void {

super.initInstance(instance);

MyEffectInstance(instance).color = _color;

}

}

}

大家看看上面的代码,其中先看构造函数,构造函数要接收一个默认为空的Object对象

public function MyEffect(newTarget:Object = null)

之后在该构造函数里面调用父类的构造函数,并且将instanceClass这个属性设置为你的该效果的实例类,因为这个类是工厂类,所以要知道你这个工厂生产什么产品,即上面说的“衣服”,所以这里我们将其命名为MyEffectInstance,注意:在Flex中的所有效果实例类都是在工厂类后面加Instance,也不是一定,只是规范而已。还有注意,下面一会定义的实例类的类名一定要跟这里的一致。

大家还会看到,上面的代码中,复写(override)了二个方法:getAffectedProperties( )与initInstance(instance:EffectInstance)

这两个方法都是要复写的,先说说getAffectedProperties( )这个方法,这个方法是获取被改变的属性值,怎么说呢,比如说,你做的动画效果如果要用到组件对象的一些属性的话,就要返回这些属性的名字,如:你的效果是对组件做旋转的话,则:

[复制到剪贴板]

CODE:

override public function getAffectedProperties( ):Array {

return ["rotation"];

}

反正你做的效果需要对组件修改什么属性的话,都在这个方法里返回名字,修改多个属性的话就往数组里加就是了。

后面就是这个方法了initInstance,该方法接收一个instance:EffectInstance参数,也就是效果实例类啦,因为每个效果实例类都要继承EffectInstance类,所以这个方法里的参数写的是父类,在里面要做其它的话,需要将 instance 转换为你相应的效果类。在这个方法里面,也是要调用父类的同名方法:super.initInstance(instance);

基本上,一个工厂类就写好了,但这样只是最简单的写法,试想想,每个人穿衣服的Size不同,喜欢的颜色也不同,所以,是不是可以由用户来定义他们想要的效果的颜色等属性呢?当然,你对衣服有什么要求,都是向工厂提出的,没有人会对衣服说吧?所以,这些可设置的属性也是定义在工厂类里面,所以下面,我们为该衣服可定制颜色为例,在工厂类里面加入如下代码:

[复制到剪贴板]

CODE:

private var _color:Number = 0xFF0000;

public function set color(value:Number):void {

_color = value;

}

你想运行时的效果可以设置不同的颜色的话,就可以直接设置MyEffect的color属性,之后将这个属性传给效果实例类:

[复制到剪贴板]

CODE:

override protected function initInstance(instance:EffectInstance):void {

super.initInstance(instance);

MyEffectInstance(instance).color = _color;

}

这些对效果实例类的设置,都是要定在initInstance方法里了,你想对运行时的效果设置什么属性的话,都要先告诉工厂类,之后工厂类在这个方法里面转嫁给实例类,这样,同一个效果,可以运行不同的颜色。但前提是你后面要写的实例类要有color这个属性。

现在已做好了工厂类了,下面要做效果实例类了,先贴出完整代码:

[复制到剪贴板]

CODE:

package com.jiangzone.flex.effects {

import mx.effects.EffectInstance;

import flash.display.Shape;

import flash.events.Event;

public class MyEffectInstance extends EffectInstance {

private var _color:Number;

private var shape:Shape;

public function set color(value:Number):void {

_color = value;

}

public function MyEffectInstance(newTarget:Object) {

super(newTarget);

}

override public function play( ):void {

super.play( );

drawShape();

}

private function drawShape():void{

shape = new Shape();

shape.graphics.beginFill(_color);

shape.graphics.drawRect(target.width * -0.5,target.height * -0.5,target.width,target.height);

shape.graphics.endFill();

shape.x = target.x + target.width * 0.5;

shape.y = target.y + target.height * 0.5;

target.parent.rawChildren.addChild(shape);

target.addEventListener(Event.ENTER_FRAME,onEnterFrame);

}

private function onEnterFrame(e:Event):void{

shape.scaleX += 0.1;

shape.scaleY += 0.1;

shape.alpha -= 0.05;

if(shape.alpha <= 0){

target.parent.rawChildren.removeChild(shape);

target.removeEventListener(Event.ENTER_FRAME,onEnterFrame);

}

}

}

}

我们看到,每一个动画效果实例类,都要继承自EffectInstance这个类,构造函数也是需要接收一个Object,这个Object其实就是你要应用到的组件对象,这个会是系统自动传递的,接收了Object后还要用该Object 调用父类的构造函数:super(newTarget);

之后还有一件必做的事,就是重写play()这个方法:override public function play( ):void

是不是对play()很熟悉?因为第一篇文章中,就用到这个方法来发动效果的播放的,所以,你需要做的动画编程都是在这个方法里。但还是要先调用父类的同名方法,super.play();之后的,就是你想怎么画就怎么画啦。我将画一个与要应用效果的组件一样大小的矩型,之后该矩形会放大并透明,效果都写在drawShape()方法里了。看到这个方法里面的代码,是不是跟Flash里的一样了?

这里先看看最终效果:

在这里,我用了ENTER_FRAME的写法,但是如果不用ENTER_FRAME方式制作动画的话,还有另外一种方法的,那就是Tween了,Tween是以“时间”为准,而ENTER_FRAME是以“帧”为准,其实到这里,一个基本的Flex自定义动画效果就完成了,但扩展一下的,还可以用Tween来实现,而且建议用Tween来写动画效果,易控制,清淅一点。用Tween实现的话,效果与写法都是差不多的,要用Tween就要将效果实例类继承自TweenEffectInstance这个类,并重写它的onTweenUpdate( )方法与onTweenEnd( )方法,这种Tween效果的写法,将会比ENTER_FRAME的写法方便,因为它根据的是时间,所以,你可以指定效果播放的时间,并且当播放完毕会自动调用onTweenEnd()方法,你可以在该方法里写一些处理操作,如释放资源等等

由于编幅关系,就不在这里详细介绍TweenEffectInstence了,就简单贴出该类的写法与注释吧:

[复制到剪贴板]

CODE:

package com.jiangzone.flex.effects {

import mx.effects.effectClasses.TweenEffectInstance;

import flash.display.Shape;

import flash.events.Event;

import mx.effects.Tween;

public class MyEffectInstance extends TweenEffectInstance {

private var _color:Number;

private var shape:Shape;

public function set color(value:Number):void {

_color = value;

}

//构造函数

public function MyEffectInstance(newTarget:Object) {

super(newTarget);

}

//同样的要重写play()方法与调用父类同名方法

override public function play( ):void {

super.play();

drawShape(); //先创建一个矩形

/*注意:用Tween效果写法的话,就一定要创建一个Tween对象

第一个参数是侦听器,即侦听Update与End的,这两个方法都在这个类里,

所以这里就写this,第二和第三个参数都是一个数组

第二个参数是初始值数组,第三个是结果值数组,都要一一对应,第四个是变化时间

这里的是[1,1]分别是初始时的scale比例与alpha,[3,0]就是最终结果数值

系统会自动在1000毫秒里平分这些值来得到渐变效果

并将每一次数值的改变时调用Update方法,结束后调用End方法

你也可以将时间的参数发布到工厂类属性里,可以方便设置播放时间,像Flex自带效果一样

*/

new Tween(this,[1,1],[3,0],1000);

}

override public function onTweenUpdate(value:Object):void{

//这里将改变的数值应用到组件对象中。注意:也要与上面的数值数组相对应。

shape.scaleX = Number(value[0]);

shape.scaleY = Number(value[0]);

shape.alpha = Number(value[1]);

}

override public function onTweenEnd(value:Object):void {

//当播放完时会自动调用该方法,这里就做删除该矩形的操作吧

target.parent.rawChildren.removeChild(shape);

}

private function drawShape():void{

shape = new Shape();

shape.graphics.beginFill(_color);

shape.graphics.drawRect(target.width * -0.5,target.height * -0.5,target.width,target.height);

shape.graphics.endFill();

shape.x = target.x + target.width * 0.5;

shape.y = target.y + target.height * 0.5;

target.parent.rawChildren.addChild(shape);

}

}

}

就写到这里吧,关于Tween其它的,就留作为作业,让大家思考与探索吧!之后如果有时间的话,将会写完下篇文章介绍Flex的“变面”动画,即状态变换!这里先谢谢大家支持!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CSS是一种用于网页设计的样式表语言,它可以控制网页的布局、字体、颜色、大小、背景、边框、动画等方面。下面是一些常用的CSS属性和动画特效: 1. 属性 - background-color:设置元素的背景色。 - color:设置元素的文字颜色。 - font-size:设置元素的文字大小。 - border:设置元素的边框。 - padding:设置元素的内边距。 - margin:设置元素的外边距。 - display:设置元素的显示方式,如block、inline、inline-block等。 - position:设置元素的定位方式,如relative、absolute等。 - z-index:设置元素的堆叠顺序。 - transform:设置元素的变换效果,如旋转、缩放、平移等。 2. 动画特效 - transition:设置元素的过渡效果,如颜色、大小、位置等属性的变化过渡。 - animation:设置元素的动画效果,如旋转、移动、闪烁等。 - keyframes:定义动画的关键帧,即动画从哪个状态到哪个状态。 例如,实现旋转照片墙可以使用以下CSS代码: ```css .photo-wall { display: flex; flex-wrap: wrap; justify-content: center; } .photo { width: 200px; height: 200px; margin: 10px; border: 1px solid #ccc; transition: transform .5s ease-in-out; } .photo:hover { transform: rotateY(180deg); } ``` 其中,.photo-wall是照片墙的容器,.photo是每张照片的样式,当鼠标悬停在照片上时,会触发transform属性的变化,从而实现照片的旋转效果

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值