2011-10-27 54 views
0

我創建了一個mc,它用作我的地圖和控件,以便使地圖可以四處移動,並將關鍵點導航到並放大在不同的縮放級別。Flash AS3 - 如何在縮放後的某個點周圍圍繞對象

我使用scaleX和scaleY來縮放地圖mc和x和y位置列表,以正確定位每個關鍵點的地圖。

當我想去的特定區域我執行此計算(OFFSETX和OFFSETY在屏幕的中心):

newX = posX * scale + offsetX; 
newY = posY * scale + offsetY; 

然後我吐溫順利縮放地圖的位置和規模和將地圖移動到正確的位置:

var tween = new TweenLite(_background, EASING_SPEED, {x:newX, y:newY,scaleX:scale.getScale(),scaleY:scale,ease:EASING_TYPE,onComplete:moveToComplete,onCompleteParams:[room]}); 

我現在需要實現放大/縮小功能,這就是我與掙扎。變焦應使用屏幕作爲REG點規模的中心,所以我一直在想沿着以下線的東西,以獲得正確的定位:

var newX = offsetX - (offsetX - _background.x) * scale; 
var newY = offsetY - (offsetY - _background.y) * scale; 

所以在我的腦海裏這得到距離地圖當前位置相對於屏幕中心點的距離(offsetX,offsetY),然後按照新比例縮放該距離。

但是,這顯然是錯誤的,因爲它不工作,地圖的定位是錯誤的。

我也嘗試過使用變換矩陣來得到正確的值,但我對它們的瞭解甚少,沒有得到正確的結果。

function scale(target:MovieClip, center:Point, scale:Number):Point { 
    var m:Matrix = new Matrix(); 
    m.translate(-center.x, -center.y);//move the center into (0,0) 
    m.scale(scale, scale);//scale relatively to (0,0) (which is where our center is now) 
    m.translate(center.x, center.y);//move the center back to its original position 
    return m.transformPoint(new Point());//transform (0,0) using the whole transformation matrix to calculate the destination of the upper left corner 
} 

如果有人可以指出我要出錯的地方,我會非常感激!

回答

2

我有一個類似的問題,我想要圖像在圖像中心旋轉時,我改變了圖像旋轉,而是圖像會圍繞0,0點旋轉。

在這兩種情況下(您的和我的)都有兩種解決方法。
第一種方法是在縮放比例更改時將其設置爲數學。

var newX = stage.width/2 - _background.width/2 
var newY = stage.height/2- _background.height/2 

曾經加載的另一種方式不需要額外的代碼。
在該movieclip中的_background中添加另一個movieClip,該圖像將會去。 該圖像的中心點位於0,0點,而不是圖像的頂部爲0,0。 所以基本上

image.x = -(image.width/2) 
image.y = -(image.height/2) 

這將會對圖像的縮放和旋轉上的所有圖像的中心定位工作。

[編輯]
好的,你需要做的是開始一個新的項目,並創建類似這個圖。
enter image description here

放入容器中的movieclip
的圖像的圖像和容器將具有相同的高度和寬度
移動圖像,使得它的中心是在0,0點了MovieClip
的把容器放在舞臺上。 單擊事件上的2個按鈕添加.1另一個按鈕將.1減去容器上的刻度。
現在運行測試
正如你可以看到scaleing在圖像
上居中現在對於測試2打開容器並拖動圖像更左 再次運行測試。
您會看到圖像現在縮放到中間的右側(與拖動位置相反)。

所以總結起來偏移量是從圖像的中心逆運動(+ 2分,如果你明白一個)

image.x = -(image.width/2) - offsetX 
image.y = -(image.height/2) - offsetY 


注:比例將適用於容器不是圖像直接在那裏作爲圖像移動仍然會image.x和image.y

+0

感謝您的迴應The_asMan,如果我錯了,請糾正我的錯誤,但這種解決方案只能讓我放大和縮小圖像的中心,而不是屏幕中心的圖像中的點? –

+0

確定它可以根據你的偏移量 –

+0

