web-dev-qa-db-ja.com

Actionscript3でドラッグ中にマウスがステージを離れることを検出する

Event.MOUSE_LEAVE Actionscript 3では優れていますが、ユーザーがマウスの左ボタン(または右ボタン)を押したままにしている場合は起動しないようです。

マウスを押している間にマウスがFlashムービーを離れたかどうかを検出する方法はありますか?それとも、フラッシュムービーの外でリリースされた場合はどうなりますか?

16
Adam Harte

これらすべてを取得するには、少しハックする必要があります。マウスがステージから外れているかどうかを保存し、それに応じてEvent.MOUSE_LEAVEイベントを処理する必要があります。このようにすると、マウスがステージから外れたからといってドラッグを停止しないなど、通常のマウス機能がすべて提供されます。ユーザーがステージに戻ってドラッグを続ける可能性があるため、ユーザーがステージ上またはステージ外でマウスを離すまで待機します。

var mouseOffStage:Boolean;

var bonk:YourDisplayObject = new YourDisplayObject()
addChild(bonk);
bonk.addEventListener(MouseEvent.MOUSE_DOWN, function():void {
  mouseOffStage = false;

  bonk.startDrag();

  stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
  stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);
  stage.addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
  stage.addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
})

private function mouseUp(e:MouseEvent) :void {
  trace("Mouse Up On Stage")
  bonk.stopDrag()
}

private function mouseLeave(e:Event) :void {
  if(mouseOffStage){
    trace("mouse up and off stage");
    bonk.stopDrag();
  }else{
    trace("mouse has left the stage");
    //no reason to stop drag here as the user hasn't released the mouse yet
  }
}

private function mouseOut(e:MouseEvent) :void {
  mouseOffStage = true;
  trace("mouse has left the stage")
}

private function mouseOver(e:MouseEvent) :void {
  mouseOffStage = false;
  trace("mouse has come back on stage");
}

ハックは、マウスがステージから解放されたときにMOUSE_LEAVEイベントではなくMOUSE_UPイベントが発生するため、マウスが解放されたときにすでにステージから外れていたかどうかを追跡する必要があることです。 。

ドラッグが終了したら、もちろん、マウスアウトとマウスアップの検出に関連するすべてのイベントリスナーを削除する必要がありますが、そのコードは読みやすくするために省略されています。

28
greggreg

これが私がすることです:

mc.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

private function onMouseDown(_e:MouseEvent):void
{
    mc2.startDrag(params);

    stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
    stage.addEventListener(Event.MOUSE_LEAVE, onMouseLeave);
    stage.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
}

private function onMouseUp(_e:MouseEvent):void
{
    ms2.stopDrag();
}

private function onMouseLeave(_e:Event):void
{
    mc2.stopDrag();
}

private function onMouseOut(_e:MouseEvent):void
{
    if (e.stageX <= 0 || e.stageX >= stage.stageWidth || e.stageY <= 0 || e.stageY >= stage.stageHeight)
    {
        mc2.stopDrag();
    }
}
4
Michal M

陥らないように注意が必要なトラップがいくつかあります。

奇妙なことの1つは、Chrome + Firefoxでは、MOUSE_LEAVEイベントがOPAQUE or TRANSPARENT。マウスを下または上に動かしても起動しません。

WINDOWを使用すると、正常に機能します。それを見つけるのに長い時間がかかりました! grr ... http://bugs.Adobe.com/jira/browse/FP-892


次に、Eventではなく、_Event.MOUSE_LEAVE_ハンドラーのパラメータータイプにMouseEventを使用していることを確認します。 _MOUSE_LEAVE_を_e:MouseEvent_で処理しようとすると、(デバッグフラッシュプレーヤーを使用していない限り)表示されない可能性のあるエラーが発生します。他のすべてのハンドラーが同じメソッドを指している可能性があるため、これは非常に簡単な間違いです。

私がしていることは次のとおりです(mouseLeave(e:Event)からメインのendDragを呼び出すだけです。

_stage.addEventListener(MouseEvent.MOUSE_MOVE, drag);
stage.addEventListener(MouseEvent.MOUSE_UP, endDrag);
stage.addEventListener(Event.DEACTIVATE, endDrag);
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);

private function mouseLeave(e:Event):void
{
    endDrag(new MouseEvent("MOUSE_LEAVE"));
}

public function endDrag(evt:MouseEvent):void
{
    /// handle end drag
}
_
2
Simon_Weaver

Flexアプリケーションに組み込む必要のあるPDFタイプのビューアで同様の問題が発生しました。マウスがステージまたはブラウザウィンドウから離れても、パン機能を引き続き機能させたいと思いました。これがこれをどのように達成したか、Flex Frameworkクラスへの参照を削除するようにコードを変更したため、これはすべてのAS3プロジェクトに適用できます。mouseDownで、タイマーでこれらの値の追跡を開始します。_clientターゲットステージでは任意のflash.display.DisplayObjectにすることができます。私の場合はFlexmx.controls.SWFLoaderオブジェクトでしたが、あなたの場合はドラッグターゲットになると思います。

private function get currentMouseX():Number
{
     return _client.stage.mouseX; 
}

private function get currentMouseY():Number
{
     return _client.stage.mouseY; 
}

stage.mouseXstage.mouseYの値は、マウスがステージにあるかブラウザウィンドウにあるかに関係なく、ステージに関連して定義されます(少なくとも、Flash Player 10では、以前のFlashPlayerではテストしていません。バージョン)。マウスがステージの外にあるかどうかを確認するには、次のようにテストして、これらの値がステージ内にあるかどうかを確認します。

