플래시 가로 슬라이더바
개발이유
플래시에서 제공하는 슬라이더 컴포넌트는 너무 플래시스럽지 않아 자체적으로 제작하여 사용하였습니다.
개발내용
- 슬라이더는 이미지를 사용하지 않고
Rectangle
객체를 이용하여 처리한다. - 슬라이더의 값이 변경되면 이벤트를 발생한다.
- 슬라이더의 단계를 입력하여 단계별로 이벤트를 발생시킨다.
결과물
소스
[HorizontalSlider.as]
package { import flash.geom.Rectangle; import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.Event; import flash.display.GradientType; import flash.geom.Matrix; import flash.display.SpreadMethod; public class HorizontalSlider extends Sprite { public static const SLIDER_CHANGE:String = "sliderChange"; var sliderBackground:Sprite; var sliderKnob:Sprite; var sliderKnobWidth:Number = 25; var sliderKnobHeight:Number = 40; var sliderBackgroundWidth:Number; var sliderBackgroundHeight:Number; var prevX:Number; var boundaries:Rectangle; var stepWidth:Number = 40; /** * 슬라이더 초기 좌표를 저장한다. StepIndex에 따라 슬라이더를 가운데에서 좌, 우로 이동한다. */ var sliderKnobCenterPositionX:Number = 0; protected var _isPressed:Boolean; /** * 슬라이더 바를 생성하도록 한다. 슬라이더는 Rectangle Object 두개를 이용하도록 처리한다. * Background에 생성되는 Rectangle도 MOUSE_CLICK 이벤트를 수신하여 슬라이더 버튼을 이동시킨다. * * @param sliderWidth 슬라이더의 너비을 설정한다. * @param sliderHeight 슬라이더의 높이를 설정한다. * @param stepCount 슬라이더 버튼을 Index의 위치에 맞게 이동시킨다. * 슬라이더 이동 범위 (sliderWidth / stepCount) 룰을 따른다. * */ public function HorizontalSlider(sliderWidth:Number, sliderHeight:Number, stepCount:Number) { _isPressed = false; this.sliderBackgroundWidth = sliderWidth; this.sliderBackgroundHeight = sliderHeight; this.sliderKnobWidth = Math.round(sliderBackgroundWidth / 15); this.sliderKnobHeight = Math.round(sliderHeight + 20); boundaries = new Rectangle(0, -10, sliderWidth - this.sliderKnobWidth, 0); this.stepWidth = int(sliderWidth / stepCount); drawSliderBackground(); drawSliderKnob(); bindSliderEvents(); } private function bindSliderEvents() : void { this.sliderKnob.addEventListener(MouseEvent.MOUSE_DOWN, onSliderKnobMouseDownHandler); this.sliderKnob.addEventListener(MouseEvent.MOUSE_UP, onSliderKnobMouseUpHandler); this.sliderBackground.addEventListener(MouseEvent.MOUSE_UP, onSliderBackgroundMouseUpHandler); } private function drawSliderBackground() : void { sliderBackground = new Sprite(); sliderBackground.graphics.lineStyle(2, 0xF298A2); sliderBackground.graphics.beginFill(0xFFFFFF); sliderBackground.graphics.drawRoundRect(0, 0, this.sliderBackgroundWidth, this.sliderBackgroundHeight, 5); sliderBackground.graphics.endFill(); sliderBackground.width = this.sliderBackgroundWidth; sliderBackground.height = this.sliderBackgroundHeight; trace(sliderBackground.width); trace(sliderBackground.height); this.addChild(sliderBackground); sliderBackground.x = 0; sliderBackground.y = 0; } private function drawSliderKnob() : void { this.sliderKnob = new Sprite(); this.addChild(sliderKnob); this.sliderKnob.graphics.beginFill(0xE53F00); this.sliderKnob.graphics.drawRoundRect(0, 0, sliderKnobWidth, sliderKnobHeight, 5); this.sliderKnob.graphics.endFill(); sliderKnob.x = (sliderBackground.width - sliderKnob.width) / 2; sliderKnob.y = sliderBackground.y - 10; // // 중간값을 저장하고 슬라이더 버튼을 이동시킨다. // sliderKnobCenterPositionX = sliderKnob.x; } private function onSliderKnobMouseDownHandler(e:MouseEvent) : void { this.sliderKnob.startDrag(false, boundaries); stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUpHandler); stage.addEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMoveHandler); this.prevX = this.sliderKnob.x; _isPressed = true; this.sliderBackground.removeEventListener(MouseEvent.MOUSE_UP, onSliderBackgroundMouseUpHandler); } private function onStageMouseMoveHandler(e:MouseEvent) : void { var currentPositionX = this.sliderKnob.x; if (_isPressed) { if (Math.abs(currentPositionX - prevX) > 0) { prevX = currentPositionX; // dispatchEvent(new Event(HorizontalSlider.SLIDER_CHANGE)); e.updateAfterEvent(); } } } private function onStageMouseUpHandler(e:MouseEvent) : void { this.sliderKnob.stopDrag(); stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUpHandler); stage.removeEventListener(MouseEvent.MOUSE_DOWN, onStageMouseMoveHandler); _isPressed = false; this.sliderBackground.addEventListener(MouseEvent.MOUSE_UP, onSliderBackgroundMouseUpHandler); this.calculatePositionX(sliderKnob.x); } private function onSliderKnobMouseUpHandler(e:MouseEvent) : void { this.sliderKnob.stopDrag(); stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUpHandler); stage.removeEventListener(MouseEvent.MOUSE_DOWN, onStageMouseMoveHandler); _isPressed = false; this.sliderBackground.addEventListener(MouseEvent.MOUSE_UP, onSliderBackgroundMouseUpHandler); this.calculatePositionX(sliderKnob.x); } private function onSliderBackgroundMouseUpHandler(e:MouseEvent) : void { var target:Sprite = e.target as Sprite; sliderKnob.x = e.localX - (this.sliderKnob.width / 2); this.calculatePositionX(sliderKnob.x); } private function calculatePositionX(x:Number) : void { var stepIndex:int = int(sliderKnob.x / this.stepWidth) + 1; var offsetCount:Number = stepIndex - (int(int(this.sliderBackgroundWidth / this.stepWidth) / 2)+1); this.sliderKnob.x = this.sliderKnobCenterPositionX + (offsetCount * this.stepWidth); var param:Object = { "index" : stepIndex }; this.dispatchEvent(new HorizontalSliderEvent(HorizontalSliderEvent.HorizontalSliderEvent, param)); } } }
[HorizontalSliderEvent.as]
package { import flash.events.Event; /** * 슬라이더값 변경시 발생되는 이벤트 * * <사용법> * * // * // Dispatch Event * // * var param:Object = { * "index" : currentIndex * }; * this.dispatchEvent(new HorizontalSliderEvent(HorizontalSliderEvent.HorizontalSliderEvent, param)); * */ public class HorizontalSliderEvent extends Event { public static const HorizontalSliderEvent:String = "HorizontalSliderEvent"; public var param:Object; public function HorizontalSliderEvent(type:String, param:Object, bubbles:Boolean = false, cancelable:Boolean = false) { super(type, bubbles, cancelable); this.param = param; } override public function toString() : String { return "HorizontalSliderEvent: " + param.toString(); } } }