好好調整。我很努力地看到如何在計算中實現這一點,請您詳細說明第一點問題嗎? –

1

縮放對象時,焦點應保持相同的座標。由於您要縮放對象,因此應該根據地圖大小使用此點的座標。

由於該點保持在同一階段位置,因此應該可以計算相對於該固定值的地圖座標。

//Pseudo Code 
    // the point you want to zoom in 
    // Record Mouse Click Coordinates , store in variable 
    var origin:Point = new Point (mouseX , mouseY); 

    //calculate these coordinates as percentage of 
    //the map's width & height 
    //store in variable 
    var percent:Object = { x% , y%} 

    //during scaling, calculate the point's 
    //position using the "percent" values and 
    //tween back to original (var origin) position 

好了,我還沒有試過,但是這將是我的第一種方法:)

希望它能幫助!

假設您的地圖以1:1的比例爲800x400。該中心將在(400,200)。 如果您縮放地圖,比方說1600x800,則中心點將移至(800,400)。然後,您需要補間地圖才能將該點恢復到(400,200),這將有效地給出中心點保持不變的印象。

我給你的例子是基於「放大」點變量的想法,無論鼠標點擊什麼地方,例如。如果不是,那麼你應該簡單地將你的註冊點移動到中心:)

+0

感謝您的回覆Patrick。由於這種情況下的原點是屏幕的中心,並且地圖與屏幕初始爲1:1的比例,因此百分比對象的值將爲{50%,50%},我不太確定如何操作接下來的一點,你能否詳細說明一下? –

4
function scaleAroundPoint (object:DisplayObject, offsetX:Number, offsetY:Number, absScaleX:Number, absScaleY:Number):void { 
    var relScaleX:Number = absScaleX/object.scaleX; 
    var relScaleY:Number = absScaleY/object.scaleY; 
    var AC:Point = new Point(offsetX, offsetY); 
    AC = object.localToGlobal(AC); 
    AC = object.parent.globalToLocal(AC); 
    var AB:Point = new Point(object.x, object.y); 
    var CB:Point = AB.subtract(AC); 
    CB.x *= relScaleX; 
    CB.y *= relScaleY; 
    AB = AC.add(CB); 
    object.scaleX *= relScaleX; 
    object.scaleY *= relScaleY; 
    object.x = AB.x; 
    object.y = AB.y; 
} 

http://timwhitlock.info/blog/2008/04/13/scale-rotate-around-an-arbitrary-centre/

上述功能的

用例:

var currentScale:Number = 1; 
mc.addEventListener(MouseEvent.CLICK, onClick); 

function onClick (e:MouseEvent):void { 
    var point:Point = new Point(e.localX, e.localY); 
    currentScale += .1; 
    scaleAroundPoint(mc, point.x, point.y, currentScale, currentScale); 
} 
0

的人,我認爲這只是一個數學問題。您可以在動畫中同時更改x,y位置:

public function FadeInWithGrowth(_obj:*, _timeSec:Number=DEFAULT_TIMESEC_FADE_IN, _ease:Ease=null):void{ 
     var _endAlpha:int = _obj.alpha; 
     var _startScaleX:int = _obj.scaleX/2; 
     var _startScaleY:int = _obj.scaleY/2; 
     var _endScaleX:int = _obj.scaleX; 
     var _endScaleY:int = _obj.scaleY; 
     var _startX:int = _obj.width/2 -(_startScaleX*_obj.width/2); 
     var _startY:int = _obj.height/2 -(_startScaleY*_obj.height/2); 
     var _endX:int = _obj.x; 
     var _endY:int = _obj.y; 
     _ease = _ease ? _ease : Back.easeOut; 
     //Para que o scale ocorra centralizado e não a partir do topo 
     TweenMax.fromTo(_obj, DEFAULT_TIMESEC_FADE_IN, 
      {alpha:0, scaleX:_startScaleX, scaleY:_startScaleY, x:_startX, y:_startY}, 
      {alpha:_endAlpha, scaleX:_endScaleX, scaleY:_endScaleY, x:_endX, y:_endY, ease:_ease} 
     ); 
    }