if (currentMouseY < 0 || 
    currentMouseY > _client.stage.height || 
    currentMouseX < 0 || 
    currentMouseX > _client.stage.width)
{
     // Do something here
}

編集:ステージ外でのmouseUpイベントの検出に関しては、ステージにリスナーを登録すると、イベントがステージまたはブラウザの外部で発生した場合でも、mouseUpが発行されます。参照用にイベント関数を処理する方法のコードを次に示します。 _clientオブジェクトは任意のflash.display.DisplayObjectにすることができます。

 // attach the events like so when you initialize
 _client.addEventListener(MouseEvent.MOUSE_DOWN  , handleMouse);   
 _client.addEventListener(MouseEvent.MOUSE_OUT   , handleMouse);
 _client.addEventListener(MouseEvent.MOUSE_OVER  , handleMouse);
//

// and handle them like this:
 private function handleMouse(e:MouseEvent):void
 {
      switch(e.type)
      {

          case "mouseDown":

         // add listeners, notice the mouse move and mouse up are 
         // attached to the stage, not the display object this way
         // events are issued regardless of whether the mouse is in 
         // the stage or even within the browser window

         _client.stage.addEventListener(MouseEvent.MOUSE_UP, handleMouse);
         _client.addEventListener(MouseEvent.CLICK, handleMouse);      
         _client.stage.addEventListener(MouseEvent.MOUSE_MOVE, handleMouse);    


         // remove listeners     
         _client.removeEventListener(MouseEvent.MOUSE_DOWN, handleMouse); 

         //
         // commands / actions 

         break;


         case "mouseUp":

         // add listeners
        _client.addEventListener(MouseEvent.MOUSE_DOWN, handleMouse); 


         // remove listeners 
         _client.stage.removeEventListener(MouseEvent.MOUSE_UP, handleMouse);
         _client.stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleMouse);    


         // commands/actions 

         break;


         case "click":


         // add listeners
         _client.addEventListener(MouseEvent.DOUBLE_CLICK, handleMouse);


         // remove listeners    
         _client.removeEventListener(MouseEvent.CLICK, handleMouse); 


         // commands / actions

         break;

         case "mouseMove":

         // add listeners


         // remove listeners
         _client.stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleMouse);
         _client.removeEventListener(MouseEvent.CLICK, handleMouse);   


         // commands 

         break;

         case "mouseOut":

         // add listeners


         // remove listeners

         // commands / actions

         break;

         case "mouseOver":

         // add listeners


         // remove listeners


         // commands /actions

         break;
     }
 }

編集:Flexフレームワーククラスへの参照を削除しました編集:アプリケーションをMac OSXのSafariブラウザーで実行すると、ブラウザーウィンドウ外のイベントに問題が発生する可能性があることを覚えています。このコードを使用する場合は、必ずそのブラウザでテストしてください。これは私のアプリケーションでは問題ではなかったので、この問題についてはこれ以上調べませんでした。

1
Ryan Lynch
    var youMax_X:Number; //set this var to Max x
    var youMax_Y:Number; //set this var to `enter code here`Max y

    var dragBounds:Rectangle = new Rectangle(0,0,youMax_X,yourMax_Y);

    stage.addEventListener(MouseEvent.MOUSE_DOWN,handleDown);
    stage.addEventListener(MouseEvent.MOUSE_UP,handleUp);


    private function handleDown(e:Event):void{
            this.startDrag(false,dragBounds);
    }
    private function handleUp(e:Event):void{
        this.stopDrag();
    }
0
Jileni Bouguima

ムービークリップをドラッグしている場所で何かをしている場合、これはうまく機能しているようです。

stage.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);

編集-気にしないで

0
Allan

これが正しい答えです。 DisplayObjectを渡すカスタムクラスで、マウスを上に移動するか、マウスをステージから外すまでドラッグします。自由にカスタマイズ:

package fanlib.gfx
{
    import flash.display.DisplayObject;
    import flash.display.Stage;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.ui.Mouse;

    public class Drag
    {
        private var obj:DisplayObject;
        private var point:Point = new Point();
        private var stg:Stage;

        public function Drag(obj:DisplayObject)
        {
            this.obj = obj;
            stg = Stg.Get();
            stg.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
            stg.addEventListener(MouseEvent.MOUSE_UP, stopDrag);
            //stg.addEventListener(Event.MOUSE_LEAVE, stopDrag); // sh*t just won't fire
            point.setTo(stg.mouseX, stg.mouseY);
        }

        private function mouseMove(e:MouseEvent):void {
            if (stg.mouseX <= 0 ||
                stg.mouseY <= 0 ||
                stg.mouseX >= stg.stageWidth ||
                stg.mouseY >= stg.stageHeight) {
                stopDrag();
                return;
            }
            obj.x += stg.mouseX - point.x;
            obj.y += stg.mouseY - point.y;
            point.setTo(stg.mouseX, stg.mouseY);
        }

        public function stopDrag(e:* = null):void {
            stg.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
            stg.removeEventListener(MouseEvent.MOUSE_UP, stopDrag);
            //stg.removeEventListener(Event.MOUSE_LEAVE, stopDrag);
        }
    }

}
0
Bill Kotsias

マウスを押している間にマウスがFlashムービーを離れたかどうかを検出する方法はありますか?

私が知っていることではありません

それとも、フラッシュムービーの外でリリースされた場合はどうなりますか?

Event.MOUSE_LEAVEは、外部でリリースすると発生します。

詳細はこちら http://blog.zupko.info/?p= JIMISAACSのコメントを参照してください。

0
SketchBookGames