CAShapeLayer 动画路径毛刺/闪烁(从椭圆到矩形并返回)

Posted

技术标签:

【中文标题】CAShapeLayer 动画路径毛刺/闪烁(从椭圆到矩形并返回)【英文标题】:CAShapeLayer Animating Path Glitches / Flickers (From Ellipse to Rect and back) 【发布时间】:2012-03-01 08:43:55 【问题描述】:

当我创建显式动画以将 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

【问题讨论】:

【参考方案1】:

我收到了来自quartz-dev 列表的反馈:

大卫·邓肯写道:

只有在以下情况下才能保证为形状图层的路径设置动画 你正在从喜欢到喜欢制作动画。一个矩形是一个序列 线,而椭圆是一系列弧(你可以看到 使用 CGPathApply 生成的序列),以及动画 不能保证它们之间看起来非常好,或者根本不能很好地工作。

要做到这一点,您基本上必须通过以下方式创建一个矩形的模拟 使用与创建椭圆相同的曲线,但 带有会导致渲染看起来像的参数 长方形。这应该不会太难(同样,您可以使用 您在创建的路径上从 CGPathApply 获得什么 CGPathAddEllipseInRect 作为指导),但可能需要一些 调整到正确。

【讨论】:

【参考方案2】:

不幸的是,这是对 CAShapeLayers 原本很棒的动画路径属性的限制。

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

您可以尝试通过将椭圆绘制为 4 条曲线而不是单个椭圆来尽量减少影响,但这仍然不太正确。我还没有找到一种从曲线平滑到多边形的方法。

您可能能够到达那里的大部分内容,然后为最后一部分转移到淡入淡出动画 - 不过这看起来不太好。

【讨论】:

在您的回答和我从 David Duncan 那里发布的回答之间,我对发生的事情有了很好的了解。希望动画路径属性在未来的版本中变得更好。 如果您确实使用圆弧矩形方法解决了问题,请在此处发布! 我不知道你是否在这方面工作过,或者自从发表这篇文章以来看到任何好的答案。我开始研究一般的圆形到多边形动画,目前它正在用于圆形到方形的动画。我已经发布了该代码作为这个问题的答案,***.com/questions/28437014/… @rdelmar 不,我有一段时间没有研究这个了。它应该比现在更容易......

以上是关于CAShapeLayer 动画路径毛刺/闪烁(从椭圆到矩形并返回)的主要内容,如果未能解决你的问题,请参考以下文章

CAShapeLayer 动画无需更新路径

CAShapeLayer 路径动画——缩小圆

CAShapeLayer 路径动画

如何为 CAShapeLayer 路径和填充颜色设置动画

我正在为填充但未描边的 CAShapeLayer 的路径值设置动画,我想让它的动画更流畅

贝塞尔曲线与CAShapeLayer的关系以及Stroke动画