[test]stagedrag
/**
* Copyright okoi ( http://wonderfl.net/user/okoi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/dz78
*/
//
// ステージをドラッグするとオブジェクトがそれに沿って動く処理のテスト
// MOUSE_LEAVEはドラッグ中は送出されないので自前で座標計算を行って再現
//
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.ContextMenuEvent;
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;
[SWF(width = "465", height = "465", frameRate = "60")]
/**
* ...
* @author
*/
public class Main extends Sprite
{
private var sp:Sprite;
private var mouseInStage:Boolean = true;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
sp = new Sprite();
sp.graphics.beginFill(0);
sp.graphics.drawCircle(0, 0, 30);
sp.graphics.endFill();
sp.x = 465 / 2;
sp.y = 465 / 2;
addChild( sp );
this.contextMenu = new ContextMenu();
stage.addEventListener( MouseEvent.MOUSE_DOWN, MouseDownHandler );
stage.addEventListener( MouseEvent.MOUSE_UP, MouseUpHandler );
this.contextMenu.addEventListener( ContextMenuEvent.MENU_SELECT, OpenContextMenuHandler );
addEventListener( Event.ENTER_FRAME, EnterFrameHandler );
}
/**
* ステージ上でマウスが押された時に呼ばれる
* @param event
*/
private function MouseDownHandler( event:MouseEvent ) : void
{
StageDragManager.getInstance().MouseDown( this.stage );
}
/**
* ステージ上でマウスが離された時に呼ばれる
* @param event
*/
private function MouseUpHandler( event:MouseEvent ) : void
{
StageDragManager.getInstance().MouseUp();
}
/**
* コンテキストメニューが開かれた時に呼ばれる
* @param e
*/
private function OpenContextMenuHandler( e:ContextMenuEvent ) : void
{
StageDragManager.getInstance().MouseUp();
}
private function EnterFrameHandler( e:Event ) : void
{
// マウスが場外に出た判定(自前)
// 場外に出た瞬間はMOUSE_UPと同じ状態にする
if ( mouseInStage && (stage.mouseX < 0 || stage.mouseX >= stage.stageWidth || stage.mouseY < 0 || stage.mouseY >= stage.stageHeight) )
{
mouseInStage = false;
MouseUpHandler( null );
}else
if ( stage.mouseX > 0 && stage.mouseX < stage.stageWidth && stage.mouseY > 0 && stage.mouseY < stage.stageHeight )
{
mouseInStage = true;
}
StageDragManager.getInstance().Update(this.stage);
if ( StageDragManager.getInstance().dragflag )
{
sp.x += StageDragManager.getInstance().moveX;
sp.y += StageDragManager.getInstance().moveY;
}
}
}
}
import flash.display.Stage;
import flash.geom.Point;
/**
* ステージのドラッグ情報を管理するクラス(直接処理させるわけではない)
* どっからでも参照したいのでシングルトンパターンで実装
* @author
*/
class StageDragManager
{
private static var instance:StageDragManager = null;
private static var callGetInstance:Boolean = false;
public function StageDragManager()
{
if ( callGetInstance ) {
callGetInstance = false;
}else
{
throw new Error("コンストラクタの直接呼び出しは禁止");
}
}
public static function getInstance() : StageDragManager
{
if ( StageDragManager.instance == null )
{
callGetInstance = true;
StageDragManager.instance = new StageDragManager();
}
return StageDragManager.instance;
}
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
private var mousedownFlag:Boolean = false;
private var mousedownPoint:Point = new Point();
private var dragFlag:Boolean = false;
public function get dragflag():Boolean { return dragFlag; }
private var prevMousePoint:Point = new Point();
private var mouseMoveVector:Point = new Point();
/**
* ステージでマウスダウンが発生した時に呼び出すようにする
* @param stage
*/
public function MouseDown(stage:Stage) : void
{
mousedownFlag = true;
dragFlag = false;
mousedownPoint.x = stage.mouseX;
mousedownPoint.y = stage.mouseY;
}
/**
* ステージでマウスアップが発生、もしくはそれに該当する処理が発生した時に呼び出すようにする
*/
public function MouseUp() : void
{
mousedownFlag = false;
dragFlag = false;
mouseMoveVector.x = 0;
mouseMoveVector.y = 0;
}
/**
*
* @param stage
*/
public function Update(stage:Stage) : void
{
mouseMoveVector.x = 0;
mouseMoveVector.y = 0;
// 差分を見て、ある程度移動していたならドラッグ開始
if ( !dragFlag && mousedownFlag )
{
var sx:Number = (stage.mouseX - mousedownPoint.x);
var sy:Number = (stage.mouseY - mousedownPoint.y);
if ( sx * sx + sy * sy > 5 * 5 )
{
dragFlag = true;
prevMousePoint.x = stage.mouseX;
prevMousePoint.y = stage.mouseY;
mouseMoveVector.x = sx;
mouseMoveVector.y = sy;
trace("ドラッグ開始");
}
}else
// ドラッグ中は毎フレーム移動差分を取る
if( dragFlag )
{
mouseMoveVector.x = stage.mouseX - prevMousePoint.x;
mouseMoveVector.y = stage.mouseY - prevMousePoint.y;
prevMousePoint.x = stage.mouseX;
prevMousePoint.y = stage.mouseY;
}
}
public function get moveX():Number { return mouseMoveVector.x; }
public function get moveY():Number { return mouseMoveVector.y; }
}