2017-08-05 147 views
4

我正在使用TransformGestureEvent和StartDrag和StopDrag事件,並遇到一些問題。ActionScript 3縮放和滾動問題

我會盡我所能解釋,當我放大時,我的圖像放大,並在放大時居中。放大後,我開始拖到圖像的頂部,當我到達頂部時,我現在不能滾動更多(所有內容都按預期工作到目前爲止),但是當我縮小圖像時,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

+0

你想讓地圖保持比例,還是應該可以獨立於y軸縮放X軸? –

回答

2

由於空氣的內置觸摸手勢是不是這個非常方便,我已經實現了使用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) 
} 

讓我知道如果有什麼不清楚,我會嘗試添加更多評論。

+0

這是驚人的代碼,它的完美 – user979331