【问题标题】:Drag panning with zoom on mouseclick location AS3在鼠标单击位置 AS3 上使用缩放拖动平移
【发布时间】:2012-12-13 06:18:25
【问题描述】:

所以,这里的另一篇帖子真的帮助了我之前来自this link! 它让我可以整齐地放大,但我在平移中真正想要的是鼠标拖动(我将使用触摸屏,所以拖动移动很重要)不需要使用 Touch 类,我已经完成了以前用鼠标类拖动事件,发现对我来说更容易。

我的问题是我的整洁缩放与此 MOUSE_MOVE 平移相关联,我想知道一种干净的方法将我的平移更改为拖动事件,并且我的平移仍然没有超出我的图像限制。

bg_mc- 是我移动和缩放的背景图像。

我的代码:

    import com.greensock.*; 
    bg_mc.doubleClickEnabled = true;



    //Variables
    var percX:Number;
    var percY:Number;
    var destX:Number;
    var destY:Number;

    //Image panned and masked
    this.mask = mask_mc;
    stage.addEventListener(MouseEvent.MOUSE_MOVE,mousemove);
    function mousemove(e:MouseEvent) {
        if (mask_mc.hitTestPoint(stage.mouseX,stage.mouseY,false)) {
            if (bg_mc.width>mask_mc.width) {//Avoids Scrolling if image is under mask area width
                percX = mask_mc.mouseX/mask_mc.width;
            }
            if (bg_mc.height>mask_mc.height) {
    //Avoids Scrolling if image is under mask area height
                percY = mask_mc.mouseY/mask_mc.height;
            }
            destX = -(bg_mc.width-mask_mc.width)*percX;
            destY = -(bg_mc.height-mask_mc.height)*percY;
            TweenMax.to(bg_mc,.5,{x:destX,y:destY});
        }
    }
    //Add listeners for the imgLoader movie clip.
    bg_mc.doubleClickEnabled = true;  
    bg_mc.addEventListener(MouseEvent.DOUBLE_CLICK, increaseSize);
    bg_mc.addEventListener(MouseEvent.CLICK, decreaseSize);

    function scaleAroundMouse(objectToScale:DisplayObject, scaleAmount:Number,          
    bounds:Rectangle = null, onComplete:Function = null):TweenLite {
        // scaling will be done relatively
        var relScaleX:Number = scaleAmount / objectToScale.scaleX;
        var relScaleY:Number = scaleAmount / objectToScale.scaleY;
        // map vector to centre point within parent scope

        var scalePoint:Point = objectToScale.localToGlobal( new         
        Point(objectToScale.mouseX, objectToScale.mouseY));
        scalePoint = objectToScale.parent.globalToLocal( scalePoint );
        // current registered postion AB
        var AB:Point = new Point( objectToScale.x, objectToScale.y );
        // CB = AB - scalePoint, objectToScale vector that will scale as it runs from the centre
        var CB:Point = AB.subtract( scalePoint );
        CB.x *= relScaleX;
        CB.y *= relScaleY;
        // recaulate AB, objectToScale will be the adjusted position for the clip
        AB = scalePoint.add( CB );
        // set actual properties

        if(bounds){
         var limits:Rectangle = new Rectangle(
            bounds.x + (bounds.width - (objectToScale.width * relScaleX)),
            bounds.y + (bounds.height - (objectToScale.height * relScaleY)),
            (objectToScale.width * relScaleX) - bounds.width,
            (objectToScale.height * relScaleY) - bounds.height
         );

         if(AB.x < limits.x) AB.x = limits.x;
         if(AB.x > limits.x + limits.width) AB.x = limits.x + limits.width;
         if(AB.y < limits.y) AB.y = limits.y;
         if(AB.y > limits.y + limits.height) AB.y = limits.y + limits.height;       
        }

        return TweenLite.to(objectToScale,1,{onComplete: onComplete, 
    scaleX: scaleAmount, scaleY: scaleAmount, x: AB.x, y: AB.y});
    }


    function increaseSize(event:MouseEvent):void{
        stopMouseMove();
        scaleAroundMouse(bg_mc, 4, null, resumeMouseMove);
    }

    function decreaseSize(event:MouseEvent):void{
        stopMouseMove();
        scaleAroundMouse(bg_mc, 1, null, resumeMouseMove);
    }

    function stopMouseMove():void {
       stage.removeEventListener(MouseEvent.MOUSE_MOVE,mousemove);
    }

    function resumeMouseMove():void {
       stage.addEventListener(MouseEvent.MOUSE_MOVE,mousemove);
    }

