Event.MOUSE_LEAVE Actionscript 3では優れていますが、ユーザーがマウスの左ボタン(または右ボタン)を押したままにしている場合は起動しないようです。
マウスを押している間にマウスがFlashムービーを離れたかどうかを検出する方法はありますか?それとも、フラッシュムービーの外でリリースされた場合はどうなりますか?
これらすべてを取得するには、少しハックする必要があります。マウスがステージから外れているかどうかを保存し、それに応じて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
イベントが発生するため、マウスが解放されたときにすでにステージから外れていたかどうかを追跡する必要があることです。 。
ドラッグが終了したら、もちろん、マウスアウトとマウスアップの検出に関連するすべてのイベントリスナーを削除する必要がありますが、そのコードは読みやすくするために省略されています。
これが私がすることです:
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();
}
}
陥らないように注意が必要なトラップがいくつかあります。
奇妙なことの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
}
_
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.mouseX
とstage.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ブラウザーで実行すると、ブラウザーウィンドウ外のイベントに問題が発生する可能性があることを覚えています。このコードを使用する場合は、必ずそのブラウザでテストしてください。これは私のアプリケーションでは問題ではなかったので、この問題についてはこれ以上調べませんでした。
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();
}
ムービークリップをドラッグしている場所で何かをしている場合、これはうまく機能しているようです。
stage.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
編集-気にしないで
これが正しい答えです。 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);
}
}
}
マウスを押している間にマウスがFlashムービーを離れたかどうかを検出する方法はありますか?
私が知っていることではありません
それとも、フラッシュムービーの外でリリースされた場合はどうなりますか?
Event.MOUSE_LEAVEは、外部でリリースすると発生します。
詳細はこちら http://blog.zupko.info/?p= JIMISAACSのコメントを参照してください。