Flash 在Actionscript 3中拖动时检测鼠标离开舞台

Flash 在Actionscript 3中拖动时检测鼠标离开舞台,flash,actionscript-3,events,mouseevent,Flash,Actionscript 3,Events,Mouseevent,在ActionScript3中非常好,但是如果用户按住鼠标左键(或右键),它似乎不会启动 有没有办法在按住鼠标时检测鼠标是否离开Flash电影?或者,如果它是在flash电影之外发布的?如果你正在做一些事情,而你正在拖动一个电影剪辑,这似乎很有效 stage.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut); 编辑-没关系 有没有办法在按住鼠标时检测鼠标是否离开Flash电影 据我所知,没有 或者它是在flash电影之外发布的 Event.M

在ActionScript3中非常好,但是如果用户按住鼠标左键(或右键),它似乎不会启动


有没有办法在按住鼠标时检测鼠标是否离开Flash电影?或者,如果它是在flash电影之外发布的?

如果你正在做一些事情,而你正在拖动一个电影剪辑,这似乎很有效

stage.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
编辑-没关系

有没有办法在按住鼠标时检测鼠标是否离开Flash电影

据我所知,没有

或者它是在flash电影之外发布的

Event.MOUSE_离开在您释放到外部时发生

更多信息请点击这里 请参阅JIMISAACS评论。

以下是我的工作:

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();
    }
}
mc.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
mousedown(_e:MouseEvent)上的私有函数:void
{
mc2.startDrag(参数);
stage.addEventListener(MouseEvent.MOUSE\u UP,onMouseUp);
stage.addEventListener(Event.MOUSE\u LEAVE,onMouseLeave);
stage.addEventListener(MouseEvent.MOUSE_OUT,onMouseOut);
}
mouseup上的私有函数(_e:MouseEvent):void
{
ms2.stopDrag();
}
mouseLeave的私有函数(_e:Event):void
{
mc2.stopDrag();
}
onMouseOut(_e:MouseEvent)的私有函数:void
{
if(e.stageX=stage.stageWidth | | e.stageY=stage.stageHeight)
{
mc2.stopDrag();
}
}

我在不得不构建到Flex应用程序中的PDF类型查看器中遇到了类似的问题。我希望即使鼠标离开舞台或浏览器窗口,平移功能仍能工作。下面是我如何做到这一点的,我修改了代码以删除对Flex框架类的引用,因此这应该适用于任何AS3项目。在
mouseDown
上,我将开始在计时器上跟踪这些值<代码>\u客户端可以是目标阶段中的任何
flash.display.DisplayObject
。在我的例子中,它是一个Flex
mx.controls.SWFLoader
对象,但在您的例子中,我认为它应该是拖动目标:

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

private function get currentMouseY():Number
{
     return _client.stage.mouseY; 
}
stage.mouseX
stage.mouseY
值是相对于stage定义的,无论鼠标是否在stage中,甚至是在浏览器窗口中(至少在Flash Player 10中,我没有在早期的Flash Player版本中测试过这一点)。要查看鼠标是否在后台,只需测试并查看这些值是否在后台,如下所示:

if (currentMouseY < 0 || 
    currentMouseY > _client.stage.height || 
    currentMouseX < 0 || 
    currentMouseX > _client.stage.width)
{
     // Do something here
}
编辑:删除对Flex框架类的引用
编辑:我记得当应用程序在Mac OSX上的Safari浏览器中运行时,浏览器窗口之外的事件可能会出现一些问题。如果使用该浏览器,请确保在该浏览器中测试该代码。这在我的应用程序中不是问题,所以我没有进一步研究这个问题。

要获得所有这些,需要一点技巧。您必须存储鼠标是否离开舞台并处理
事件。鼠标将相应地离开
事件。这样做可以提供所有正常的鼠标功能,包括不会因为鼠标离开舞台而停止拖动。因为用户可能会回到舞台上继续拖动,所以它会等待,直到用户在舞台上或舞台下释放鼠标

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");
}
问题在于,当鼠标被释放出舞台时,会触发
鼠标离开
事件,而不是
鼠标向上
事件,因此您必须跟踪鼠标释放时是否已经离开舞台


拖动完成后,您当然希望删除与检测鼠标悬停和鼠标向上移动相关的所有事件侦听器,但出于可读性考虑,该代码被省略了。

这里有几个棘手的陷阱:

一件奇怪的事情是,在Chrome+Firefox中,鼠标离开事件没有被调度为
不透明
透明
。它只是不点火-鼠标向下或向上

使用
窗口
它可以正常工作。我花了很长时间才弄明白!grr


第二,确保对
事件的参数类型使用
Event
。鼠标离开
处理程序,而不是
MouseEvent
。如果您试图用
e:MouseEvent
处理
MOUSE\u LEAVE
,您将得到一个可能永远看不到的错误(除非您使用的是调试flash播放器)。这是一个非常容易犯的错误,因为您可能将所有其他处理程序指向同一个方法

下面是我要做的:(只需从
mouseLeave(e:Event)


这是正确的答案。自定义类可以将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);
        }
    }

}
package fanlib.gfx
{
导入flash.display.DisplayObject;
导入flash.display.Stage;
导入flash.events.Event;
导入flash.events.MouseEvent;
导入flash.geom.Point;
导入flash.ui.Mouse;
公共类拖动
{
私有变量obj:DisplayObject;
私有变量点:点=新点();
私有var-stg:阶段;
公共函数拖动(obj:DisplayObject)
{
this.obj=obj;
stg=stg.Get();
stg.addEventListener(MouseEvent.MOUSE\u MOVE,mouseMove);
stg.addEventListener(MouseEvent.MOUSE\u UP,停止拖动);
//stg.addEventListener(Event.MOUSE_LEAVE,stopDrag);//sh*t只是不会开火
点设置为(stg.mouseX,stg.mouseY);
}
私有函数mouseMove(e:MouseEvent):void{
如果(stg.mouseX=stg.stageHeight){
停止拖动();
返回;
}
obj.x+=标准鼠标点x;
对象y+=标准鼠标点y;
点设置为(stg.mouseX,stg.mouseY);
}
公共函数stopDrag(e:*=null):无效{
stg.removeEventListener(MouseEvent.MOUSE\u MOVE,mouseMove);
stg.removeEventListener(MouseEvent.MOUSE_UP,stopDrag);
//stg.removeEventListener(Event.MOUSE_LE
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
}
    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();
    }
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);
        }
    }

}