2011-07-07 32 views
0

有人知道如何在空中应用中捕捉鼠标。我知道它的可能性,因为flex滚动条捕捉鼠标。我想复制滚动条的鼠标捕捉。有谁知道如何在Flex/Flash Air应用程序中捕捉鼠标?

试试这个在Flex/AIR应用程序窗口:如果按

<s:Scroller height="500" width="300"> 
    <s:VGroup> 
     <s:Rect width="100%" height="2000"> 
      <s:fill> 
       <s:SolidColor color="#ffcc00"/> 
      </s:fill> 
     </s:Rect> 
    </s:VGroup> 
</s:Scroller> 

并按住滚动条手柄并拖动之外,连外面的窗口,滚动条仍然有效。它不会失去焦点。所以它捕获鼠标。

我想要什么:

  • 鼠标和触摸拍摄。 (即使在窗户外仍然按下按钮或触摸点)
+0

您是否尝试过实施这种天真的方式?回想起来,它会自动运行 - 只要拖动操作正在进行中,即使在舞台外,您也可以继续获取MouseMove事件。它可能也取决于注册,比如说MouseDown或DragStart,但不应该有任何魔力。 – fenomas

+0

我实际上并没有试图拖动一个对象,我想实现平移。像任何触摸设备,当你想向下滚动。你知道我可以使用的东西吗?我尝试了startDrag,但它使用了整个容器Im。它有点捕捉鼠标,如果鼠标在窗口之外,则不会触发事件,但当鼠标返回到窗口时继续拖动。 – Vicro

+0

我无法将此视觉化。这是在浏览器中,对吗?你在触摸设备上吗? (通常在设备上,浏览器在进入Flash之前就会进行拖拽事件,除非在某些情况下(例如全屏模式)。) 无论如何,我会用一些测试代码编写正确的答案,因为我相信这应该可以正常工作(这意味着您的问题可能会在其他地方)。 – fenomas

回答

0

至少在使用鼠标的桌面上,据我所知,这应该是正常工作。例如:

import flash.text.TextField; 
import flash.events.MouseEvent; 

var t:TextField = new TextField(); 
stage.addChild(t); 
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouse); 

function onMouse(e:MouseEvent) { 
    t.text = e.stageX +", "+ e.stageY; 
} 

对于我来说,事件在文本字段中显示两个时鼠标的Flash区域,并单击Flash内部并拖动外里面的时候。因此,如果您遇到问题,我的猜测是它可能与您正在使用的组件或您的内容的结构(例如您注册事件的对象等)有关。但是,当用户拖出Flash矩形时,没有任何特殊的方式让鼠标事件继续。 (请注意,触摸设备可能是一种不同的情况 - 通常他们的浏览器在Flash全屏模式之前到达Flash之前就会进行平移手势,或者有时当Flash“放大”时它们会给Flash拖动事件(通过双击)。您的里程可能因不同设备上的不同浏览器而异..)

+0

这实际上是一个带触摸屏的平板电脑(平板电脑或触摸屏)。你的例子是否在空气应用程序中工作?例如,你开始一个拖放操作,并在按住鼠标的同时将鼠标移动到窗口之外? – Vicro

+0

它在PC上的AIR应用程序中正常工作。我不知道slates,因为我从来没有用过,但除非操作系统像我描述的那样吃事件,否则它应该以同样的方式工作。顺便提一下,默认情况下,触摸事件会被转换为鼠标事件,所以您应该也可以免费使用它们。 (即使应用程序在触摸设备上运行,您也必须先切换一些开关。) – fenomas

+0

我做了一些测试,如果将侦听器添加到舞台并单击并拖动到窗口外面,它会起作用。活动将走到舞台。所以如果我点击舞台并按住按钮,舞台就会捕捉鼠标。它不会为一个按钮工作。如果我点击并拖动按钮外面,它不会捕获鼠标,所以不会有事件发生。 – Vicro

0

您无法获得任何对您有意义的信息。我明白你要完成的是什么,是的,你说得对,滚动条对他们来说有一些黑魔法,因为如果你开始拖动它,即使鼠标超出了播放器的范围,它也将继续滚动。

我跑了一些试图聆听事件并空手而来的测试。玩家本身必须得到他们,但他们不会暴露在我能找到的地方。

所以,我想创建一个或多或少的隐藏的滚动组件(或它们的集合)来捕获点击并开始拖动事件。有点黑客,但很酷的想法...

然后,您可以轮询当前的滚动位置,以猜测鼠标在窗口外的位置(带有一组水平和垂直滚动条)。您可以这样做,但是,问题是滚动条位置值会根据其原始大小而具有最大限制。这意味着你将在鼠标所在的位置上留下空隙。因此,即使Y轴鼠标位于应用程序的左侧或右侧(X轴)之外(例如,我在第二台显示器上),您也可以知道Y轴鼠标位于屏幕上的位置,但是您会不知道它在X轴上的存在位置,并且只会知道与应用程序大小相关的Y(不在其他位置)。

这里是你可以用这一招捕捉什么图像/黑客: enter image description here

所以,是的,你可以像我描述的方法做的轮询类型,但是,你只会得到这些坐标。

最终,它不是非常有用,因为您需要扩展滚动矩形(或应用程序)的边界以完全捕获鼠标所在的位置 - 因此您可以将其扩展为全屏大小,并且可以只是使用正常的事件。对于负面的边界(左边或上面的应用)尤其如此。

我没有尝试过的是创建一个大容器放置在主应用程序窗口外并将滚动条应用到它。如果你这样做,你可能会使其工作:

enter image description here

这是一个有趣的概念,聪明的 - 绝对不支持的功能。 :P〜

+0

我也想过在内容的顶部放置一个隐藏的滚动条来处理滚动,但是我也希望能够在点击或点击时(不拖动)点击区域内的对象进行点击(不拖动) – Vicro

+0

我向你保证柔性滚动条中没有黑魔法,它们使用与您相同的事件。该框架是开源的,你可以检查你是否喜欢。 – fenomas

0

下面是一些代码我用于此目的:

import flash.display.InteractiveObject; 
import flash.events.MouseEvent; 
import flash.geom.Point; 

public class Dragger 
{ 
    private var target:InteractiveObject; 
    private var mouseDownPoint:Point; 
    private var originalPosition:Point; 

    public function Dragger(target:InteractiveObject) 
    { 
     this.target = target; 
     target.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); 
    } 

    private function onMouseDown(event:MouseEvent):void 
    { 
     mouseDownPoint = new Point(event.stageX, event.stageY); 
     originalPosition = new Point(target.x, target.y); 
     event.stopPropagation(); 

     target.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); 
     target.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); 
    } 
    private function onMouseUp(event:MouseEvent):void 
    { 
     onMouseMove(event); 
     mouseDownPoint = null; 
     event.stopPropagation(); 
     target.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); 
     target.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); 
    } 
    private function onMouseMove(event:MouseEvent):void 
    { 
     if (!mouseDownPoint) return; 
     target.x = originalPosition.x + event.stageX - mouseDownPoint.x; 
     target.y = originalPosition.y + event.stageY - mouseDownPoint.y; 
     event.updateAfterEvent();    
     event.stopPropagation(); 
    } 
} 

要使用,只需做新的牵引机(your_object)。