2011-10-10 33 views
0

我有一個應用程序CALayers從屏幕的一側移動到另一側。我試圖讓時機正確,以便他們都將相同時間從第一方傳遞到我已經決定的任意分隔符(靠近另一端),然後繼續運行以從屏幕消失。CoreAnimation圖層並非都以相同的速度移動:我錯過了什麼?

這裏是我的意思的例子:

visual description of my problem

兩個箱子應該以相同的速度移動(動畫具有線性時間),所以當小盒子打的分隔符,間隙小兩者應該是一樣的。

不過,我更願意看到這一點:

visual description of what happens

用言語來表達,看來我的大箱子被移動比小盒子快。

這是我的代碼的相關部分。我決定以每秒像素爲單位的速度,然後考慮盒子必須行進的像素數量來設置動畫的持續時間。

const CGRect viewBounds = CGRectMake(0,0, 500, 400); 
const CGFloat distanceToCross = viewBounds.size.width - delimiterX; 
const CFTimeInterval timeToCross = 5; 
const CGFloat pixelsPerSecond = distanceToCross/timeToCross; 

const CGFloat y = /* y coordinate of the box */; 
CALayer* box = [CALayer layer]; 
// the layer should lie outside the viewport at first 
box.frame = CGRectMake(viewBounds.size.width, y, /* size here */); 
box.anchorPoint = CGPointMake(0, 0.5); 
// snip 

[CATransaction begin]; 
CATransaction.animationTimingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
CATransaction.animationDuration = (viewBounds.size.width + box.frame.size.width)/pixelsPerSecond; 
// and the layer should cross the viewport to outside of it, too 
box.position = CGPointMake(-box.frame.size.width, y); 
[CATransaction commit]; 

這不是我的圖形示例所示,但同樣大小的箱子都去以同樣的速度,所以很明顯我做錯了我的時間計算。我錯過了什麼?

回答

1

CALayer.position,默認情況下,表示方塊的中心點。因此,每個框的結尾框架實際上已經超過了您想要的點數,並且其結果的數量取決於框的大小。這是因爲你的持續時間是基於錯誤的距離,所以會推遲你的計算。我很驚訝你沒有注意到你的箱子在移動時略微向下漂移,因爲y座標同時用於frame.origin.yposition.y

一個簡單的解決方法是採取框架的中點。你可以做這樣的事情

CGFrame newFrame = (CGRect){{-box.frame.size.width, y}, box.frame.size}; 
box.position = CGPointMake(CGRectGetMidX(newFrame), CGRectGetMidY(newFrame)); 

或者使其在anchorPoint變化面前彈性做到這一點,你可以使用類似

box.position = CGPointMake(-box.frame.size.width + box.frame.size.width*box.anchorPoint.x, y + box.frame.size.height*box.anchorPoint.y); 
+0

我忘了提,但我設置了'anchorPoint'屬性改爲'{0,0.5}',所以沿X軸的距離應該是正確的。此外,我非常確定'anchorPoint'不會影響到旅行的距離,除非在中途改變,因爲起點將以與終點相同的方式受到影響。 – zneak

+0

起始點是使用'frame'定義的,而不是'position',而'frame'已經隱式地考慮了'anchorPoint'。 –

+0

@zneak:你可以嘗試在末尾設置'frame'而不是'position',看看是否有所作爲。 'CALayer'文檔'frame'不是直接可以動畫的,但我認爲它仍然支持隱式動畫(通過修改「bounds' /'position'屬性)。 –