漂亮的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,radius); _content.graphics.endFill(); var ringR:Number=radius+2 if(extendRadius-ringR<=255){ _content.graphics.lineStyle(extendRadius-ringR,extendColor); _content.graphics.drawCircle(cx,(ringR+extendRadius)/2); } this.addElement(_content); } public function glowTween(color:uint=0x7CC3D8,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,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,2,2); this.filters=[glow]; } } } <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方法,点击后 改变是否闪烁,嘿嘿! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |