漂亮的Flex流程状态闪烁

因项目中需要表示一个业务流程中的3个阶段的状态,想到采用链式的表现方法,每个阶段的状态用一种颜色表示,当流程执行到该阶段后,对应的状态闪烁高亮。

最初的想法是直接继承自Ellipse,直接重写draw 方法,恩 没想到绘制出来的效果都偏离了中心位置。

最后发现是drawX、drawY忘记加上绘制圆圈的半径了~~导致直接基于0,0点绘制,图像整体向左上方偏移。


但是我想要效果更炫一点,给状态点增加点击事件、或者鼠标悬停事件,例如,点击状态改变颜色、或者悬停时提示之类的。

结果,因为Ellipse本身不是交互对象,未继承鼠标相关的事件,然后本人各种给自定义组件加自定义事件,都无法生效。最后,无奈之下将继承的父类改为Graphic,然后遇到了一个新问题,除了第一个绘制出来的图形位置正常外,其他阶段的状态无法正常显示。根据显示重绘区域,最终发现,除第一个组件中的graphics绘制正常外,其他阶段调用组件绘制均变成基于屏幕(舞台)左上角绘制。而本身自定义的State控件显示大小是有设定的,所以导致绘制的对象无法显示。详见下图:


各种debug调试,查看父容器的坐标,绘图坐标,均未发现异常,都是相对坐标啊,但是各种无法生效,被逼之下,又在该自定义控件内部定义了一个私有的group,作为绘图的舞台。

        _content=new Group;
        ......
        var cx:Number,cy:Number;
	cx=radius;
	cy=radius;
	_content.graphics.beginFill(stateColor,0.8);
	_content.graphics.drawCircle(cx,cy,radius);
	_content.graphics.endFill();

这回终于成了!

绘制时调用内置group的graphics绘制,相对坐标正常,最终结果如下:


说明:实现以下功能

1、预定义了4种状态,分别是红#FF7F6B、黄#FFB66B、蓝#53A6BE、绿#58D27D(色表参照:http://paletton.com/#uid=72V0u0kiAFk8FVce5NUmrwOqVte),传入state(0、1、2、3)可以设定不同的状态;

2、通过changeState(_state:int) 方法可以调用批量更改状态、闪烁变化相关颜色赋值,然后重绘状态;

3、通过glowTween(color:uint=0x7CC3D8,maxBlur:int=10, duration:int=100)方法可以添加闪烁效果,cancelGlowTween()方法可以主动取消闪烁效果。


最后,上代码!

