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.