我能得到的任何帮助都会很棒!

【问题讨论】:

  • 是的。我很想看看这是否有效!

标签: actionscript-3 flash


【解决方案1】:

在鼠标按下或您想要开始拖动的任何侦听器上,使用 MovieClip.StartDrag() 函数允许拖动,并使用 StopDrag() 停止拖动。

【讨论】:

    【解决方案2】:

    虽然您可以使用内置的 startDrag(或 startTouchDrag)和 stopDrag 方法,但它不能很好地配合您的放大/缩小功能。

        bg_mc.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown); //add the listener to the bg directly
        function mouseDown(e:MouseEvent) {
           // if (mask_mc.hitTestPoint(stage.mouseX,stage.mouseY,false)) {  //this isn't needed if you add the listener directly to bg_mc
           stage.addEventListener(MouseEvent.MOUSE_UP,mouseUp);
           bg_mc.startDrag(false, getBoundsRect());  //see the code below for the getBoundsRect() function
        }
    
        function mouseUp(e:MouseEvent):void {
            bg_mc.stopDrag();
            stage.removeEventListener(MouseEvent.MOUSE_UP,mouseUp);
        }
    

    最好有一个自定义拖动功能,如下所示:

    import com.greensock.*; 
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;
    import flash.events.Event;
    import flash.geom.Point;
    
        bg_mc.doubleClickEnabled = true;
    
        //Variables
        var percX:Number;
        var percY:Number;
        var destX:Number;
        var destY:Number;
    
        //Image panned and masked
        bg_mc.mask = mask_mc;
    
        //this function generates a bounds rectangle that would keep bg_mc edges from going outside of mask_mc area
        function getBoundsRect():Rectangle {
            return new Rectangle((mask_mc.x + mask_mc.width) - bg_mc.width, (mask_mc.y + mask_mc.height) - bg_mc.height, bg_mc.width - mask_mc.width, bg_mc.height - mask_mc.height);
        }
    
        var isZoomed:Boolean = false;  //a var to keep track of whether your zoomed in or out
    
        var isDragging:Boolean = false; //a var to keep track of whether the bg is being dragged
        var tmpMousePoint:Point = new Point(); //this stores the mouse coordinates on the mouse down, to compare later on the mouse up to see if the mouse moved
        var decay:Number = .27; //make this lower for slower drag, make it 1 to turn off a smooth drag all together
        var tmpMouseMoved:Boolean = false; //to keep track on mouse up whether the action was a drag or a click
        var mouseMoveSensitivity:Number = 15; //how far does mouse need to move before you cancel the click event
        var offset:Point = new Point(); //the offset of the initial mouse click relative to bg_mc's  0,0
    
        bg_mc.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown);
        bg_mc.addEventListener(MouseEvent.CLICK,mouseClick, false, 99999); //listen with a higher priority than any other click listeners on bg_mc - this way if it's a drag, you can cancel the click event
    
        function mouseDown(e:Event):void {
                //reset these to default
            isDragging = true;
            tmpMouseMoved = false;
    
            tmpMousePoint.x = mouseX; //capture the current mouse to check later if it moved (so you know the user intended to drag not click)
            tmpMousePoint.y = mouseY;
            offset.x = bg_mc.mouseX;
            offset.y = bg_mc.mouseY;
    
            bg_mc.addEventListener(Event.ENTER_FRAME,bgEnterFrame); //listen every frame until the mouse is released
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
        }
    
        function bgEnterFrame(e:Event):void {
            bg_mc.x += decay * (mouseX - offset.x - bg_mc.x);
            bg_mc.y += decay * (mouseY - offset.y - bg_mc.y);
    
            var bounds:Rectangle = getBoundsRect();
    
            switch(true){
                case (bg_mc.x < bounds.x):
                    bg_mc.x = bounds.x;
                    break;
    
                case (bg_mc.x > bounds.x + bounds.width):
                    bg_mc.x = bounds.x + bounds.width;
            }
    
            switch(true){
                case (bg_mc.y < bounds.y):
                    bg_mc.y = bounds.y;
                    break;
    
                case (bg_mc.y > bounds.y + bounds.height):
                    bg_mc.y = bounds.y + bounds.height;
            }
    
            if(Math.abs(tmpMousePoint.x - mouseX) > mouseMoveSensitivity || Math.abs(tmpMousePoint.y - mouseY) > mouseMoveSensitivity){
                tmpMouseMoved = true;
            }
        }
    
        function mouseUp(e:Event):void {
            isDragging = false;
            //remove listeners
            bg_mc.removeEventListener(Event.ENTER_FRAME,bgEnterFrame);
            stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
        }
    
        function mouseClick(e:MouseEvent):void {
            trace("CLICK cap");
            if(tmpMouseMoved){
                trace("Kill");
                e.stopImmediatePropagation(); //cancel the mouse event
            }
        }
    
    
        //Add listeners for the imgLoader movie clip.
    
        bg_mc.doubleClickEnabled = true;  
        bg_mc.addEventListener(MouseEvent.DOUBLE_CLICK, increaseSize);
        bg_mc.addEventListener(MouseEvent.CLICK, decreaseSize,false,0,true);
    
        function scaleAroundMouse(objectToScale:DisplayObject, scaleAmount:Number,          
        bounds:Rectangle = null, onComplete:Function = null):TweenLite {
            // scaling will be done relatively
            var relScaleX:Number = scaleAmount / objectToScale.scaleX;
            var relScaleY:Number = scaleAmount / objectToScale.scaleY;
            // map vector to centre point within parent scope
    
            var scalePoint:Point = objectToScale.localToGlobal( new         
            Point(objectToScale.mouseX, objectToScale.mouseY));
            scalePoint = objectToScale.parent.globalToLocal( scalePoint );
            // current registered postion AB
            var AB:Point = new Point( objectToScale.x, objectToScale.y );
            // CB = AB - scalePoint, objectToScale vector that will scale as it runs from the centre
            var CB:Point = AB.subtract( scalePoint );
            CB.x *= relScaleX;
            CB.y *= relScaleY;
            // recaulate AB, objectToScale will be the adjusted position for the clip
            AB = scalePoint.add( CB );
            // set actual properties
    
            if(bounds){
             var limits:Rectangle = new Rectangle(
                bounds.x + (bounds.width - (objectToScale.width * relScaleX)),
                bounds.y + (bounds.height - (objectToScale.height * relScaleY)),
                (objectToScale.width * relScaleX) - bounds.width,
                (objectToScale.height * relScaleY) - bounds.height
             );
    
             if(AB.x < limits.x) AB.x = limits.x;
             if(AB.x > limits.x + limits.width) AB.x = limits.x + limits.width;
             if(AB.y < limits.y) AB.y = limits.y;
             if(AB.y > limits.y + limits.height) AB.y = limits.y + limits.height;       
            }
    
            TweenLite.killTweensOf(objectToScale); //need to add this so the click/double click don't compete with each other
            return TweenLite.to(objectToScale,1,{onComplete: onComplete, 
        scaleX: scaleAmount, scaleY: scaleAmount, x: AB.x, y: AB.y});
        }
    
    
        function increaseSize(event:MouseEvent):void{
            if(isZoomed){
                scaleAroundMouse(bg_mc, 4, getBoundsRect());
                isZoomed = false;
            }
        }
    
        function decreaseSize(event:MouseEvent):void{
           if(!isZoomed){
                scaleAroundMouse(bg_mc, 1, getBoundsRect());  
                isZoomed = true;
           } 
        }
    

    【讨论】:

      猜你喜欢
      • 2023-01-25
      • 2011-08-28
      • 1970-01-01
      • 2017-10-22
      • 2017-07-29
      • 1970-01-01
      • 2016-02-28
      • 1970-01-01
      • 2020-05-28
      相关资源
      最近更新 更多