package com.css.jlry.suportCom
{
	
	import flash.events.Event;
	import flash.filters.GlowFilter;
	import flash.utils.clearInterval;
	import flash.utils.setInterval;
	
	import spark.components.Group;
	import spark.primitives.Graphic;
	

	/**
	 * normal:#53A6BE\#AFE0EE\#7CC3D8
	 * state1:#FFB66B\#FFDDBA\#FFC78F
	 * state2:#FF7F6B\#FFC3BA\#FF9E8F
	 * state3:#58D27D\#B1F3C5\#80E49E
	 */
	public class StateSymbol extends Graphic
	{
		
		public var stateColor:uint=0x53A6BE;
		public var extendColor:uint=0xAFE0EE;
		public var radius:Number=10;
		public var extendRadius:Number=12;
		public var state:int=0;
		
		
		private var _toggle:Boolean;
		private var _blur:Number=2;
		private var _glowColor:uint=0x7CC3D8;
		private var _maxBlur:int=10;
		private var _duration:int=100;
		private var _interval:int;
		
		private var _content:Group;
		
		public function StateSymbol()
		{
			super();
		}
		override protected function createChildren():void
		{
			super.createChildren();
			changeState(state);
		}
		
		override protected function measure():void{
			super.measure();
			var l:Number=radius*2;
			measuredMinHeight=measuredMinWidth=l;
			measuredHeight=l;
			measuredWidth=l;
		}
		
		override protected function updateDisplayList(unscaledWidth:Number, 
													  unscaledHeight:Number):void{
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			var realHeight:Number,realWidth:Number;
			realHeight=this.getExplicitOrMeasuredHeight();
			realWidth=this.getExplicitOrMeasuredWidth();
			this.setActualSize(realWidth,realHeight);
		}
		
		public function changeState(_state:int):void{
			state=_state;
			switch(_state){
				case 0:{  //#53A6BE\#AFE0EE\#7CC3D8
					stateColor=0x53A6BE;
					extendColor=0xAFE0EE;
					_glowColor=0x7CC3D8;
					break;
				}
				case 1:{  //#FFB66B\#FFDDBA\#FFC78F
					stateColor=0xFFB66B;
					extendColor=0xFFDDBA;
					_glowColor=0xFFC78F;
					break;
				}
				case 2:{  //#FF7F6B\#FFC3BA\#FF9E8F
					stateColor=0xFF7F6B;
					extendColor=0xFFC3BA;
					_glowColor=0xFF9E8F;
					break;
				}
				case 3:{  //#58D27D\#B1F3C5\#80E49E
					stateColor=0x58D27D;
					extendColor=0xB1F3C5;
					_glowColor=0x80E49E;
					break;
				}
			}
			drawState();
		}
		
		private function drawState():void{
			if(_content){
				this.removeElement(_content);
			}
			_content=new Group;
			var cx:Number,cy:Number;
			cx=radius;
			cy=radius;
			_content.graphics.beginFill(stateColor,0.8);
			_content.graphics.drawCircle(cx,cy,radius);
			_content.graphics.endFill();
			var ringR:Number=radius+2
			if(extendRadius-ringR<=255){
				_content.graphics.lineStyle(extendRadius-ringR,extendColor);
				_content.graphics.drawCircle(cx,cy,(ringR+extendRadius)/2);
			}
			this.addElement(_content);
		}
		
		public function glowTween(color:uint=0x7CC3D8,maxBlur:int=10, duration:int=100):void{
			cancelGlowTween();
			if(_glowColor<0){
				_glowColor=color>=0?color:stateColor;
			}
			_maxBlur=maxBlur;
			_duration=duration;
			_interval=setInterval(dispatchEnterFrame,_duration);
			this.addEventListener(Event.ENTER_FRAME, blinkHandler, false, 0, true);
		}
		
		private function dispatchEnterFrame():void{
			this.dispatchEvent(new Event(Event.ENTER_FRAME,true));
		}
		
		public function cancelGlowTween():void{
			clearInterval(_interval);
			this.filters=[];
			this.removeEventListener(Event.ENTER_FRAME, blinkHandler);
		}
		
		private function blinkHandler(evt:Event):void
		{
			if (_blur >= _maxBlur)
				_toggle=false;
			else if (_blur <= 2)
				_toggle=true;
			_toggle ? _blur++ : _blur--;
			var glow:GlowFilter=new GlowFilter(_glowColor, 1, _blur, _blur, 2, 2);
			this.filters=[glow];
		}
	}
}


在mxml里面调用方式如下:

<s:BorderContainer height="80" width="100%" 
							   top="40" borderWeight="1" 
							   borderColor="0x9E92F1" borderAlpha="0.8"
							   backgroundAlpha="0" borderStyle="inset"
							   verticalCenter="0" horizontalCenter="0">
				<s:layout>
					<s:HorizontalLayout gap="5"
						verticalAlign="middle" horizontalAlign="center" />
				</s:layout>
			<!-- -->	<suportCom:StateSymbol id="startSymbol" stateColor="0x53A6BE"
									   extendColor="0xAFE0EE" visible="true"
									   width="20" height="20" /> 
				<s:Line id="p1Line" width="40" xFrom="0" xTo="0" >
					<s:stroke>
						<s:SolidColorStroke color="0x333333" weight="2" caps="round"/>
					</s:stroke>
				</s:Line>
				<suportCom:StateSymbol id="middleSymbol" stateColor="0xFFB66B"
									   extendColor="0xFFDDBA" visible="true"
									   width="20" height="20" 
									   click="middleSymbol_clickHandler(event)" />
				<s:Line id="p2Line" width="40" xFrom="0" xTo="0" >
					<s:stroke>
						<s:SolidColorStroke color="0x333333" weight="2" caps="round"/>
					</s:stroke>
				</s:Line>
				<suportCom:StateSymbol id="endSymbol" stateColor="0x58D27D"
									   extendColor="0xB1F3C5" visible="true"
									   width="20" height="20" click="endSymbol_symbolClickHandler(event)"/>
			</s:BorderContainer>

效果:

点击后



考虑追加个toggle方法,点击后 改变是否闪烁,嘿嘿!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值