如何防止拖动操作影响MovieClip的儿童 [英] How to prevent a drag action to affect the childrens of a MovieClip

查看:120
本文介绍了如何防止拖动操作影响MovieClip的儿童的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是:我有一个MovieClip( obj ),用户可以拖动双方进行导航,我用这个代码:

  import flash.events.MouseEvent; 
导入flash.geom.Point;
import flash.events.Event;
import flash.geom.Rectangle;

var destination:Point = new Point();
var dragging:Boolean = false;
var speed:Number = 10;
var offset:Point = new Point();
var bounds:Rectangle = new Rectangle(0,0,stage.stageWidth,stage.stageHeight);

obj.addEventListener(MouseEvent.MOUSE_DOWN,startdrag);
stage.addEventListener(MouseEvent.MOUSE_UP,stopdrag);
obj.addEventListener(Event.ENTER_FRAME,followmouse);

函数startdrag(e:MouseEvent):void {
offset.x = obj.mouseX * obj.scaleX;
dragging = true;


函数stopdrag(e:MouseEvent):void {
dragging = false;


函数followmouse(e:Event):void {
if(obj){
if(dragging){
destination.x = mouseX ;


obj.x - =(obj.x - (destination.x - offset.x))/ speed;

if(obj.x> bounds.left){
obj.x = bounds.left;
}

if(obj.x< -obj.width + bounds.right){
obj.x = -obj.width + bounds.right;



$ / code $ / pre

到目前为止,当我在MovieClip( obj )中放置一些可点击的元素时,问题就出现了,下面是可点击元素的代码:

  objA.addEventListener(MouseEvent.CLICK,objATrigger); 
objB.addEventListener(MouseEvent.CLICK,objBTrigger);
objC.addEventListener(MouseEvent.CLICK,objCTrigger);

函数objATrigger(event:MouseEvent):void {
MovieClip(this.parent).gotoAndPlay(1,Main);


函数objBTrigger(event:MouseEvent):void {
MovieClip(this.parent).gotoAndPlay(1,Main);


函数objCTrigger(event:MouseEvent):void {
MovieClip(this.parent).gotoAndPlay(1,Main);



$ b $ p
$ b

问题是:当我拖动MovieClip( obj )与事件发生冲突,在拖动后释放鼠标时,MovieClip中的MovieClip事件点击 $ c> obj )被解雇,我该如何解决这个问题?只有在没有拖动动作的情况下才能触发它们。

解决方案

这就是我如何处理拖动有可点击的子项的父项。这种方法的好处是,你不需要对孩子做任何事情(在他们的点击处理程序等没有额外的条件),点击事件根本无法达到他们。



您也可以希望从下面的代码/注释中获得一些效率提示:

  var wasDragged:Boolean = false ; 
var dragThreshold:Point = new Point(10,10);
// ^需要移动多少个像素才能被视为拖动
//这在触摸屏上尤其好,因为点击时很容易意外地拖动项目几个像素。

var dragStartPos:Point = new Point(); //存储拖动原点以计算是否发生了拖动
var dragOffset:Point = new Point(); //追踪鼠标停靠点与对象左上角之间的空白处

obj.addEventListener(MouseEvent.MOUSE_DOWN,startdrag);
obj.addEventListener(MouseEvent.CLICK,dragClick,true); //监听事件的捕获阶段。

//我们听点击可拖动对象的唯一原因是取消点击事件,所以它的孩子不会得到
function dragClick(e:Event):void {
//如果我们认为它是一个拖动,停止点击事件到达obj
的子元素if(wasDragged)e.stopImmediatePropagation();


函数startdrag(e:MouseEvent):void {
//重置所有的拖动变量
wasDragged = false;
dragStartPos.x = obj.x;
dragStartPos.y = obj.y;

//设置偏移量,使对象在第一次点击时不跳转
dragOffset.x = stage.mouseX - obj.x;
dragOffset.y = stage.mouseY - obj.y;

//只添加鼠标向上的侦听器鼠标向下
stage.addEventListener(MouseEvent.MOUSE_UP,stopdrag);
// mouse_move比enter_frame更高效,只在拖动
时监听它。


$ b $ remove b





$ b $ ;
stage.removeEventListener(MouseEvent.MOUSE_MOVE,followmouse);









$ obj.x = stage.mouseX - dragOffset.x;
obj.y = stage.mouseY - dragOffset.y;

//检查obj是否从原始位置移动得足够远以至于被认为是拖拽
if(!wasDragged
&&(Math.abs(obj.x - dragStartPos.x)> dragThreshold.x
|| Math.abs(obj.y - dragStartPos.y)> dragThreshold.y)
){
wasDragged = true;
}
}
}


My problem is: I have a MovieClip (obj) that users can drag to both sides to navigate, the code I use for this:

import flash.events.MouseEvent;
import flash.geom.Point;
import flash.events.Event;
import flash.geom.Rectangle;

var destination: Point = new Point();
var dragging: Boolean = false;
var speed: Number = 10;
var offset: Point = new Point();
var bounds: Rectangle = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);

obj.addEventListener(MouseEvent.MOUSE_DOWN, startdrag);
stage.addEventListener(MouseEvent.MOUSE_UP, stopdrag);
obj.addEventListener(Event.ENTER_FRAME, followmouse);

function startdrag(e: MouseEvent): void {
    offset.x = obj.mouseX * obj.scaleX;
    dragging = true;
}

function stopdrag(e: MouseEvent): void {
    dragging = false;
}

function followmouse(e: Event): void {
    if (obj) {
        if (dragging) {
            destination.x = mouseX;
        }

        obj.x -= (obj.x - (destination.x - offset.x)) / speed;

        if (obj.x > bounds.left) {
            obj.x = bounds.left;
        }

        if (obj.x < -obj.width + bounds.right) {
            obj.x = -obj.width + bounds.right;
        }
    }
}

So far so good, the problem comes up when I put some clickable elements inside that MovieClip (obj), here are the code for the clickable elements:

objA.addEventListener(MouseEvent.CLICK, objATrigger);
objB.addEventListener(MouseEvent.CLICK, objBTrigger);
objC.addEventListener(MouseEvent.CLICK, objCTrigger);

function objATrigger(event: MouseEvent): void {
    MovieClip(this.parent).gotoAndPlay(1, "Main");
}

function objBTrigger(event: MouseEvent): void {
    MovieClip(this.parent).gotoAndPlay(1, "Main");
}

function objCTrigger(event: MouseEvent): void {
    MovieClip(this.parent).gotoAndPlay(1, "Main");
}

The problem is: When I drag the MovieClip (obj) there is a conflict with the event, when release the mouse after the drag, the event Click of MovieClips inside the MovieClip (obj) is fired, how can I fix this? They should only be triggered when there is no drag action.

解决方案

This is how I handle dragging a parent that has clickable children. The benefit of this method, is that you don't need to do anything to the children (no extra conditions in their click handlers etc), the click event simply doesn't reach them.

You can also hopefully gleam some efficiency tips from the code/comments below:

var wasDragged:Boolean = false;
var dragThreshold:Point = new Point(10,10); 
// ^ how many pixels does it need to move before it's considered a drag
//this is good especially on touchscreens as it's easy to accidentally drag the item a couple pixels when clicking.

var dragStartPos:Point = new Point(); //to store drag origin point to calculate whether a drag occured
var dragOffset:Point = new Point(); //to track the gap between the mouse down point and object's top left corner

obj.addEventListener(MouseEvent.MOUSE_DOWN, startdrag);
obj.addEventListener(MouseEvent.CLICK, dragClick, true); //listen on the capture phase of the event. 

//the only reason we listen for click on the draggable object, is to cancel the click event so it's children don't get it
function dragClick(e:Event):void {
    //if we deemed it a drag, stop the click event from reaching any children of obj
    if(wasDragged) e.stopImmediatePropagation();
}

function startdrag(e: MouseEvent): void {
    //reset all dragging vars
    wasDragged = false;
    dragStartPos.x = obj.x;
    dragStartPos.y = obj.y;

    //set the offset so the object doesn't jump when first clicked
    dragOffset.x = stage.mouseX - obj.x;
    dragOffset.y = stage.mouseY - obj.y;

    //only add the mouse up listener AFTER the mouse down
    stage.addEventListener(MouseEvent.MOUSE_UP, stopdrag);
    //mouse_move is more efficient that enter_frame, and only listen for it when dragging
    stage.addEventListener(MouseEvent.MOUSE_MOVE, followmouse); 
}

function stopdrag(e:MouseEvent = null): void {
    //remove the dragging specific listeners
    stage.removeEventListener(MouseEvent.MOUSE_UP, stopdrag);
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, followmouse); 
}

function followmouse(e:MouseEvent): void {
    if (obj) {
        //do what you need to move the object
        obj.x = stage.mouseX - dragOffset.x;
        obj.y = stage.mouseY - dragOffset.y;

        //check if the obj moved far enough from the original position to be considered a drag
        if(!wasDragged 
            && (Math.abs(obj.x - dragStartPos.x) > dragThreshold.x
            || Math.abs(obj.y - dragStartPos.y) > dragThreshold.y)
        ){
            wasDragged = true;
        }
    }
}

这篇关于如何防止拖动操作影响MovieClip的儿童的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