Detect Mouse leave stage while dragging in Actionscript 3

后端 未结 8 566
我寻月下人不归
我寻月下人不归 2020-12-05 05:27

Event.MOUSE_LEAVE is great in Actionscript 3, but it doesn\'t seem to fire if the user is holding their left (or right for that matter) mouse button down.

Is there a

相关标签:
8条回答
  • 2020-12-05 06:07

    If your doing something where you are dragging a MovieClip this seems to work nicely.

    stage.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
    

    EDIT - never mind

    0 讨论(0)
  • 2020-12-05 06:08

    Here's a couple tricky traps not to fall into :

    One bizarre thing is that in Chrome + Firefox, the MOUSE_LEAVE event isn't dispatched for a WMODE of OPAQUE orTRANSPARENT. It just doesn't fire - mouse down or up.

    With WINDOW it works fine. That one took me a long time to find out! grr... http://bugs.adobe.com/jira/browse/FP-892


    Second, make sure you're using Event for the parameter type for your Event.MOUSE_LEAVE handler and not MouseEvent. If you try to handle MOUSE_LEAVE with e:MouseEvent you'll get an error that you may never see (unless you're using the debug flash player). It's a very easy mistake to make because you're probably pointing all your other handlers to the same method.

    Here's what I do: (just call my main endDrag from mouseLeave(e:Event)

    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
    }
    
    0 讨论(0)
  • 2020-12-05 06:10

    Is there a way to detect if the mouse leaves the Flash movie while the mouse is held down?

    Not that i know of

    Or if it is released outside the flash movie?

    Event.MOUSE_LEAVE does happen when you release outside.

    more info here http://blog.zupko.info/?p=3 see JIMISAACS comment.

    0 讨论(0)
  • 2020-12-05 06:18

    To get all of that requires a little bit of a hack. You have to store whether the mouse is off the stage or not and handle the Event.MOUSE_LEAVE event accordingly. Doing it this way gives you all the normal mouse functionality including not stopping the drag just because the mouse went off stage. Since the user might come back on stage and continue the drag it waits 'til the user releases the mouse either on or off stage.

    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");
    }
    

    The hack is that the MOUSE_LEAVE event, not the MOUSE_UP event, gets fired when the mouse is released off stage so you have to keep track of whether or not the mouse was already off stage when it was released.

    after the drag is finished you of course want to remove all the event listeners associated with detecting mouse-outs and mouse-ups but that code was left out for readability.

    0 讨论(0)
  • 2020-12-05 06:28

    I encountered a similar problem in a PDF type viewer I had to build into a Flex application. I wanted the pan functions to still work even if the mouse left the stage or the browser window. Here is how I accomplished this, I've changed the code to remove references to Flex Framework classes so this should be applicable to any AS3 project. On mouseDown I would start tracking these values on a timer. _client can be any flash.display.DisplayObject in the target stage. In my case it was a Flex mx.controls.SWFLoader object, but in your case I suppose it would be the drag target:

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

    The stage.mouseX and stage.mouseY values are defined relative to the stage whether the mouse is in the stage or even in the browser window (at least in Flash Player 10, I haven't tested this in earlier flash player versions). To see if the mouse is outside the stage just test and see if these values are within the stage, like so:

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

    EDIT: As to detecting a mouseUp event outside of the stage, if you register a listener on the stage, a mouseUp will be issued even if the event occurs outside of the stage or the browser. Here is the code for how I handle events function for reference. The _client object can be any 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;
         }
     }
    

    EDIT: Removed references to Flex framework classes EDIT: I remember that there may be some problem with events outside of the browser window when the application is run in the Safari browser on Mac OSX. Make sure you test this code in that browser if you use it. This wasn't a problem in my application, so I didn't look into the issue further.

    0 讨论(0)
  • 2020-12-05 06:29
        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 讨论(0)
提交回复
热议问题