スライダーをつくる

カスタムイベントの勉強にスライダーを作ってみた。
とりあえず

  • イベントクラス
  • スライダーのつまみ部分
  • スライダー

の3つのクラスで作ってみた。

イベントクラス

  • 発生するイベント
    • SliderEvent.START => スライダーのドラッグを開始したときに発生
    • SliderEvent.CHANGE => スライダーをドラッグ中に発生
    • SliderEvent.END => ドラッグ終了時に発生
  • コンストラクタのpercentは、ドラッグしているスライダーの割合
package
{
	import flash.events.Event;
	 
	public class SliderEvent extends Event {
		
		public static const START:String = "SliderStart";
		public static const CHANGE:String = "SliderChange";
		public static const END:String = "SliderEnd";
		
		private var _percent:Number;
		
		public function SliderEvent(type:String, percent:Number) {
			super(type);
			_percent = percent;
		}
		
		public function percent():Number {
			return _percent;
		}
		
		
		override public function clone():Event {
			return new SliderEvent(type, _percent);
		}
		
		override public function toString():String {
			return formatToString("SliderEvent", "type", 
			                      "bubbles", "cancelable", "eventPhase", "_percent");
		}
	}
}

スライダーのつまみ部分

  • つまみの絵を描くだけ。
  • コンストラク
    • widthとheightでつまみの大きさを指定。fillColorで何色で塗るか指定。
package
{
	import flash.display.Sprite;
	internal class SliderHandle extends Sprite {
		
		public function SliderHandle(width:Number, height:Number, fillColor:uint = 0xFFFFFF) {
			draw(width, height, fillColor);
		}
		
		private function draw(width:Number, height:Number, fillColor:uint):void {
			graphics.beginFill(fillColor);
			graphics.lineStyle(1, 0x000000);
			graphics.lineTo(width / 2, height);
			graphics.lineTo( -width / 2, height);
			graphics.lineTo(0, 0);
			graphics.endFill();
		}
	}
}

スライダー

  • コンストラク
    • widthはバーの長さ、percentは初期値(0〜100を指定)
  • イベントの送出
    • getPercentで、現在のスライダーバーの割合を計算して、SliderEventをdispatchEventする

startDragにスライダーのつまみを動かせる範囲を指定できたので簡単にかけた。

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;

	public class Slider extends Sprite {
		
		private const BAR_HEIGHT:uint = 10;
		private const SLIDER_HANDLE_WIDTH:uint = 10;
		private const SLIDER_HANDLE_HEIGHT:uint = 20;
		
		private var _handle:SliderHandle;
		private var _bar_width:uint;
		
		public function Slider(width:uint, percent:uint) {
			_bar_width = width;
			drawSlideLine();
			createSliderHandle();
			initStartPosition(percent);
		}
		
		private function drawSlideLine():void {
			graphics.beginFill(0xFFFFFF);
			graphics.lineStyle(1);
			graphics.lineTo(_bar_width, 0);
			graphics.lineTo(_bar_width, BAR_HEIGHT);
			graphics.lineTo(0, BAR_HEIGHT);
			graphics.lineTo(0, 0);
			graphics.endFill();			
		}
		
		private function createSliderHandle():void {
			_handle = new SliderHandle(SLIDER_HANDLE_WIDTH, SLIDER_HANDLE_HEIGHT);
			_handle.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownListener);
			_handle.y = BAR_HEIGHT / 2;
			addChild(_handle);			
		}
		
		private function initStartPosition(percent:uint):void {
			if ( 0 > percent || percent > 100) {
				throw Error("percent mast range 0 to 100:" + percent);
			}
			_handle.x = _bar_width * percent / 100;
		}
		
		private function draggableArea():Rectangle {
			return  new Rectangle(0, BAR_HEIGHT / 2, _bar_width, 0);
		}
		
		private function getPercent():Number {
			return _handle.x / _bar_width * 100;
		}
		
	    private function mouseDownListener(e:MouseEvent):void {
			stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveListener);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
			dispatchEvent(new SliderEvent(SliderEvent.START, getPercent()));
			_handle.startDrag(false, draggableArea());
		}
		
		private function mouseMoveListener(e:MouseEvent):void {
			dispatchEvent(new SliderEvent(SliderEvent.CHANGE, getPercent()));			
		}
		
		private function mouseUpListener(e:MouseEvent):void {
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveListener);
			stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
			dispatchEvent(new SliderEvent(SliderEvent.END, getPercent()));
			_handle.stopDrag();
		}		
	}
}

使い方

下のようにして使う。

package
{
	import flash.display.Sprite;
	
	public class Main extends Sprite {
		public function Main() {
		    var slider:Slider = new Slider(500, 50);
			addChild(slider);
			slider.addEventListener(SliderEvent.START, f1);
			slider.addEventListener(SliderEvent.CHANGE, f2);
			slider.addEventListener(SliderEvent.END, f3);
		}
		
		private function f1(e:SliderEvent):void {
			trace("start:" + e.percent());
		}
		
		private function f2(e:SliderEvent):void {
			trace("change:" + e.percent());
		}
		
		private function f3(e:SliderEvent):void {
			trace("end:" + e.percent());
		}
	}
	
}