捏一个特定点并缩放整个视图?

时间:2013-01-12 13:24:59

标签: android flex text zoom pinch

我试图为我的移动android项目进行缩放。问题是,我想用两根手指指向一个特定位置并捏它们进行缩放(不只是一个图像,整个活动视图):

private function onGestureZoom(event:TransformGestureEvent):void{
    if(canvas.scaleY.valueOf() >= 1) {
        canvas.scaleX *= event.scaleX;
        canvas.scaleY *= event.scaleY;
    } else {
        canvas.scaleX = 1;
        canvas.scaleY = 1;
    }
}

1 个答案:

答案 0 :(得分:0)

这个答案包括我编写的两个(感兴趣的)类,有助于抽象问题以重用某些功能。我在这里也包含了ToolBase,尽管理解这个问题并不重要。基本上MultiTouchTool.as设置为捕获TouchEvents并在对象中跟踪它们,它还根据我需要知道的一些常见操作调用一些方法(我只是扩展这个类并覆盖我想要的方法)挂钩)。

然后关键元素在NavigatorTool.as中,它使用对象原始变换矩阵并调整平移然后进行缩放然后重新调整平移。这有效地改变了注册点。因此图像向上和向左移动,因此两个手指之间的点现在位于左上角,然后图像被缩放并且其位置被重置。由于缩放是以增量方式进行的,因此我不断更新intialDistance(名称可能会产生误导)。

在我的情况下,我正在缩放一个名为layerM的对象,它是一个Sprite,但任何DisplayObject都可以。

[MultiTouchTool.as]

package com.shaunhusain.fingerPainting.tools
{
    import flash.display.Stage;
    import flash.events.TouchEvent;
    import flash.geom.Point;

    public class MultiTouchTool extends ToolBase implements ITool
    {
        protected var pointsTracked:Number = 0;
        protected var ptsTracked:Object;
        public function MultiTouchTool(stage:Stage)
        {
            super(stage);
            ptsTracked = {};
        }

        public function takeAction(event:TouchEvent=null):void
        {
            switch(event.type)
            {
                case TouchEvent.TOUCH_BEGIN:
                    ptsTracked[event.touchPointID] =  new Point(event.stageX, event.stageY);
                    pointsTracked++;
                    if(pointsTracked>1)
                        secondFingerDown();
                    break;

                case TouchEvent.TOUCH_MOVE:
                    switch(pointsTracked)
                    {
                        case 1:
                            oneFingerMoving(event);
                            break;
                        case 2:
                            twoFingersMoving(event);
                            break;

                    }
                    ptsTracked[event.touchPointID] =  new Point(event.stageX, event.stageY);
                    break;

                case TouchEvent.TOUCH_END:
                case TouchEvent.TOUCH_ROLL_OUT:
                    switch(pointsTracked)
                    {
                        case 1:
                            oneFingerEnd();
                            break;
                        case 2:
                            twoFingerEnd();
                            break;
                    }


                    ptsTracked[event.touchPointID] = null;
                    pointsTracked--;
                    if(pointsTracked<0)
                        pointsTracked = 0;
                    break;
            }
        }

        protected function oneFingerEnd():void
        {
            trace("default handler for one finger end, not overridden");
        }
        protected function twoFingerEnd():void
        {
            trace("default handler for two finger end, not overridden");
        }
        protected function oneFingerMoving(event:TouchEvent):void
        {
            trace("default handler for one finger moving, not overridden");
        }
        protected function twoFingersMoving(event:TouchEvent):void
        {
            trace("default handler for two fingers moving, not overridden");
        }
        protected function secondFingerDown():void
        {
            trace("default handler for second finger down, not overridden");
        }

        public function toString():String
        {
            return "Multi-Touch tool";
        }
    }
}

[NavigatorTool.as]

package com.shaunhusain.fingerPainting.tools 
{
    import flash.display.Stage;
    import flash.events.TouchEvent;
    import flash.geom.Matrix;
    import flash.geom.Point;

    /**
     * Allows the layer manager to be panned and zoomed on, other tools are
     * responsible for taking into account the current zoom and pan position
     * when modifying the layers.
     */
    public class NavigationTool extends MultiTouchTool implements ITool
    {
        private var initialDistance:Number;
        private var newDistance:Number;
        private var layerLocal:Point;
        //--------------------------------------------------------------------------------
        //              Constructor
        //--------------------------------------------------------------------------------
        public function NavigationTool(stage:Stage)
        {
            super(stage);
        }


        override public function toString():String
        {
            return "Navigation";
        }

        //--------------------------------------------------------------------------------
        //              Overrides
        //--------------------------------------------------------------------------------
        override protected function oneFingerMoving(event:TouchEvent):void
        {
            var currentTouchPrevPos:Point = ptsTracked[event.touchPointID];
            var offset:Point = new Point(event.stageX-currentTouchPrevPos.x,event.stageY-currentTouchPrevPos.y);
            layerM.x += offset.x;
            layerM.y += offset.y;
        }
        override protected function twoFingersMoving(event:TouchEvent):void
        {
            if(isNaN(initialDistance))
            {
                initialDistance = Point.distance(ptsTracked[0],ptsTracked[1]);
                layerLocal = new Point((ptsTracked[0].x+ptsTracked[1].x)/2,(ptsTracked[0].y+ptsTracked[1].y)/2);
            }
            else
            {
                newDistance = Point.distance(ptsTracked[0],ptsTracked[1]);

                var matrix:Matrix = layerM.transform.concatenatedMatrix.clone();

                matrix.tx -= layerLocal.x;
                matrix.ty -= layerLocal.y;
                matrix.scale(newDistance/initialDistance,newDistance/initialDistance);
                matrix.tx += layerLocal.x;
                matrix.ty += layerLocal.y;

                layerM.transform.matrix = matrix;

                initialDistance = newDistance;
            }
        }
        override protected function twoFingerEnd():void
        {
            initialDistance = NaN;
        }

    }
}

[ToolBase.as]

package com.shaunhusain.fingerPainting.tools
{
    import com.shaunhusain.fingerPainting.view.managers.LayerManager;
    import com.shaunhusain.fingerPainting.view.managers.SecondaryPanelManager;
    import com.shaunhusain.fingerPainting.managers.UndoManager;
    import com.shaunhusain.fingerPainting.model.PaintModel;

    import flash.display.Stage;

    /**
     * Base class for tools to give them all easy access to the Singletons and
     * the Stage.
     */
    public class ToolBase
    {
        //--------------------------------------------------------------------------------
        //              Variables
        //--------------------------------------------------------------------------------
        protected var model:PaintModel = PaintModel.getInstance();
        protected var undoManager:UndoManager = UndoManager.getIntance();
        protected var secondaryPanelManager:SecondaryPanelManager = SecondaryPanelManager.getIntance();
        protected var layerM:LayerManager = LayerManager.getIntance();
        protected var stage:Stage;

        //--------------------------------------------------------------------------------
        //              Constructor
        //--------------------------------------------------------------------------------
        public function ToolBase(stage:Stage)
        {
            this.stage = stage;
        }
    }
}