Actionscript 3 ActionScript 3的缩放和滚动问题

Actionscript 3 ActionScript 3的缩放和滚动问题,actionscript-3,flash,actionscript,Actionscript 3,Flash,Actionscript,我正在使用TransformGestureEvent和StartDrag以及StopDrag事件,我遇到了一些问题 我会尽我最大的努力解释,当我放大时,我的图像会放大,并在放大时居中。放大后,我开始拖动到图像的顶部,当我到达顶部时,我现在无法再滚动(到目前为止,一切正常),但当我要缩小图像时,我的图像y轴不再位于顶部,我的图像应该位于空白处 这是我的密码: mapMC.addEventListener(TransformGestureEvent.GESTURE_ZOOM, zoom); mapM

我正在使用TransformGestureEvent和StartDrag以及StopDrag事件,我遇到了一些问题

我会尽我最大的努力解释,当我放大时,我的图像会放大,并在放大时居中。放大后,我开始拖动到图像的顶部,当我到达顶部时,我现在无法再滚动(到目前为止,一切正常),但当我要缩小图像时,我的图像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();
}
这里有一个链接到一个示例项目,它将向您展示我的意思


由于内置的Air触摸手势在这方面不是很方便,我已经使用
多点触摸模式实现了一个自制的缩放功能

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)
}
导入flash.events.Event;
导入flash.geom.Rectangle;
导入flash.events.MouseEvent;
导入flash.ui.multi-touchinputmode;
导入flash.events.TouchEvent;
导入flash.geom.Point;
//瓦尔斯
变量接触点:数组=[]
var touch_模式:字符串=null
var touch_起点:点
变量映射\u开始:点
变量映射\缩放:数字
变量映射\u宽度:数字
变量映射高度:数字
var zoom_StartList:编号
//配置
var max_缩放:数字=6
变量最小值缩放:数字=1
var map_bounds:Rectangle=new Rectangle(0,0,mapMC.width,mapMC.height)//这定义了映射应该适合的区域
//允许触摸手势
Multitouch.inputMode=MultitouchInputMode.TOUCH\u点;
//缩放和拖动事件侦听器
stage.addEventListener(TouchEvent.TOUCH\u BEGIN,touchBegin)
stage.addEventListener(TouchEvent.TOUCH\u MOVE,touchMoved)
stage.addEventListener(TouchEvent.TOUCH_END,touchEnd)
//触摸处理器
函数touchBegin(e:TouchEvent){
if(接触点。长度平移)
startPan()
}else如果(touchpoints.length==2){//2 touchpoints=>缩放
startZoom()
}
}
函数startPan(){
触摸屏模式=‘平移’
touch_start=新点(接触点[0].x,接触点[0].y)
map_start=新点(mapMC.x,mapMC.y)
}
函数startZoom(){
触摸屏模式=‘缩放’
touch_start=getZoomCenter()
zoom_startdist=getZoomDist()
map_start=新点(mapMC.x,mapMC.y)
map\u zoom=mapMC.scaleX
map_width=mapMC.width
地图高度=地图高度
}
函数touchpointMoved(){
开关(触摸模式){
“潘”案:
mapMC.x=map\u start.x+触点[0]。x-touch\u start.x
mapMC.y=map\u start.y+触点[0]。y-touch\u start.y
打破
“缩放”案例:
var current_scale:Number=map_zoom*getZoomFactor()//获取当前缩放因子(相对于上一次地图缩放)
当前缩放=数学.min(最大缩放,数学.max(最小缩放,当前缩放))//限制缩放(定义见->配置)
mapMC.scaleX=mapMC.scaleY=current\u比例
//将贴图位置设置为当前缩放中心
var zoom_pos:Point=getZoomCenter()
mapMC.x=map\u start.x+zoom\u pos.x-触摸\u start.x
mapMC.y=map\u start.y+zoom\u pos.y-触摸\u start.y
//有关缩放的正确地图位置
mapMC.x+=-(当前地图缩放)*地图宽度*((触摸地图开始.x地图开始.x)/地图宽度)/地图缩放
mapMC.y+=-(当前缩放贴图缩放)*贴图高度*((触摸开始.y-map开始.y)/贴图高度)/贴图缩放
打破
}
//确保地图没有离开其定义的区域-请参阅配置(地图边界)
if(mapMC.x>map_bounds.x)
mapMC.x=map_bounds.x
else if(mapMC.x+mapMC.widthmap_bounds.y)
mapMC.y=map_bounds.y

否则,如果(mapMC.y+mapMC.heights),您希望贴图保持比例,还是可以独立于y轴缩放x轴?
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)
}