使用GestureEvent / MouseEvent

时间:2015-05-13 17:32:18

标签: actionscript-3 flash zoom gesture pan

我想要做的是让我的MovieClip(比视口大)保持其边框可见。就像许多应用程序一样,例如部落冲突。

这样,如果你放大并缩小或平移,你将永远不会看到它下面的舞台。

如果我只是为了平移而不是缩放,那将很容易,因为我只需要计算我的MC矩形是否在我的舞台内,如果是的话我只会:

mc.x = 0 + mc.width / 2;
//or
mc.x = stage.StageWidth - (mc.width/2);
//or .... The same for y

现在最大的问题是当我也放大!每次我提出一些代码时,它都不能很好地工作。在网络上通过GestureEvent进行缩放的例子有很多,但没有一个让MC受到约束,因此你不会看到它下面的舞台。

有人可以为我提供一个例子。让我们说舞台是480x720,mc是1080x720!

你必须平移和放大,同时总是覆盖舞台,mc的比例将保持在1-1.5之内。

这是我目前的代码:

Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener(TransformGestureEvent.GESTURE_PAN, onPan);
stage.addEventListener(MouseEvent.CLICK, gotoBox);

var isInBox: Boolean = false;
table.x = 203.1;
table.y = 360;
table.scaleX = 1;
table.scaleY = 1;

var mouseTimer: Timer;

function onPan(event: TransformGestureEvent): void
{
    if (!isInBox)
    {
        if (event.phase == GesturePhase.BEGIN)
        {
        stage.removeEventListener(MouseEvent.CLICK, gotoBox);
        trace("noClick");
        }

        table.x += event.offsetX;
        table.y += event.offsetY;
        if (table.x > (table.width / 2))
        {
        table.x = table.width / 2;
        }
        if (table.x < stage.stageWidth - (table.width / 2))
        {
            table.x = stage.stageWidth - (table.width / 2)
        }
        if (table.y > (table.height / 2))
        {
            table.y = table.height / 2;
        }
        if (table.y < stage.stageHeight - (table.height / 2))
        {
            table.y = stage.stageHeight - (table.height / 2)
        }

        if (event.phase == GesturePhase.END)
        {
            if (mouseTimer !== null)
            {
                if (mouseTimer.running)
                {
                    mouseTimer.stop();
                    mouseTimer.removeEventListener(TimerEvent.TIMER, enableClick);
                }
            }
            mouseTimer = new Timer(250);
            mouseTimer.addEventListener(TimerEvent.TIMER, enableClick);
            mouseTimer.start();
            trace("start");
        }
    }
}
function enableClick(e: TimerEvent)
{
    mouseTimer.stop();
    trace("stop");
    mouseTimer.removeEventListener(TimerEvent.TIMER, enableClick);
    stage.addEventListener(MouseEvent.CLICK, gotoBox);
    trace("nowClick");
}
function gotoBox(e: MouseEvent)
{
// here it goes to another frame
}

我无法添加缩放功能,因为它完全是灾难;我在此链接FlashAndMath

中使用了与函数onZoom类似的内容

因为我需要放大一个点并从中放出,这是主要的问题,因为我必须移动mc左右才能在中心点上这一点,而我在GOTTA中移动它来制作我的整个MC在一个边界覆盖阶段!这些过于动作互相反对。如果最后一部分不清楚,请让我解释一下:)

在得到LDMS的正确答案后,我更新了这个问题以避免聊天讨论:)

1 个答案:

答案 0 :(得分:0)

您需要做的就是移动或缩放对象,检查以确保它不会超出范围。

因此,如果您创建了一个名为forceBounds的函数,只需在缩放或更改x / y时调用它:

        function forceBounds():void {
            //figure out the bounds to constrain to
            //the x, should be the farthest left it can go without the edge being seen on the right. To get this value just subtract the smaller width (stage) from the larger width (mc) - this should be a negative number
            var bounds:Rectangle = (stage.stageWidth - mc.width, stage.stageHeight - mc.height, mc.width - stage.stageWidth, mc.height - stage.stageHeight);

            if (mc.x > bounds.x + bounds.width) {
                mc.x = bounds.x + bounds.width;
            }
            else if (mc.x < bounds.x) {
                mc.x= bounds.x;
            }

            if (mc.y > bounds.y + bounds.height) {
                mc.y = bounds.y + bounds.height;
            }
            else if (mc.y < bounds.y) {
                mc.y = bounds.y;
            }
        }

以下是我在FlashPro中创建的完整示例:(舞台上的对象实例名称为mc,大于舞台边界。

缩放代码取自FlashAndMath.com

import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.events.TransformGestureEvent;
import fl.motion.MatrixTransformer;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.events.GesturePhase;

Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener(TransformGestureEvent.GESTURE_PAN, onPan);
stage.addEventListener(TransformGestureEvent.GESTURE_ZOOM, onZoom);

forceBounds();

function onPan(e:TransformGestureEvent):void {
    trace("PAN");
    if(e.phase == GesturePhase.BEGIN){
        stage.removeEventListener(TransformGestureEvent.GESTURE_ZOOM, onZoom);
    }

    //localToGlobal is a helper method that converts a point to global coordinates
    var p:Point = DisplayObject(e.target).localToGlobal(new Point(e.offsetX, e.offsetY));
    //conversely, global to local does the opposite
    p = mc.globalToLocal(p);

    mc.x = p.x;
    mc.y = p.y;

    forceBounds();

    if(e.phase == GesturePhase.END){
        stage.addEventListener(TransformGestureEvent.GESTURE_ZOOM, onZoom);
    }
}

function onZoom(event:TransformGestureEvent):void {
    trace("ZOOM");
    var container:MovieClip = mc;
    var locX:Number=event.localX;
    var locY:Number=event.localY;
    var stX:Number=event.stageX;
    var stY:Number=event.stageY;
    var prevScale:Number=container.scaleX;
    var mat:Matrix;
    var externalPoint=new Point(stX,stY);
    var internalPoint=new Point(locX,locY);

    container.scaleX *= (event.scaleX + event.scaleY) * .5;

    if(event.scaleX > 1 && container.scaleX > 6){
        container.scaleX=prevScale;
    }
    if(event.scaleY > 1 && container.scaleY > 6){
        container.scaleX=prevScale;
    }
    if(event.scaleX < 1 && container.scaleX < 0.8){
        container.scaleX=prevScale;
    }
    if(event.scaleY < 1 && container.scaleY < 0.8){
        container.scaleX=prevScale;
    }

    if(container.scaleX < 1) container.scaleX = 1;
    if(container.scaleX > 1.5) container.scaleX = 1.5;
    container.scaleY = container.scaleX;

    mat=container.transform.matrix.clone();
    MatrixTransformer.matchInternalPointWithExternal(mat,internalPoint,externalPoint);
    container.transform.matrix=mat;

    forceBounds();
}

function forceBounds():void {
    //figure out the bounds to constrain to
    //the x, should be the farthest left it can go without the edge being seen on the right. To get this value just subtract the smaller width (stage) from the larger width (mc) - this should be a negative number
    var bounds:Rectangle = new Rectangle(stage.stageWidth - mc.width, stage.stageHeight - mc.height, mc.width - stage.stageWidth, mc.height - stage.stageHeight);

    if (mc.x > bounds.x + bounds.width) {
        mc.x = bounds.x + bounds.width;
    }
    else if (mc.x < bounds.x) {
        mc.x= bounds.x;
    }

    if (mc.y > bounds.y + bounds.height) {
        mc.y = bounds.y + bounds.height;
    }
    else if (mc.y < bounds.y) {
        mc.y = bounds.y;
    }
}