首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

一个简略的组件弹出弹入效果

2012-11-25 
一个简单的组件弹出弹入效果什么是好的效果。我的体会是那些模拟真实世界的物体运动,被现有物理学所支持的

一个简单的组件弹出弹入效果
什么是好的效果。我的体会是那些模拟真实世界的物体运动,被现有物理学所支持的简洁效果才是历久常新,实用的好效果。这是由人脑本身的思维模式所决定的。iPhone就是一个很典型的例子。某些视觉冲击极强的效果,在初接触的时候确实能给人耳目一新的感觉,但是超现实的手法看久了难免会有审美疲劳,反而会让人觉得是形式大于内容。这和吃多了大鱼大肉会腻味是一个道理。

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 —— 控制组件的运动方向marginTopmarginBottommarginLeftmarginRight —— 整形,表像素, 控制组件的边际空白大小--><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"]);elserect.x = int(animation.currentValue["value"]);t.scrollRect = rect;}}
1 楼 smithfox 2011-01-19   好文章, 现在直接用spark Animate的例子还真不多呀!!

热点排行