【Dragger】高機能なドラッグ操作を容易に
DraggerクラスはあるDisplayObjectに対する
高機能なドラッグ操作を容易に可能にします。
/**
* Copyright wetcradle ( http://wonderfl.net/user/wetcradle )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/zCoV
*/
/*
DraggerクラスはあるDisplayObjectに対する
高機能なドラッグ操作を容易に可能にします。
*/
package {
import flash.display.Sprite;
import flash.geom.Rectangle;
public class DraggerTest extends Sprite {
public function DraggerTest():void {
var sprite1:Sprite = getBox(0x000000);
addChild(sprite1);
var dragger1:Dragger = new Dragger(sprite1);
dragger1.alpha = 0.5;//ドラッグ中のalphaを指定
dragger1.draggableRect = new Rectangle(10, 10, 100, 100);//ドラッグ可能領域
var sprite2:Sprite = getBox(0xff0000);
sprite2.y = 100;
addChild(sprite2);
var dragger2:Dragger = new Dragger(sprite2);
dragger2.vertical = false;//垂直方向のドラッグを禁止
dragger2.bufferDistance = 10;//ドラッグがアクティブになるための猶予距離
}
private function getBox(color:uint):Sprite {
var box:Sprite = new Sprite();
box.graphics.beginFill(color);
box.graphics.drawRect(0, 0, 100, 100);
box.graphics.endFill();
return box;
}
}
}
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
class Dragger extends EventDispatcher {
protected var _target:DisplayObject;
protected var _enabled:Boolean = true;
protected var _horizontal:Boolean = true;
protected var _vertical:Boolean = true;
protected var _bufferDistance:Number = 0;
protected var _alpha:Number = 1;
protected var _dragging:Boolean = false;
protected var _draggableRect:Rectangle;
protected var downPoint:Point;
protected var delta:Point;
protected var originalAlpha:Number;
////////////////////////////////////////////////////////////
//////////////コンストラクタ
////////////////////////////////////////////////////////////
public function Dragger(target:DisplayObject):void {
super();
_target = target;
_target.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
_target.addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
}
////////////////////////////////////////////////////////////
//////////////プロパティ
////////////////////////////////////////////////////////////
//______________ target ______________//
public function get target():DisplayObject {
return _target;
}
//______________ enabled ______________//
public function get enabled():Boolean {
return _enabled;
}
public function set enabled(value:Boolean):void {
_enabled = value;
}
//______________ horizontal ______________//
public function get horizontal():Boolean {
return _horizontal;
}
public function set horizontal(value:Boolean):void {
_horizontal = value;
}
//______________ vertical ______________//
public function get vertical():Boolean {
return _vertical;
}
public function set vertical(value:Boolean):void {
_vertical = value;
}
//______________ bufferDistance ______________//
public function get bufferDistance():Number {
return _bufferDistance;
}
public function set bufferDistance(value:Number):void {
_bufferDistance = value;
}
//______________ alpha ______________//
public function get alpha():Number {
return _alpha;
}
public function set alpha(value:Number):void {
_alpha = value;
}
//______________ draggableRect ______________//
public function get draggableRect():Rectangle {
return _draggableRect;
}
public function set draggableRect(value:Rectangle):void {
_draggableRect = value;
}
//______________ dragging ______________//
public function get dragging():Boolean {
return _dragging;
}
////////////////////////////////////////////////////////////
//////////////パブリックメソッド
////////////////////////////////////////////////////////////
//______________ startDrag ______________//
/**
*/
public function startDrag():void {
if (!_dragging && _target.stage) {
refreshDelta();
}
setDragging(true, _target.stage, false);
}
//______________ stopDrag ______________//
/**
*/
public function stopDrag():void {
setDragging(false, _target.stage, false);
}
//______________ destroy ______________//
/**
*/
public function destroy():void {
setDragging(false, _target.stage, false);
_target.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
_target = null;
}
////////////////////////////////////////////////////////////
//////////////メソッド
////////////////////////////////////////////////////////////
//______________ setDragging ______________//
protected function setDragging(value:Boolean, stage:Stage, fireEvent:Boolean):void {
if (!stage) {
return;
}
if (_dragging == value) {
if (!_dragging) {
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
if (fireEvent) {
dispatchEvent(new DraggerEvent(DraggerEvent.CANCEL_DRAG));
}
}
return;
}
_dragging = value;
if (_dragging) {
originalAlpha = _target.alpha;
_target.alpha = _alpha;
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
if (fireEvent) {
dispatchEvent(new DraggerEvent(DraggerEvent.START_DRAG));
}
}
else {
_target.alpha = originalAlpha;
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
if (fireEvent) {
dispatchEvent(new DraggerEvent(DraggerEvent.STOP_DRAG));
}
}
}
//______________ refreshDelta ______________//
protected function refreshDelta():void {
var globalPoint:Point = _target.parent.localToGlobal(new Point(_target.x, _target.y));
delta = new Point(globalPoint.x - _target.stage.mouseX, globalPoint.y - _target.stage.mouseY);
}
////////////////////////////////////////////////////////////
//////////////イベントハンドラ
////////////////////////////////////////////////////////////
//______________ mouseDownHandler ______________//
protected function mouseDownHandler(e:MouseEvent):void {
if (!_enabled) {
false;
}
_target.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
_target.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
downPoint = new Point(_target.stage.mouseX, _target.stage.mouseY);
refreshDelta();
}
//______________ mouseMoveHandler ______________//
protected function mouseMoveHandler(e:MouseEvent):void {
var stage:Stage = Stage(e.currentTarget);
if (_dragging) {
var localPoint:Point = _target.parent.globalToLocal(new Point(stage.mouseX + delta.x, stage.mouseY + delta.y));
if (_draggableRect) {
localPoint.x = Math.max(_draggableRect.x, Math.min(_draggableRect.x + _draggableRect.width, localPoint.x));
localPoint.y = Math.max(_draggableRect.x, Math.min(_draggableRect.x + _draggableRect.width, localPoint.y));
}
var changed:Boolean = false;
if (_horizontal && _target.x != localPoint.x) {
_target.x = localPoint.x;
changed = true;
}
if (_vertical && _target.y != localPoint.y) {
_target.y = localPoint.y;
changed = true;
}
if (changed) {
dispatchEvent(new DraggerEvent(DraggerEvent.DRAG));
}
}
else if (Point.distance(downPoint, new Point(stage.mouseX, stage.mouseY)) > _bufferDistance) {
setDragging(true, stage, true);//
}
}
//______________ mouseUpHandler ______________//
protected function mouseUpHandler(e:MouseEvent):void {
setDragging(false, Stage(e.currentTarget), true);
}
//______________ removedFromStageHandler ______________//
protected function removedFromStageHandler(e:Event):void {
setDragging(false, Stage(DisplayObject(e.currentTarget).stage), true);
}
}
import flash.events.Event;
class DraggerEvent extends Event {
public static const START_DRAG:String = "draggerStartDrag";
public static const STOP_DRAG:String = "draggerStopDrag";
public static const DRAG:String = "draggerDrag";
public static const CANCEL_DRAG:String = "draggerCancelDrag";
////////////////////////////////////////////////////////////
//////////////コンストラクタ
////////////////////////////////////////////////////////////
public function DraggerEvent(type:String, bubbles:Boolean = true, cancelable:Boolean = false):void {
super(type, bubbles, cancelable);
}
////////////////////////////////////////////////////////////
//////////////パブリックメソッド
////////////////////////////////////////////////////////////
//______________ toString ______________//
override public function toString():String {
return formatToString("DraggerEvent","type","bubbles","cancelable");
}
//______________ clone ______________//
override public function clone():Event {
return new DraggerEvent(type, bubbles, cancelable);
}
}