使用移动框架为 CAShapeLayer 设置动画

Posted

技术标签:

【中文标题】使用移动框架为 CAShapeLayer 设置动画【英文标题】:Animating CAShapeLayer with moving frame 【发布时间】:2011-08-17 09:26:44 【问题描述】:

使用核心动画层,我一直在尝试实现以下功能。在包含超层中,有两个锚层,以及连接两者的另一个层。下图应该可以清楚地说明情况。在左侧,两个橙色锚点分别标记为“A”和“B”,绿线将它们连接起来。封闭层框架使用虚线显示。在右侧,层层次结构显示为我当前实现的那样,其中锚点和连接都是封闭超层的子层。

现在,我要做的是让锚点四处移动,并使连接保持连接状态。我目前正在利用连接层的-setFrame: 方法更新其框架和路径属性,使用如下所示的代码:

- (void)setFrame:(CGRect)frame

CGSize size = frame.size;
CGPoint startPoint = CGPointZero;
if (size.height < 0.0) startPoint.y -= size.height;

CGPathRef oldPath = self.path;
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, startPoint.x, startPoint.y);
CGPathAddLineToPoint(path, NULL, startPoint.x + size.width, startPoint.y + size.height);

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.duration = [CATransaction animationDuration];
animation.timingFunction = [CATransaction animationTimingFunction];
animation.fromValue = (id)oldPath;
animation.toValue = (id)path;
[self addAnimation:animation forKey:@"pathAnimation"];

self.path = path;
CGPathRelease(path);
[super setFrame:frame];

现在,这种方法有效,但问题是帧(或位置 + 边界)动画与路径动画不同步运行,导致连接远端暂时分离(以及其他一些小问题到,大概是由同一个核心问题引起的)。

我一直在玩弄这个问题,但只是为了适度的成功。有一次,我将连接的框架设置为与封闭的超层的框架相同,这确实产生了预期的效果(因为现在框架不再需要动画了)。但是,我担心此解决方案在具有多个连接的上下文中的性能 - 即。多个不透明的大尺寸重叠层似乎不好?

有人对此有更好、更优雅的解决方案吗?谢谢!

【问题讨论】:

【参考方案1】:

由于您只是真正拉伸(缩放)和旋转连接层,您是否考虑过对其应用转换而不是手动修改框架?

您应该能够使用基于锚层位置的一些基本三角函数来计算旋转角度和比例因子。

【讨论】:

嗯,这不会扭曲形状图层的路径,例如。线宽各向异性缩放?请注意,提出的问题已简化,实际上我使用的是贝塞尔曲线路径。 CAShapeLayers 是基于矢量的,所以应该没有失真。它也应该适用于贝塞尔曲线路径。 我会试一试。不过,您能告诉我有关我指出的性能问题的任何信息吗? 我不确定它会如何比较性能,我提到了转换,因为我在没有性能问题的路径中使用了它们。 您的解决方案确实有效,以供将来参考。但是,它仅适用于线性缩放路径时,而我的情况并非如此(例如,我处理锚 B 位于锚 A 左侧或上方的边缘情况不同。)不过,最后,解决方案与我在原始帖子中提到的相似,因为您将形状图层框架设为常量,并且仅触摸形状本身或变换。我仍然很好奇是否还有其他解决方案。【参考方案2】:

由于您是在为路径而不是图层或路径的框架设置动画,因此您将在大约 10 分钟后遇到性能问题。 50 个同步动画。 由于 gpu 加速,只有在操作层隐式动画属性时,您才能获得高性能,因此是它的框架而不是它的内容(例如路径)。

【讨论】:

以上是关于使用移动框架为 CAShapeLayer 设置动画的主要内容,如果未能解决你的问题,请参考以下文章

沿路径设置动画时保持对象朝向某个点

移动尾巴动画

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

CAShapeLayer 路径动画

CAShapeLayer shadowPath 动画。如何防止动画完成时的阴影填充?

从UICollectionView cellForItemAt indexPath为CAShapeLayer动画设置toValue