`
bigt
  • 浏览: 45579 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

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

阅读更多
什么是好的效果。我的体会是那些模拟真实世界的物体运动,被现有物理学所支持的简洁效果才是历久常新,实用的好效果。这是由人脑本身的思维模式所决定的。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;
	}
	
}
分享到:
评论
1 楼 smithfox 2011-01-19  
好文章, 现在直接用spark Animate的例子还真不多呀!!

相关推荐

    QML弹出窗口组件,灯箱效果、动画效果,可拖拽

    QML弹出窗口组件,灯箱效果、动画效果,可拖拽 核心思路:一个mask层,一个最顶层,都用rectangle,禁止事件穿透,动画效果 http://www.cnblogs.com/surfsky/p/3998391.html

    一个简单的弹出层代码

    在给定的资源包中,"一个简单的弹出层代码" 提供了一个实现这一功能的实例。这个压缩包包含了几个关键文件,让我们逐一解析它们。 首先,`demo.html` 是一个演示文件,它展示了弹出层如何工作以及如何被使用。在该...

    弹出窗口效果

    首先,jQuery 是一个轻量级的 JavaScript 库,它简化了 JavaScript 的语法,使开发者能更容易地处理DOM操作、事件处理、动画效果和AJAX交互。在创建弹出窗口时,jQuery 可以帮助我们轻松地控制窗口的显示与隐藏,...

    jQuery弹出层 可加载iframe 功能强大 简单易用

    在这个特定的案例中,标题和描述提到的“jQuery弹出层可加载iframe”指的是一个利用jQuery实现的弹出窗口,它能够嵌入一个iframe(内联框架)来展示外部网页或应用程序。 首先,我们需要理解jQuery是什么。jQuery是...

    自定义JavaScript弹出框组件

    1. 结构设计:一个基本的弹出框组件应包含标题区、内容区、按钮区等部分。内容区可以根据需要承载文本、图像、表单等多种元素。为了增加可扩展性,可以考虑采用模态(modal)设计,使得弹出框出现时,背景页面变为半...

    可自定义的底部弹出框

    在描述中提到的"仿分享的底部弹出框",其主要功能是模仿社交应用中常见的分享功能,当用户点击某个按钮后,一个底部弹出的视图会出现,显示可供分享到的不同平台或服务。这种设计使得用户能够方便地进行多选操作,而...

    仿腾讯弹出层效果代码

    "仿腾讯弹出层效果"是一个旨在模仿腾讯产品中弹出层样式的代码实现,它具有美观和实用的特点。这种效果能够提升用户体验,使用户在不离开当前页面的情况下,方便地查看或操作额外的内容。 首先,我们来详细解释弹出...

    TMsnPopup (MSN弹出效果组件)

    TMsnPopup是一款用于实现MSN风格弹出效果的组件,它在编程领域,特别是GUI(图形用户界面)设计中,提供了一种吸引用户注意力的方式。这种组件常见于Windows桌面应用程序,可以用于创建通知、提示信息或者广告等,...

    一个简单好用的弹出层

    标题中的“一个简单好用的弹出层”指的是在网页前端开发中常见的一种交互元素,通常称为模态框(Modal)或对话框。这种组件在用户界面设计中扮演着重要角色,它能在用户与主页面交互的过程中临时显示额外信息、进行...

    一个ReactJS灵活的弹出式组件支持动画

    "一个ReactJS灵活的弹出式组件支持动画"是一个专为创建模态框和弹出框设计的库,它允许开发者轻松地在应用程序中添加具有动画效果的弹出功能。此组件提供了高度的定制性,以满足不同场景下的需求。 首先,我们要...

    带动画效果jQuery+CSS3实现的弹出框弹出层效果

    本文将深入探讨如何使用jQuery和CSS3来创建一个带有动画效果的弹出框弹出层,以及其核心组件和实现原理。 首先,jQuery是一个广泛使用的JavaScript库,它简化了DOM操作、事件处理、动画效果以及Ajax交互。在本项目...

    js组件弹出框

    在Web开发中,弹出框常用于提示信息、获取用户输入或展示详情,因此js组件弹出框在前端开发中具有广泛的应用。 lhgdialog、dialog和zcms dialog是三个不同的JavaScript弹出框组件,它们各自具有独特的特性和使用...

    jquery弹出窗体效果

    例如,你可能有一个隐藏的div元素,当用户点击某个按钮时,通过jQuery选择该元素并调用`show()`方法使其可见,形成弹出效果。同时,使用`fadeOut()`和`fadeIn()`可以增加平滑的过渡动画,使用户体验更佳。 第二种...

    jQuery LayerModel弹出层插件拖动弹出层效果

    jQuery LayerModel是一款基于jQuery的弹出层插件,它提供了丰富的功能,包括创建各种类型的弹出窗口,如提示、信息、确认、加载等,并且支持弹出层的拖动效果。在网页交互设计中,弹出层是常用的一种增强用户体验的...

    两个层实现弹出效果两个层实现弹出效果两个层实现弹出效果

    在IT领域的前端开发中,利用两个层来实现弹出效果是一种常见的技术手段,尤其是在网页设计与交互中。本文将深入探讨这一技术的核心概念、实现原理以及具体的代码实践,旨在为前端开发者提供一个全面的理解框架。 ##...

    弹出层2,可以弹出多个层,并实现数据交互

    弹出层是在网页主内容之上显示的一个浮动窗口,它可以用来展示详细信息、提示、表单、图片或其他互动组件。其主要目的是在不中断用户对主要页面浏览的情况下,提供一个临时的交互空间,增加用户的沉浸感和操作便捷...

    一个Jsp弹出窗口

    总的来说,这个"一个Jsp弹出窗口"项目展示了一个结合了JSP后端处理能力和前端JavaScript交互的实例,通过自定义的弹出窗口组件实现了动态提示的功能。这涉及到HTML布局、CSS美化、JavaScript交互和JSP的服务器端逻辑...

    TIA博途中如何利用一个弹出画面同时控制多个相同类型的设备或参数(例如多台电机)?.docx

    在TIA博途中,通过一个弹出画面同时控制多个相同类型的设备或参数,例如多台电机,可以有效地简化HMI用户界面,减轻屏幕负载。以下是一个详细的步骤指南,以控制3台电机启停为例: 1. 首先,创建一个新的TIA博途...

    Android实现人人网点击“+”弹出效果

    "Android实现人人网点击“+”弹出效果"就是一个常见的应用场景,它通常指的是在界面上点击一个"+"图标后,弹出一个下拉菜单或者浮层,显示更多的功能选项。这种设计在社交应用、工具类应用中非常常见,可以有效地...

    javascript九种自定义弹出层效果

    1. **基础弹出层**:这是最简单的弹出层实现,通过创建一个CSS隐藏的元素,在需要时用JavaScript显示。可以使用`document.getElementById()`获取元素,然后改变`style.display`属性来控制元素的可见性。 2. **模态...

Global site tag (gtag.js) - Google Analytics