`
ioryioryzhan
  • 浏览: 155444 次
  • 性别: 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中动画效果

    13. **TweenEffect**:这是大部分效果的基类,提供了动画的基础框架,子类可以通过继承和定制来创建自定义效果。 通过这些动画效果的组合和配置,开发者可以创造出复杂且富有表现力的用户界面交互。例如,可以使用 ...

    基于ARM架构服务器部署docker-compose

    基于arm64版本的docker-compose文件

    附件3-4:台区智能融合终端全性能试验增值税发票开具确认单.docx

    台区终端电科院送检文档

    埃夫特机器人Ethernet IP 通讯配置步骤

    埃夫特机器人Ethernet IP 通讯配置步骤

    rv320e机器人重型关节行星摆线减速传动装置研发.rar

    rv320e机器人重型关节行星摆线减速传动装置研发

    气缸驱动爬杆机器人的设计().zip

    气缸驱动爬杆机器人的设计().zip

    软件工程中期答辩1234567

    56tgyhujikolp[

    基于OpenCV的数字身份验证系统:人脸检测、训练与识别的Python实现

    内容概要:本文档提供了基于OpenCV的数字身份验证系统的Python代码示例,涵盖人脸检测、训练和识别三个主要功能模块。首先,通过调用OpenCV的CascadeClassifier加载预训练模型,实现人脸检测并采集多张人脸图像用于后续训练。接着,利用LBPH(局部二值模式直方图)算法对面部特征进行训练,生成训练数据集。最后,在实际应用中,系统能够实时捕获视频流,对比已有的人脸数据库完成身份验证。此外,还介绍了必要的环境配置如依赖库安装、文件路径设置以及摄像头兼容性的处理。 适合人群:对计算机视觉感兴趣的研发人员,尤其是希望深入了解OpenCV库及其在人脸识别领域的应用者。 使用场景及目标:适用于构建安全认证系统的企业或机构,旨在提高出入管理的安全性和效率。具体应用场景包括但不限于门禁控制系统、考勤打卡机等。 其他说明:文中提供的代码片段仅为基本框架,可根据实际需求调整参数优化性能。同时提醒开发者注意隐私保护法规,合法合规地收集和使用个人生物识别信息。

    Java并发编程面试题详解:123道经典题目解析与实战技巧

    内容概要:本文档详细介绍了Java并发编程的核心知识点,涵盖基础知识、并发理论、线程池、并发容器、并发队列及并发工具类等方面。主要内容包括但不限于:多线程应用场景及其优劣、线程与进程的区别、线程同步方法、线程池的工作原理及配置、常见并发容器的特点及使用场景、并发队列的分类及常用队列介绍、以及常用的并发工具类。文档旨在帮助开发者深入理解和掌握Java并发编程的关键技术和最佳实践。 适合人群:具备一定Java编程经验的研发人员,尤其是希望深入了解并发编程机制、提高多线程应用性能的中级及以上水平的Java开发者。 使用场景及目标:①帮助开发者理解并发编程的基本概念和技术细节;②指导开发者在实际项目中合理运用多线程和并发工具,提升应用程序的性能和可靠性;③为准备Java技术面试的候选人提供全面的知识参考。 其他说明:文档内容详尽,适合用作深度学习资料或面试复习指南。建议读者结合实际编码练习,逐步掌握并发编程技巧。文中提到的多种并发工具类和容器,均附有具体的应用场景和注意事项,有助于读者更好地应用于实际工作中。

    个人健康与健身追踪数据集,包含了日常步数统计、睡眠时长、活跃分钟数以及消耗的卡路里,适用于数据分析、机器学习

    这个数据集包含了日常步数统计、睡眠时长、活跃分钟数以及消耗的卡路里,是个人健康与健身追踪的一部分。 该数据集非常适合用于以下实践: 数据清洗:现实世界中的数据往往包含缺失值、异常值或不一致之处。例如,某些天的步数可能缺失,或者存在不切实际的数值(如10,000小时的睡眠或负数的卡路里消耗)。通过处理这些问题,可以学习如何清理和准备数据进行分析。 探索性分析(发现日常习惯中的模式):可以通过分析找出日常生活中的模式和趋势,比如一周中哪一天人们通常走得最多,或是睡眠时间与活跃程度之间的关系等。 构建可视化图表(步数趋势、睡眠与活动对比图):将数据转换成易于理解的图形形式,有助于更直观地看出数据的趋势和关联。例如,绘制步数随时间变化的趋势图,或是比较睡眠时间和活动量之间的关系图。 数据叙事(将个人风格的追踪转化为可操作的见解):通过讲述故事的方式,把从数据中得到的洞察变成具体的行动建议。例如,根据某人特定时间段内的活动水平和睡眠质量,提供改善健康状况的具体建议。

    《基于YOLOv8的港口船舶靠泊角度偏差预警系统》(包含源码、可视化界面、完整数据集、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    nginx 访问访问日志按天切割 shell脚本

    nginx

    《基于YOLOv8的核废料运输容器密封性检测系统》(包含源码、可视化界面、完整数据集、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    《基于YOLOv8的农业无人机播种深度监测系统》(包含源码、可视化界面、完整数据集、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    uniapp知识付费(流量主)demo

    模拟知识付费小程序,可流量主运营模式

    java高并发之分片上传

    什么是普通上传 调用接口一次性完成一个文件的上传。 普通上传2个缺点 文件无法续传,比如上传了一个比较大的文件,中间突然断掉了,需要重来 大文件上传太慢 解决方案 分片上传

    英二2010-2021阅读理解 Part A 题干单词(补).pdf

    英二2010-2021阅读理解 Part A 题干单词(补).pdf

    2023-04-06-项目笔记 - 第四百五十五阶段 - 4.4.2.453全局变量的作用域-453 -2025.04-01

    2023-04-06-项目笔记-第四百五十五阶段-课前小分享_小分享1.坚持提交gitee 小分享2.作业中提交代码 小分享3.写代码注意代码风格 4.3.1变量的使用 4.4变量的作用域与生命周期 4.4.1局部变量的作用域 4.4.2全局变量的作用域 4.4.2.1全局变量的作用域_1 4.4.2.453局变量的作用域_453- 2025-04-01

    友缘公司钢材管理平台微信小程序的设计与实现.zip

    微信小程序项目课程设计,包含LW+ppt

    GP300单缸液压圆锥破碎机CAD().zip

    GP300单缸液压圆锥破碎机CAD().zip

Global site tag (gtag.js) - Google Analytics