相对Flash来说Flex的动画功能还是比较弱的,Flash的动画基于帧、时间轴等概念,而Flex的动画则基于Flex内部的{tx},使用麻烦而且有时候还达不到想要的效果。笔者试过在Flex中使用Flash同样的脚本创建一个跑马灯动画,居然能把程序卡死~
下面结合项目中的实际例子讲一下Flash和Flex结合制作动画的方法,在Flash中制作一些动画作为Flex的组件,然后在Flex中像普通组件一样随意使用。
首先描述下本功能,在程序中弹出一个类似桌面歌词的牌子,牌子里滚动的显示一些重要的业务信息,点击某个信息能在地图中定位该信息宿主的位置。
1.Flash制作swc包
首先看一下它们之间的区别:
flex中的架构,(举例UIComponent类的继承关系)
UIComponent > FlexSprite> Sprite >DisplayObjectContainer>InteractiveObject >Displayobject
flash中的架构(Sprite类的继承关系)
Sprite >DisplayObjectContainer>InteractiveObject >Displayobject
Flex中的UIMovieClip类继承于UIComponent ,flash中的MovieClip继承于Sprite,
flash中直接导出SWC,SWC中的元件属于MovieClip,而在Flex中不能在现实对象中直接添加没有IUIComponent接口的类对象,所以不能使用.
我们通过Adobe官方的插件 让Flash编译器把MovieClip转换成UIMovieClip。
下载该插件安装好之后可以在Flash中看到命令目录下面多了两个选项。
在Flash中制作好元件,然后右键点导出SWC文件。
导出成功之后再查看该元件的属性,可以看到这时该元件的基类已经变成了 mx.flash.UIMovieClip
实际上,在我的例子里只是做了一个空的元件(作为显示内容的容器),然后导出swc文件,为的是能用Flash的框架来实现Flex里不容易而Flash轻而易举就能实现的动画,看稍后的代码部分就会明白~
2.Flex中使用导出的swc文件
在Flex工程中引用刚才生成的wsc文件,下面直接贴代码~~
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx=" width="400" height="30" backgroundAlpha="0" horizontalScrollPolicy="off" creationComplete="init()" xmlns:local="*">
<mx:Script>
<![CDATA[
import com.esri.solutions.flexviewer.SiteContainer;
import fl.controls.Label;
import mx.collections.ArrayCollection;
var ismove:Boolean=true;
var lb1:Label;
private var medalsAC:ArrayCollection = new ArrayCollection( [
{ STNM: "1水文站", Gold: 35, Silver:39, STCD: "12300" },
{ STNM: "2水文站", Gold: 32, Silver:17, STCD: "12301" },
{ STNM: "3水位站", Gold: 27, Silver:27, STCD: "12302" } ]);
//初始化把显示内容加入广告容器
private function init():void
{
for(var i:int=0;i<medalsAC.length;i++)
{
lb1=new Label(); //注意这里的Label是Flash里的fl.controls.Label
lb1.autoSize="left";
lb1.width=200;
lb1.x=i*300;
var text:String=medalsAC[i].STNM+":水位("+medalsAC[i].Gold+"m),流量("+medalsAC[i].Silver+"m<font size='16'>³</font>/s)";
lb1.htmlText="<b><font size='17' color='#ffffff'>"+text+"</font></b>";
lb1.name=medalsAC[i].STCD; //用于后面能根据名字拿到关键信息
lb1.addEventListener(Event.ENTER_FRAME,onEnterframe); //监听ENTER_FRAME时间 让其动起来
lb1.addEventListener(MouseEvent.MOUSE_OVER,onMouseOver);//鼠标移入 停止滚动
lb1.addEventListener(MouseEvent.MOUSE_OUT,onMouseOut);//鼠标移出 继续滚动
lb1.addEventListener(MouseEvent.CLICK,onDBClick); //双击 定位
ad.addChildAt(lb1,i);
}
}
private function onMouseOver(e:MouseEvent):void
{
e.target.x=e.target.x;
ismove=false;
}
private function onMouseOut(e:MouseEvent):void
{
ismove=true;
}
private function onEnterframe(e:Event):void
{
if(ismove)
{
e.currentTarget.x-=2; //向左移动2像素
if(e.currentTarget.x+e.currentTarget.width<0) //如果跑出容器 继续循环
{
e.currentTarget.x=ad.width;
}
}
}
//地图定位操作
private function onDBClick(e:MouseEvent):void
{
var stcd:String=e.currentTarget.name;
…
}
]]>
</mx:Script>
<!--
AD3 就是刚才导出来的swc里的组件
-->
<local:AD3 id="ad" alpha="0">
</local:AD3>
</mx:Canvas>
在这里,我们可以在Flex中通过程序控制动画的方向、速度、文字的颜色、大小等等 还可以用Flex访问数据库更便捷的特点 从webservice或httpservice等获取要显示的内容。下面贴两张图~~
结语:或许通过Flash直接做成一个可访问外部数据和可配置的swf动画,然后在Flex中使用更简单,不过笔者在使用过程中总感觉Flash对外部数据的操作总是感觉有些麻烦~ 应该是不熟悉Flash的原因~