CoreAnimation图层并非都以相同的速度移动:我缺少什么?

时间:2011-10-10 20:57:34

标签: core-animation timing

我有一个CALayers的应用,它从屏幕的一侧移动到另一侧。我试图让时间正确,以便他们都花费同样的时间从第一面传递到我决定的任意分隔符(靠近另一边),然后继续他们的运行从屏幕上消失。

这是我的意思的一个例子:

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 个答案:

答案 0 :(得分: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);