什么是好的效果。我的体会是那些模拟真实世界的物体运动,被现有物理学所支持的简洁效果才是历久常新,实用的好效果。这是由人脑本身的思维模式所决定的。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 —— 控制组件的运动方向
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;
}
}
分享到:
相关推荐
QML弹出窗口组件,灯箱效果、动画效果,可拖拽 核心思路:一个mask层,一个最顶层,都用rectangle,禁止事件穿透,动画效果 http://www.cnblogs.com/surfsky/p/3998391.html
用PopupWindow实现的一个组件附近弹出选项框的效果,欢迎下载,共同学习
TMsnPopup (MSN弹出效果组件) TMsnPopup (MSN弹出效果组件)
前言:对于Web开发人员,弹出框和提示框的使用肯定不会陌生,比如常见的表格新增和编辑功能,一般常见的主要有两种处理方式:行内...使用过JQuery UI应该知道,它里面有一个dialog的弹出框组件,功能也很丰富。与jQue
AMPopTip:一个实现效果非常精细的气泡弹出组件
AMPopTip:一个实现效果非常精细的气泡弹出组件.zip,一个动画弹出框弹出,非常适合微妙的用户界面提示和登入。
javascript弹出式登陆框,一个别人做的弹出式登陆框
左上角按钮 android:id="@+id/id_arcmenu1" android:layout_width="fill_parent" android:layout_height="fill_parent" zhy:position="left_top" zhy:radius="130dp" > android:layout_width="wrap_...
在基于 Vue 3、TypeScript 和 Vite 4 的开发环境中,博主成功开发了一个弹出层组件,该组件不仅支持设置动画时间参数,还具备动态插槽的强大功能。这样的组件设计和实现充分展现了博主对于前端开发技术的深刻理解和...
本文实例讲述了微信小程序使用modal组件弹出对话框功能。分享给大家供大家参考,具体如下: 1、效果展示 2、关键代码 ①、index.wxml 提示:{{tip}} <button type=default bindtap=showModal>点击我弹出...
第一部分只制作了常用的轮播及弹出层组件 demo里包含了比较详细的注释讲解参数,可直接复制到后台预览效果 文档由于制作比较快,仅作参考,考虑可能不详细 如果有问题可于PSD源文件自行修改 Ps:有时间可能会出...
RbCornerDialog.cs是一个C#右下角弹出框组件,有动态效果的,类似QQ右下角弹出新闻框,你只要将这个组件添加到你的项目当中,实例化后直接调用其Show()方法就行了,非常易用
由于我的更改密码弹出框是一个组件引用的,所以在一开始是隐藏的,这就需要在当前的页面上对弹出框组件设置v-show,但是在弹出框显示出来的时候,操作执行完后当前页面的更改按钮已经被弹出框覆盖了。所以只能在弹出...
今天给大家带来一个微信小程序的弹出是菜单效果,老规矩先上效果图。(录制的gif动画有点卡,实际真机或是模拟器上很顺畅) 先简单说下思路: 1、首先在屏幕的某个位置放几个悬浮按钮,放几个看你需要的功能 2、点击...
非常简单的checkbox按下前弹出是否确认对话框,该checkbox的效果是通过pushbutton改写的,可以通过调整图片调整checkbox的大小和样式。。
为页面内容添加一个小的覆盖层,就像iPad上的效果一样,为页面元素增加额外的信息。 插件依赖 弹出框依赖工具提示插件,因此需要先加载工具提示插件。 选择性加入的功能 出于性能方面的考虑,工具提示和弹框组件的...
弹出窗口框架是一个简洁、高效、美观、易用的多功能弹出窗口组件。代码简洁,程序运行效率高,窗口样式更改简便,支持所有主流浏览器:IE6+,Firefox2.0+,Chrome(谷歌浏览器),Opera9.5+,Safari3.0+等
使用ColorLayer 和 一个基类实现动态弹出框 和遮罩效果
弹出窗口,提示,web页面 WEB窗口右下角弹出窗口提示效果