浏览 5020 次
锁定老帖子 主题:一个简单的组件弹出弹入效果
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-09-25
最后修改:2010-09-25
OK, 废话到此为止。Flex 本身的 PopupButton 实现了一种弹出弹入组件的效果。我很喜欢。遗憾的是A司并没有把这种效果抽取出来作为效果类发布。好在原理和实现都不复杂,所以自己写了一个,功能并不完善但刚刚够用。合适的才是最好的嘛。 原理很简单:利用继承 Animate 效果类, 操作 UIComponent 的 scrollRect 的 x|y 坐标值来实现目标组件弹出和弹入。考虑到有些组件有用样式产生的阴影,这种阴影显示在 scrollRect 的范围之外,所以效果使用了边际值来补偿这种显示局限。用代码说话。 PopupEffect.mxml <?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" xmlns:myEffect="customEffect.*" width="600" height="600" viewSourceURL="srcview/index.html"> <s:layout> <s:BasicLayout/> </s:layout> <fx:Declarations> <s:Power id="powerEasing" exponent="5"/> <!-- 主要属性说明: direction up, down, left, right —— 控制组件的运动方向 marginTop marginBottom marginLeft marginRight —— 整形,表像素, 控制组件的边际空白大小 --> <myEffect:PopupEffect id="popup" direction="left" easer="{powerEasing}" duration="500" marginLeft="20" marginRight="20" marginBottom="20" /> </fx:Declarations> <s:states> <s:State name="Un" /> <s:State name="Deux" /> <s:State name="Trois" /> </s:states> <s:transitions> <s:Transition> <myEffect:PopupEffect targets="{[p1,i2,r3]}" direction="up" duration="500" marginLeft="20" marginRight="20" marginBottom="20" /> </s:Transition> </s:transitions> <!-- View State 演示 --> <s:Panel id="p1" width="390" height="200" title="Un" includeIn="Un" x="110" y="50"> <s:Label text="This is a Panel with dropShadow" x="56" y="60" fontSize="19"/> </s:Panel> <mx:Image id="i2" source="@Embed(source='assets/logo.jpg')" horizontalCenter="0" verticalCenter="-178" includeIn="Deux"/> <mx:RichTextEditor id="r3" height="200" width="390" text="View State Trois" horizontalCenter="0" verticalCenter="-160" includeIn="Trois"/> <s:Button label="Un" width="40" x="75" y="94" rotation="-90" click="currentState='Un'" /> <s:Button label="Deux" width="50" x="75" y="150" rotation="-90" click="currentState='Deux'" /> <s:Button label="Trois" width="60" x="75" y="217" rotation="-90" click="currentState='Trois'" /> <!-- ViewStack 演示 --> <mx:ViewStack id="viewstack1" horizontalCenter="-2" verticalCenter="119" height="220" width="446"> <s:NavigatorContent label="Alpha" width="100%" height="100%" showEffect="{popup}" hideEffect="{popup}"> <s:Panel width="390" height="200" title="View Alpha" horizontalCenter="0" verticalCenter="0"> <s:Label text="This is a Panel with dropShadow" x="56" y="60" fontSize="19"/> </s:Panel> </s:NavigatorContent> <s:NavigatorContent label="Bravo" width="100%" height="100%" showEffect="{popup}" hideEffect="{popup}"> <mx:Image source="@Embed(source='assets/logo.jpg')" horizontalCenter="0" verticalCenter="0"/> <s:Label y="182" text="View Bravo" fontSize="16" horizontalCenter="0"/> </s:NavigatorContent> <s:NavigatorContent label="Charlie" width="100%" height="100%" showEffect="{popup}" hideEffect="{popup}"> <mx:RichTextEditor height="200" width="390" text="View Charlie" horizontalCenter="0" verticalCenter="0"/> </s:NavigatorContent> </mx:ViewStack> <s:ButtonBar dataProvider="{viewstack1}" x="197" y="543"/> <s:Label x="243" y="291" text="ViewStack 示例" fontSize="17" x.Un="243" y.Un="297" text.Un="ViewStack 演示"/> <s:Label includeIn="Un" x="238" y="27" text="View State 演示" fontSize="16"/> </s:Application> PopupEffect.as /* Copyright 2010 Tu Ding */ package customEffect{ import flash.geom.Rectangle; import mx.core.IVisualElement; import mx.core.IVisualElementContainer; import mx.core.UIComponent; import mx.effects.IEffectInstance; import mx.events.FlexEvent; import spark.effects.Animate; import spark.effects.animation.Animation; import spark.effects.animation.IAnimationTarget; import spark.effects.animation.MotionPath; import spark.effects.animation.SimpleMotionPath; import spark.effects.supportClasses.AnimateInstance; /* 实现组件的弹入或弹出效果 */ public class PopupEffect extends Animate { /* 组件运动的方向 “上右下左” */ [Inspectable( catalog="Common", type="String",enumeration="up,right,down,left", defaultValue = "up" )] public var direction:String = "up"; // 考虑到有些组件的阴影或滤镜效果,需要设置一个对目标组件的边际填充值 [Inspectable( catalog="General", type="Number", defaultValue = "0" )] public var marginTop:int = 0; [Inspectable( catalog="General", type="Number", defaultValue = "0" )] public var marginRight:int = 0; [Inspectable( catalog="General", type="Number", defaultValue = "0" )] public var marginBottom:int = 0; [Inspectable( catalog="General", type="Number", defaultValue = "0" )] public var marginLeft:int = 0; public function PopupEffect( target:UIComponent = null ) { super( target ); instanceClass = PopupEffectInstance; } override protected function initInstance(instance:IEffectInstance):void { super.initInstance( instance ); var inst:PopupEffectInstance = instance as PopupEffectInstance; inst.direction = direction; inst.marginTop = marginTop; inst.marginRight = marginRight; inst.marginBottom = marginBottom; inst.marginLeft = marginLeft; } /** * @private */ override public function getAffectedProperties():Array /* of String */ { return ["parent"]; } } } import flash.geom.Rectangle; import mx.core.UIComponent; import mx.events.FlexEvent; import spark.effects.animation.Animation; import spark.effects.animation.MotionPath; import spark.effects.animation.SimpleMotionPath; import spark.effects.supportClasses.AnimateInstance; class PopupEffectInstance extends AnimateInstance { public var direction:String; public var marginTop:int; public var marginRight:int; public var marginBottom:int; public var marginLeft:int; public function PopupEffectInstance( target:Object ) { super( target ); autoRemoveTarget = true; } override public function play():void { var t:UIComponent = target as UIComponent; var scrollX:int = 0; var scrollY:int = 0; // 效果实际是利用 UIComponent 的 scrollRect 来实现,结合组件的边际填充来设置 scrollRect 的尺寸 var rectWidth:int = t.width + marginLeft + marginRight; var rectHeight:int = t.height + marginTop + marginBottom; // 保存效果中组件需要的位移 var offset:int; // 由于 marginLeft 的存在,需要修正坐标值组件 scrollRect 的初始坐标 var revisedLocation:int; // 修改组件位置以补偿设置 scrollRect 后造成的偏移 // 修改只需要在第一次应用效果时,通过条件判断避免多次修改 if ( null == t.scrollRect ) { t.x -= marginLeft; t.y -= marginTop; } switch( direction ) { case "up": revisedLocation = -marginTop; offset = rectHeight; scrollY = offset; break; case "right": revisedLocation = -marginLeft; offset = -rectWidth; scrollX = offset; break; case "down": revisedLocation = -marginTop; offset = -rectHeight; scrollY = offset; break; case "left": revisedLocation = -marginLeft; offset = rectWidth; scrollX = offset; } if ( null != triggerEvent ) if ( triggerEvent.type == FlexEvent.SHOW ) { t.scrollRect = new Rectangle( scrollX - marginLeft, scrollY - marginTop, rectWidth, rectHeight ); motionPaths = new <MotionPath>[ new SimpleMotionPath("value", offset, revisedLocation)]; }else{ t.scrollRect = new Rectangle( 0 - marginLeft, 0 - marginTop, rectWidth, rectHeight ); motionPaths = new <MotionPath>[ new SimpleMotionPath("value", revisedLocation, offset)]; } if ( propertyChanges ) { var parentChange:Boolean = propertyChanges.end["parent"] !== undefined && propertyChanges.end["parent"] != propertyChanges.start["parent"]; if ( parentChange ) { var moveIn:Boolean = parentChange && propertyChanges.end["parent"]; if (moveIn) { t.scrollRect = new Rectangle( scrollX - marginLeft, scrollY - marginTop, rectWidth, rectHeight ); motionPaths = new <MotionPath>[ new SimpleMotionPath("value", offset, revisedLocation)]; } else { t.scrollRect = new Rectangle( 0 - marginLeft, 0 - marginTop, rectWidth, rectHeight ); motionPaths = new <MotionPath>[ new SimpleMotionPath("value", revisedLocation, offset)]; } } } super.play(); } override public function animationUpdate(animation:Animation):void { super.animationUpdate(animation); var t:UIComponent = target as UIComponent; var rect:Rectangle = t.scrollRect; if ( direction == "up" || direction == "down" ) rect.y = int(animation.currentValue["value"]); else rect.x = int(animation.currentValue["value"]); t.scrollRect = rect; } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-01-19
好文章, 现在直接用spark Animate的例子还真不多呀!!
|
|
返回顶楼 | |
发表时间:2011-08-10
smithfox 写道 好文章, 现在直接用spark Animate的例子还真不多呀!! 文件还可以,我正想学习来的 |
|
返回顶楼 | |