CAShapeLayer 动画路径出现问题 / 闪烁(从椭圆形到矩形再返回)

8

当我创建一个显式动画,将CAShapeLayer的路径从椭圆形更改为矩形时,出现了问题。

在我的画布控制器中,我设置了一个基本的CAShapeLayer并将其添加到根视图的图层中:

CAShapeLayer *aLayer;
aLayer = [CAShapeLayer layer];
aLayer.frame = CGRectMake(100, 100, 100, 100);
aLayer.path = CGPathCreateWithEllipseInRect(aLayer.frame, nil);
aLayer.lineWidth = 10.0f;
aLayer.strokeColor = [UIColor blackColor].CGColor;
aLayer.fillColor = [UIColor clearColor].CGColor;
[self.view.layer addSublayer:aLayer];

然后,当我对路径进行动画处理时,在动画的最后几帧中出现了奇怪的闪烁/闪烁问题,此时形状变为矩形,在从矩形动画消失时的前几帧也有相同的问题。 动画的设置如下:

CGPathRef newPath = CGPathCreateWithRect(aLayer.frame, nil);
[CATransaction lock];
[CATransaction begin];
[CATransaction setAnimationDuration:5.0f];
CABasicAnimation *ba = [CABasicAnimation animationWithKeyPath:@"path"];
ba.autoreverses = YES;
ba.fillMode = kCAFillModeForwards;
ba.repeatCount = HUGE_VALF;
ba.fromValue = (id)aLayer.path;
ba.toValue = (__bridge id)newPath;
[aLayer addAnimation:ba forKey:@"animatePath"];
[CATransaction commit];
[CATransaction unlock];

我尝试了很多不同的方法,比如锁定/解锁CATransaction,调整各种填充模式等...

这里是故障的图像: http://www.postfl.com/outgoing/renderingglitch.png

我遇到的问题视频可以在此找到: http://vimeo.com/37720876

2个回答

8
我从quartz-dev列表收到了这个反馈:
David Duncan写道:
动画化形状层的路径只有在从相似形状到相似形状的动画时才能保证正常工作。矩形是一系列线段,而椭圆是一系列弧线(您可以使用CGPathApply查看生成的序列),因此它们之间的动画效果不一定很好,甚至可能无法正常工作。
要实现这一点,您基本上必须通过使用创建椭圆所使用的相同曲线来创建矩形的类比,但使用会使渲染看起来像矩形的参数。这应该不太困难(再次,您可以使用使用CGPathAddEllipseInRect创建的路径上获得的CGPathApply作为指南),但可能需要一些微调才能做到正确。

5

不幸的是,这是CAShapeLayers中本来很棒的animatable path属性的局限性。

基本上它试图在两个路径之间进行插值。当目标路径和起始路径具有不同数量的控制点时,它会遇到麻烦-曲线和直线边缘都会有这个问题。

您可以尝试将椭圆绘制为4个曲线而不是一个单独的椭圆,但仍然不太正确。我还没有找到从曲线平滑地转换到多边形的方法。

您可能能够实现大部分效果,然后在最后一个部分转换为淡入动画-虽然这不会看起来很好。


在你的回答和David Duncan发布的回答之间,我对情况有了相当好的了解。希望在未来的版本中,可动画化路径属性会变得更好。 - C4 - Travis
如果您使用弧矩形方法解决了问题,请在此处发布! - jrturton
我不知道你是否在这个帖子发布后有过相关经验或看到过一些好的答案。我正在着手开发一个通用的圆形转多边形动画,目前已经实现了圆形转正方形的动画效果。我已经将代码作为回答发布在这个问题的链接中:https://dev59.com/5Ifca4cB1Zd3GeqPmrvW#28448397 - rdelmar
@rdelmar,我已经有一段时间没有处理这个了。它应该比现在容易... - jrturton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接