代码之家  ›  专栏  ›  技术社区  ›  user979331

ActionScript 3缩放和滚动问题

  •  4
  • user979331  · 技术社区  · 9 年前

    我会尽力解释,当我放大时,我的图像会放大,并且在放大时居中。放大后,我开始拖动到图像的顶部,当我到达顶部时,我现在无法再滚动(到目前为止,一切都按预期进行),但当我要缩小图像时,我的图像y轴不再位于顶部,我的图像应该位于空白处。

    这是我的代码:

    mapMC.addEventListener(TransformGestureEvent.GESTURE_ZOOM, zoom);
    mapMC.addEventListener(MouseEvent.MOUSE_DOWN, dragStart);
    mapMC.addEventListener(MouseEvent.MOUSE_UP, dragEnd);
    
    //Zooming Method
    
    function zoom (event:TransformGestureEvent):void{
    
        var locX:Number=event.localX;
        var locY:Number=event.localY;
        var stX:Number=event.stageX;
        var stY:Number=event.stageY;
        var prevScaleX:Number=mapMC.scaleX;
        var prevScaleY:Number=mapMC.scaleY;
        var mat:Matrix;
        var externalPoint=new Point(stX,stY);
        var internalPoint=new Point(locX,locY);
    
        mapMC.scaleX *= event.scaleX;
        mapMC.scaleY *= event.scaleY;
    
    
        if(mapMC.scaleX > 6){
            mapMC.scaleX=prevScaleX;
            mapMC.scaleY=prevScaleY;
        }
    
        if(mapMC.scaleY > 6){
            mapMC.scaleX=prevScaleX;
            mapMC.scaleY=prevScaleY;
        }
    
        if(mapMC.scaleX < 1){
            mapMC.scaleX=1;
            mapMC.scaleY=1;
        }
    
        if(mapMC.scaleY < 1){
            mapMC.scaleX=1;
            mapMC.scaleY=1;
        }
    
        mat=mapMC.transform.matrix.clone();
        MatrixTransformer.matchInternalPointWithExternal(mat,internalPoint,externalPoint);
        mapMC.transform.matrix=mat;
    
    }
    
    //Dragging Start Method
    
    function dragStart(e:MouseEvent):void
    {
        mapMC.startDrag(false, new Rectangle(0,0,-mapMC.width + stage.stageWidth, -mapMC.height + stage.stageHeight));
    }
    
    //Dragging Stop Method
    
    function dragEnd(e:MouseEvent):void
    {
        mapMC.stopDrag();
    }
    

    我期望发生的事情是放大中心,能够在我的startDrag中的矩形内滚动,并在中心缩小,而图像的顶部保持在舞台的顶部,图像的左侧保持在舞台的左侧。

    mapMC.y = 0;
    mapMC.x = 0;
    

    下面是一个示例项目的链接,它将向您展示我的意思

    https://drive.google.com/open?id=0B-p_9V3gzZZTcXpQZzI0RU9ZY0k

    1 回复  |  直到 9 年前
        1
  •  2
  •   Manuel Otto    9 年前

    由于内置的触摸手势的空气不是很方便,我实现了一个自制的缩放功能,使用 MultitouchInputMode.TOUCH_POINT .

    import flash.events.Event;
    import flash.geom.Rectangle;
    import flash.events.MouseEvent;
    import flash.ui.MultitouchInputMode;
    import flash.events.TouchEvent;
    import flash.geom.Point;
    
    
    //Vars
    
    var touchpoints:Array = []
    var touch_mode:String = null
    var touch_start:Point
    var map_start:Point
    var map_zoom:Number
    var map_width:Number
    var map_height:Number
    var zoom_startdist:Number
    
    //Config
    
    var max_zoom:Number = 6
    var min_zoom:Number = 1
    var map_bounds:Rectangle = new Rectangle(0,0,mapMC.width,mapMC.height) // this defines the area in which the map should fit
    
    
    //Allow Touch Gestures
    
    Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
    
    //Zoom and Drag Event Listeners
    
    stage.addEventListener(TouchEvent.TOUCH_BEGIN, touchBegin)
    stage.addEventListener(TouchEvent.TOUCH_MOVE, touchMoved)
    stage.addEventListener(TouchEvent.TOUCH_END, touchEnd)
    
    // Touch Handlers
    
    function touchBegin(e:TouchEvent){
        if(touchpoints.length<2){ // only accept 2 active touchpoints, ignore the 3rd,4th,etc
            touchpoints.push({id:e.touchPointID,x:e.stageX,y:e.stageY})
            touchpointsChanged()
        }
    }
    function touchMoved(e:TouchEvent){
        var touchpoint:Object = getTouchPointById(e.touchPointID) // get current touchpoint...
        if(touchpoint){
            // ... and update the position
            touchpoint.x = e.stageX 
            touchpoint.y = e.stageY
            touchpointMoved()
        }
    }
    function touchEnd(e:TouchEvent){
        removeTouchPoint(e.touchPointID)
        touchpointsChanged()
    }
    
    
    
    // Pan & Zoom logic
    
    function touchpointsChanged(){
        if(touchpoints.length==1){ // 1 touch point => panning
            startPan()
        }else if(touchpoints.length==2){ // 2 touch points => zooming
            startZoom()
        }
    }
    
    function startPan(){
        touch_mode = 'pan'
        touch_start = new Point(touchpoints[0].x,touchpoints[0].y)
        map_start = new Point(mapMC.x,mapMC.y)
    }
    
    function startZoom(){
        touch_mode = 'zoom'
        touch_start = getZoomCenter()
        zoom_startdist = getZoomDist()
        map_start = new Point(mapMC.x,mapMC.y)
        map_zoom = mapMC.scaleX
        map_width = mapMC.width
        map_height = mapMC.height
    }
    
    function touchpointMoved(){
        switch(touch_mode){
            case 'pan':
                mapMC.x = map_start.x + touchpoints[0].x - touch_start.x
                mapMC.y = map_start.y + touchpoints[0].y - touch_start.y
            break
            case 'zoom':
                var current_scale:Number = map_zoom*getZoomFactor() // get current zoom factor (relative to the previous zoom of the map)
    
                current_scale = Math.min(max_zoom,Math.max(min_zoom,current_scale)) // limit zoom (as defined in -> Config)
    
                mapMC.scaleX = mapMC.scaleY = current_scale
    
                // Set map position to the current center of zoom
                var zoom_pos:Point = getZoomCenter()
                mapMC.x = map_start.x + zoom_pos.x - touch_start.x
                mapMC.y = map_start.y + zoom_pos.y - touch_start.y
    
                // Correct map position regarding the scaling
                mapMC.x += -(current_scale-map_zoom)*map_width*((touch_start.x-map_start.x)/map_width)/map_zoom
                mapMC.y += -(current_scale-map_zoom)*map_height*((touch_start.y-map_start.y)/map_height)/map_zoom
    
            break
        }
    
        // Make sure the map doesnt leave its defined area - see Config (map_bounds)
        if(mapMC.x>map_bounds.x)
            mapMC.x = map_bounds.x
        else if(mapMC.x+mapMC.width<map_bounds.x+map_bounds.width)
            mapMC.x = map_bounds.x+map_bounds.width-mapMC.width
    
        if(mapMC.y>map_bounds.y)
            mapMC.y = map_bounds.y
        else if(mapMC.y+mapMC.height<map_bounds.y+map_bounds.height)
            mapMC.y = map_bounds.y+map_bounds.height-mapMC.height
    }
    
    
    // Helper functions
    
    function getTouchPointById(id:int):Object{
        for(var i:uint=0;i<touchpoints.length;i++){
            if(touchpoints[i].id==id)
                return touchpoints[i]
        }
        return null
    }
    
    function removeTouchPoint(id:int){
        for(var i:uint=0;i<touchpoints.length;i++){
            if(touchpoints[i].id==id){
                touchpoints.splice(i,1)
                return
            }
        }
    }
    
    function getZoomCenter():Point{
        //get the average of the 2 touchpoints
        return new Point((touchpoints[0].x+touchpoints[1].x)/2,(touchpoints[0].y+touchpoints[1].y)/2)
    }
    function getZoomDist():Number{
        // calculate the distance between the 2 touchpoints
        return getDist(touchpoints[0].x,touchpoints[0].y,touchpoints[1].x,touchpoints[1].y)
    }
    function getZoomFactor():Number{
        // calculate the difference of distance between the 2 touchpoints from when the zoom gesture started
        return getZoomDist()/zoom_startdist
    }
    function getDist(x1:Number,y1:Number,x2:Number,y2:Number){
        // pythagoras, yo
        var deltaX:Number = x2-x1
        var deltaY:Number = y2-y1
        return Math.sqrt(deltaX*deltaX + deltaY*deltaY)
    }
    

    如果有什么不清楚的地方,请告诉我,我会尽量多加评论。