[AS3] Custom Sliderbar

플래시 가로 슬라이더바

개발이유

플래시에서 제공하는 슬라이더 컴포넌트는 너무 플래시스럽지 않아 자체적으로 제작하여 사용하였습니다.

개발내용

  1. 슬라이더는 이미지를 사용하지 않고 Rectangle 객체를 이용하여 처리한다.
  2. 슬라이더의 값이 변경되면 이벤트를 발생한다.
  3. 슬라이더의 단계를 입력하여 단계별로 이벤트를 발생시킨다.

결과물

CustomSlider

소스

[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();
        }

    }

}

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중