`
ioryioryzhan
  • 浏览: 154858 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

flex 自定义TweenEffect方法

阅读更多

rh      发现很久没有写BLOG了,罪过罪过,先忙着找工作,工作搞定了,又忙着毕业论文,现在终于有时间来做做Flex了,手生了些,没有项目,完全自娱自乐型。

 

      TweenEffect,补间效果~是一种渐变的类型,像Glow,Move等都是TweenEffect的子类,自已做一个TweenEffect,应该在很多场合用得到。

 

首先选取一个TweenEffect来研究一下,就Glow吧,找到它的原代码,如下(去掉了注释,加上自己的注释 ):

package mx.effects
{

import mx.effects.effectClasses.GlowInstance;
import mx.styles.StyleManager;

public class Glow extends TweenEffect
{
    include "../core/Version.as";
	public function Glow(target:Object = null)
	{
		super(target);
		instanceClass = GlowInstance;
	}
   /*添加一些效果参数,用Inspectable标签声明,这样可以在MXML上设置这些属性*/
	[Inspectable(category="General", defaultValue="NaN")]
	public var alphaFrom:Number;
	[Inspectable(category="General", defaultValue="NaN")]
	public var alphaTo:Number;
	[Inspectable(category="General", defaultValue="NaN")]
	public var blurXFrom:Number;
	[Inspectable(category="General", defaultValue="NaN")]
	public var blurXTo:Number;
	[Inspectable(category="General", defaultValue="NaN")]
	public var blurYFrom:Number;
	[Inspectable(category="General", defaultValue="NaN")]
	public var blurYTo:Number;
	[Inspectable(category="General", format="Color", defaultValue="0xFFFFFFFF")]
	public var color:uint = StyleManager.NOT_A_COLOR;
	[Inspectable(category="General", defaultValue="false")]
	public var inner:Boolean;
	[Inspectable(defaultValue="false")]
	public var knockout:Boolean;
	[Inspectable(category="General", defaultValue="2")]
	public var strength:Number;

	override public function getAffectedProperties():Array /* of String */
	{
		return AFFECTED_PROPERTIES;
	}
	override protected function initInstance(instance:IEffectInstance):void
	{
		super.initInstance(instance);
		//创建效果实例
        var glowInstance:GlowInstance = GlowInstance(instance);
        //将参数传递给实例
		glowInstance.alphaFrom = alphaFrom;
		glowInstance.alphaTo = alphaTo;
		glowInstance.blurXFrom = blurXFrom;
		glowInstance.blurXTo = blurXTo;
		glowInstance.blurYFrom = blurYFrom;
		glowInstance.blurYTo = blurYTo;
		glowInstance.color = color;
		glowInstance.inner = inner;
		glowInstance.knockout = knockout;
		glowInstance.strength = strength;
	}
}

}

 

 真的是so easy,Glow ms就是用来创建实例,外加传递参数的。在设计模式中叫工厂,看来关键还是有GlowInstance类里面,再找到GlowInstance类的代码。

package mx.effects.effectClasses
{
import flash.events.Event;
import flash.filters.GlowFilter;
import mx.core.Application;
import mx.core.mx_internal;
import mx.styles.StyleManager;
public class GlowInstance extends TweenEffectInstance
{
    include "../../core/Version.as";

	public function GlowInstance(target:Object)
	{
		super(target);
	}

	public var alphaFrom:Number;
	public var alphaTo:Number;
	public var blurXFrom:Number;
	public var blurXTo:Number;
	public var blurYFrom:Number;
	public var blurYTo:Number;
	public var color:uint = StyleManager.NOT_A_COLOR;
	public var inner:Boolean;
	public var knockout:Boolean;
	public var strength:Number;

	override public function initEffect(event:Event):void
	{
		super.initEffect(event);
	}

	override public function play():void
	{
		super.play();
		if (isNaN(alphaFrom))
			alphaFrom = 1.0;
		if (isNaN(alphaTo))
			alphaTo = 0;
		if (isNaN(blurXFrom))
			blurXFrom = 5;
		if (isNaN(blurXTo))
			blurXTo = 0;
		if (isNaN(blurYFrom))
			blurYFrom = 5;
		if (isNaN(blurYTo))
			blurYTo = 0;
		if (color == StyleManager.NOT_A_COLOR)
			color = Application.application.getStyle("themeColor");
		if (isNaN(strength))
			strength = 2;
		tween = createTween(
			this, [ color, alphaFrom, blurXFrom, blurYFrom ],
			[ color, alphaTo, blurXTo, blurYTo ], duration);

	}
	override public function onTweenUpdate(value:Object):void
	{
		setGlowFilter(value[0], value[1], value[2], value[3]);
	}
	override public function onTweenEnd(value:Object):void
	{
		setGlowFilter(value[0], value[1], value[2], value[3]);
		super.onTweenEnd(value);	
	}
	
	private function setGlowFilter (color:uint, alpha:Number,
								   blurX:Number, blurY:Number):void
	{
		var filters:Array = target.filters;
		var n:int = filters.length;
		for (var i:int = 0; i < n; i++)
		{
			if (filters[i] is GlowFilter)
				filters.splice(i, 1);
		}
		if (blurX || blurY || alpha)
			filters.push(new GlowFilter(color, alpha, blurX, blurY,
						strength, 1, inner, knockout));
		target.filters = filters;
	}
}

}

 

 

稍微有点复杂了,仔细看看,也还好,开始定义一些参数,就里面参数与Glow中定义是一致的,然后重写了一些关键函数。看看这些函数都干嘛的。

 

play():动画开始播放,首先检查参数,如果没有值,就加上默认值。最后一句是关键,

tween = createTween(
			this, [ color, alphaFrom, blurXFrom, blurYFrom ],
			[ color, alphaTo, blurXTo, blurYTo ], duration);

 

它创建了一个Tween,参数中两个数组很有意思,是一一对应的,一个是From,另一个就是To,这个Tween动画就是这样产生的,数组中的参数,从From淅变到To,中间会停地派发TweenUpdate事件,在类中对这一事件进行处理,实现淅变的效果。

 

TweenUpdate事件便是在onTweenUpdate()函数中得到处理,参数value是From与To之间的中间值,我们根据这个值来做动画,Glow调用的是setGlowFilter()函数来实现。

 

在Tween结束时,即达到To了,就会派发TweenEnd事件,所以也要重写onTweenEnd()函数。

 

好了,都研究完了,ms可以动手写个自己的TweenEffect了,写了个,先看效果,

 

 

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="300" height="300" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"> <param name="src" value="http://www.mjbox.com/r/io/ioryioryzhan/TestRound.swf"> <embed type="application/x-shockwave-flash" width="300" height="300" src="http://www.mjbox.com/r/io/ioryioryzhan/TestRound.swf"></embed></object>

javaeye变垃圾了吗,连个flash贴进去总是出问题,(http://www.mjbox.com/r/io/ioryioryzhan/TestRound.swf ) 这个是链接

点start按扭,可以看到,一个框框围着控件,一个球球在沿着框框移动,好像不怎么美观,将就一点。它是完成依照Glow编写的,叫Round,Round代码如下:

package effects
{
	import mx.effects.IEffectInstance;
	import mx.effects.TweenEffect;

	public class Round extends TweenEffect
	{
		[Inspectable(category="General", defaultValue="NaN")]
		public var lineColor:uint;
		[Inspectable(category="General", defaultValue="NaN")]
		public var lineWeight:Number;
		[Inspectable(category="General", defaultValue="NaN")]
		public var circleColor:uint;
		[Inspectable(category="General", defaultValue="NaN")]
		public var circleRadio:Number;
		[Inspectable(category="General", defaultValue="NaN")]
		public var distance:Number;
		
		
		public function Round(target:Object=null)
		{
			super(target);
			this.instanceClass = RoundInstance;
		}
		override protected function initInstance(instance:IEffectInstance):void{
			super.initInstance(instance);
			var roundInstance:RoundInstance = RoundInstance(instance);
			roundInstance.lineColor = lineColor;
			roundInstance.lineWeight = lineWeight;
			roundInstance.circleColor = circleColor;
			roundInstance.circleRadio = circleRadio;
			roundInstance.distance = distance;
		}
		
	}
}

 

 不同点在于instanceClass不同了,还有就是参数不同。

没有注释,稍微讲讲这些参数,主要设置线的宽度,颜色,小圆圈的半径,颜色,还有框框与控件的距离。

 

下面是RoundInstance的代码:

package effects
{
	import flash.events.Event;
	
	import mx.core.UIComponent;
	import mx.core.UIComponentGlobals;
	import mx.effects.effectClasses.TweenEffectInstance;
	import mx.core.mx_internal;
	use namespace mx_internal;
	
	public class RoundInstance extends TweenEffectInstance
	{
		public var lineColor:uint;
		public var lineWeight:Number;
		public var circleColor:uint;
		public var circleRadio:Number;
		public var distance:Number;
		
		public function RoundInstance(target:Object)
		{
			super(target);
		}
		override public function initEffect(event:Event):void{
			super.initEffect(event);
			
		}
		override public function play():void{
			if (isNaN(lineColor))
				lineColor = 0xff0000;
			if (isNaN(circleColor))
				circleColor = 0xff0000;
			if (isNaN(distance))
				distance = 3;
			if (isNaN(lineWeight))
				lineWeight = 1;
			if (isNaN(circleRadio))
				circleRadio = 3;
			//保证参数合理性
			if(distance<=0){
				distance = 3;
			}	
			if(lineWeight > 2 * distance){
				lineWeight = 2 * distance;
			}
			if(circleRadio > distance){
				circleRadio = distance;
			}
			
			var targetUI:UIComponent = target as UIComponent;
			var w:Number = targetUI.width;
			var h:Number = targetUI.height;
			//创建Tween
			tween = createTween(this,[0],[2*(w+2*distance)+2*(h+2*distance)],duration);
		}
		override public function onTweenUpdate(value:Object):void{
			draw(value[0]);
		}
		override public function onTweenEnd(value:Object):void{
			var targetUI:UIComponent = target as UIComponent;
			targetUI.graphics.clear();
                        super.onTweenEnd(value);
		}
		
		private function draw(d:Number):void{
			var targetUI:UIComponent = target as UIComponent;
			targetUI.graphics.clear();
			
			targetUI.graphics.lineStyle(lineWeight,lineColor);
			targetUI.graphics.moveTo(-distance,-distance);
			targetUI.graphics.lineTo(-distance,targetUI.height+distance);
			targetUI.graphics.lineTo(targetUI.width + distance,targetUI.height+distance);
			targetUI.graphics.lineTo(targetUI.width + distance,-distance);
			
			var x:Number;
			var y:Number;
			var h:Number = targetUI.height + 2*distance;
			var w:Number = targetUI.width  + 2*distance;
			if(d<h){
				x = -distance;
				y = d;
			}else if(d>=h&&d<(w+h)){
				x = d - h;
				y = h - distance;
			}else if(d>=(w+h)&&d<(w+2*h)){
				x = w - distance;
				y = w + 2* h - d;
			}else{
				x = 2*w + 2* h - d;
				y = - distance;
			}
			
			targetUI.graphics.beginFill(circleColor);
			targetUI.graphics.drawCircle(x,y,circleRadio);
			targetUI.graphics.endFill();
		}
	}
}

 

看看Tween的创建

tween = createTween(this,[0],[2*(w+2*distance)+2*(h+2*distance)],duration);

从0开始,一直到2*(w+2*distance)+2*(h+2*distance),进行淅变,这个长表达式就是框框的周长,

 

draw函数,便是以中间值,计算当前球球的位置,进行绘制。

 

主程序,很简单,三个按扭,

 

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
 creationComplete="init()" backgroundColor="0xffffff" 
 xmlns:myeffect="effects.*" width="300" height="300">
	<mx:Script>
		<![CDATA[
			import mx.effects.Effect;
			import mx.events.EffectEvent;
			import mx.effects.Glow;
			import effects.Round;
			internal function init():void{
				
			}
			internal function onClickBtn2(e:MouseEvent):void{
				round1.play();
			}
			internal function onClickBtn3(e:MouseEvent):void{
				round1.end();
			}
		]]>
	</mx:Script>
	<myeffect:Round id="round1" target="{btn}" lineColor="0xff0000" lineWeight="1" 
		circleColor="0x0000ff" circleRadio="3" distance="10" duration="2000"/>
	<mx:Button x="50" y="50" width="90" height="50" id="btn"  label="Button"/>
	<mx:Button x="50" y="200" width="90" height="50" id="btn2" label="start"click="onClickBtn2(event)"/>
	<mx:Button x="150" y="200" width="90" height="50" id="btn3" label="end" click="onClickBtn3(event)"/>
</mx:Application>

 

 

点击调试,ft,出问题了,框框也有,球也有,也转的挺好,就是转完后不消失,我记得在onTweenEnd()中已经将画布clear()了,看来是super.onTweenEnd();有问题,点进去看看,果然是它,

/*in Class TweenEffectInstance*/

public function onTweenEnd(value:Object):void 
	{
		onTweenUpdate(value);
		tween = null;
		if (mx_internal::needToLayout)
			UIComponentGlobals.layoutManager.validateNow();

		finishRepeat();
	}

 

它在里面最后还是调用了一次onTweenUpdate(),所以又将框框球球画了上去,会消失才怪,只好,将下面四行代码移到RoundInstance类的onTweenUpdate()里去,修改代码:

 

/*in Class RoundInstance*/

override public function onTweenEnd(value:Object):void{
	var targetUI:UIComponent = target as UIComponent;
	targetUI.graphics.clear();
	    //下面四行代码,是从父类中移过来的
	tween = null;
	if (mx_internal::needToLayout)
		UIComponentGlobals.layoutManager.validateNow();
	finishRepeat();

}

 

现在开以了,点击运行,就是上面flash所展示的程序了。

 

欢迎批评指教~~

 

另外求教:

RepeatCount是如何发挥作用的,相关代码在哪 ?

分享到:
评论
2 楼 yuanyang0710 2009-10-16  
不错,牛!
1 楼 yhustc 2009-08-16  

友情链接一下
关于自定义effect的实现,我引用了你的链接。我的文章里分析了repeatCount相关的内容 
http://www.yhustc.com/flex_effect_repeatCount.html

相关推荐

    Flex 自定义组件ImageViewer

    在Flex中,自定义组件是开发者根据项目需求创建的特殊UI元素,可以扩展和定制标准的MX或Spark组件。本示例着重于一个名为“ImageViewer”的自定义组件,这通常是一个用于展示图像并可能包含缩放、平移等交互功能的...

    flex 自定义组件

    在Flex中,自定义组件通常是通过继承已有的基类,如UIComponent或Button,然后添加自己的属性、方法和样式来实现的。这样做的好处在于,我们可以创建出符合设计规范、功能齐全且可重用的组件,提高代码复用率和开发...

    Flex 自定义ToolTip

    ### Flex自定义ToolTip详解 在Flex开发中,`ToolTip`是一种非常实用的界面元素,用于在用户悬停或聚焦某个控件时显示额外的信息。默认情况下,Flex提供了基本的`ToolTip`功能,但有时为了满足特定的设计需求或者...

    flex自定义组件事件DEMO

    在Flex编程中,自定义组件是提升应用可扩展性和复用性的重要手段。这个"flex自定义组件事件DEMO"提供了关于如何创建和管理自定义组件事件的实际示例。下面我们将详细探讨Flex自定义组件、事件处理以及如何通过示例...

    flex 自定义控件、事件

    这个主题聚焦于“flex自定义控件与事件”,这是一个关键的开发概念,特别是对于那些希望深入理解Flex架构和提升应用用户体验的开发者来说。 自定义控件在Flex开发中扮演着重要角色,它们允许开发者根据项目需求创建...

    flex自定义树形结构

    本篇文章将深入探讨如何在Flex环境中自定义实现一个具备展开、收缩功能的多级目录树形结构。 首先,让我们理解`Flex`布局。Flex布局,全称为Flexible Box,是一种用于容器中元素的布局模型,旨在提供更好的灵活性,...

    Flex自定义加载条(小起)

    在本文中,我们将深入探讨如何在Flex环境中自定义加载条,即进度条组件。Flex是一种基于ActionScript 3.0的开源框架,用于构建富互联网应用程序(RIA)。它提供了丰富的UI组件库,其中包括标准的进度条组件,但有时...

    各种Flex自定义组件

    在Flex中,自定义组件是开发人员为了满足特定需求而创建的特殊用户界面元素。这些组件可以扩展标准的Flex组件库,或者从头开始构建,以提供独特的功能和视觉表现。 在标题“各种Flex自定义组件”中,我们可以推断这...

    Flex 自定义 时间 日历 控件

    Flex 自定义 时间 日历 控件

    flex 自定义进度条

    标题提到的"flex 自定义进度条",指的是利用Flex布局技术来设计一个可定制的进度条组件。Flex布局,全称为Flexible Box布局,是一种在CSS3中引入的布局模型,旨在提供更灵活的盒状模型布局方式,尤其适合在不同屏幕...

    flex自定义组件介绍

    标题中的“flex自定义组件介绍”指的是在Adobe Flex框架中创建和使用自定义组件的过程。Flex是一个基于ActionScript和MXML的开源框架,用于构建富互联网应用程序(RIA)。自定义组件允许开发者根据特定需求扩展Flex...

    flex 高级自定义组件

    总的来说,理解并熟练运用这些方法是开发Flex高级自定义组件的关键。通过重写这些方法,开发者可以精确控制组件的外观、行为、布局和样式,从而创建出功能强大且具有独特设计的组件,满足各种复杂的交互需求。在实际...

    FLEX自定义等待图标资源

    自定义等待图标资源是FLEX开发中的一个重要组成部分,因为默认的等待图标可能无法满足所有设计需求。在这个压缩包中,提供了18个SWF(Shockwave Flash)资源和19个GIF(Graphics Interchange Format)资源,这些都是...

    Flex自定义编辑项目

    Flex自定义编辑项目是一种基于Adobe Flex技术的开发工具,它为用户提供了一种类似于Flash IDE的交互体验。这个项目的核心特点是其高度的可定制性,允许开发者进行多种视觉元素的编辑操作,如拖拽、放大、缩小、添加...

    Flex自定义组件和事件

    在Flex中,自定义组件和事件的使用对于创建功能丰富的用户界面至关重要。下面我们将详细探讨这两个主题。 ### 一、Flex自定义组件 #### 1. 创建自定义组件的原因 在Flex应用中,有时标准组件库提供的组件无法满足...

    Flex 自定义公共包

    Flex 自定义公共包,可以在项目里直接使用

    flex自定义文本编辑器

    在Flex开发中,创建自定义组件是提升应用用户体验和功能扩展性的重要手段。"flex自定义文本编辑器"是一个这样的示例,它展示了如何利用Flex4框架构建一个具备特定功能的文本编辑工具,同时集成了自定义的拾色器功能...

    flex自定义创建css样式

    本篇文章将深入探讨如何在Flex布局中自定义创建CSS样式,以满足多样化的设计需求。 首先,我们需要理解Flex布局的基本概念。在Flex布局中,容器被称为“flex容器”,其内部的子元素称为“flex项目”。通过设置容器...

    Flex自定义罗盘全副显示范围

    本话题聚焦于如何在Flex环境下自定义罗盘的全副显示范围,这是一种用于增强地图导航体验的技术。下面将详细阐述这个主题。 首先,罗盘在GIS应用中起到指引方向的作用,帮助用户了解地图的朝向。在SuperMap iClient ...

    flex 自定义加载进度框

    在“flex自定义加载进度条”的场景中,开发者可能想要替换Flex默认的Application预加载器,以提供更个性化的用户体验。自定义预加载器可以让开发者自由设计加载界面的外观和交互,例如改变颜色、形状或动画效果,...

Global site tag (gtag.js) - Google Analytics