我有一个CALayers
的应用,它从屏幕的一侧移动到另一侧。我试图让时间正确,以便他们都花费同样的时间从第一面传递到我决定的任意分隔符(靠近另一边),然后继续他们的运行从屏幕上消失。
这是我的意思的一个例子:
两个方框都应以相同的速度移动(动画具有线性时序),因此当小方框击中分隔符时,两者之间的小间隙应该相同。
但是,我宁愿看到这个:
用文字表示,似乎我的大盒子比小盒子移动得快。
这是我的代码的相关部分。我决定以每秒像素为单位的速度,然后根据盒子必须行进的像素数设置动画的持续时间。
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];
这在我的图形示例中没有显示,但是相同大小的框都以相同的速度显示,所以显然我的时间计算有问题。我错过了什么?
答案 0 :(得分:1)
CALayer.position
表示框的中心点。因此,每个框的结束框架实际上超过了您想要的点,并且它所经过的数量取决于框的大小。由于您的持续时间是基于错误的距离,因此这会使您的计算失效。我很惊讶你没有发现你的盒子在移动时略微向下漂移,因为y
坐标同时用于frame.origin.y
和position.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);