两个 CGPaths / UIBeziers 之间的补间 / 插值
Posted
技术标签:
【中文标题】两个 CGPaths / UIBeziers 之间的补间 / 插值【英文标题】:Tweening / Interpolating between two CGPaths / UIBeziers 【发布时间】:2013-08-22 08:58:35 【问题描述】:我有一个包含 CGPath 的 CAShapeLayer。使用 ios 的内置动画,我可以使用动画轻松地将这条路径变形为另一条路径:
CABasicAnimation *morph = [CABasicAnimation animationWithKeyPath:@"path"];
morph.fromValue = (id)myLayer.path;
mayLayer.path = [self getNewPath];
morph.toValue = (id)myLayer.path;
morph.duration = 0.3;
[myLayer addAnimation:morph forKey:nil];
效果很好。
但是,我现在想在拖动操作期间在这些路径之间逐渐变形。为了做到这一点,我需要能够在拖动过程中的任何时候检索插值路径。有没有办法向 iOS 询问这个?
【问题讨论】:
在不平凡的情况下,内置的路径变形很快就会变得毫无用处。请参阅此处描述的问题和解释:***.com/a/17864445/438982 确实如此,但就我而言,变形看起来不错... 【参考方案1】:这实际上比您首先想到的要简单得多,并且使用“无”速度(暂停)的动画。现在,将暂停的动画添加到图层后,您可以更改时间偏移以跳转到动画中的特定时间。
如果您不打算自己运行动画(即仅手动控制它),我建议您将动画的持续时间更改为 1。这意味着您将时间偏移从 0 更改为 1 从0% 到 100%。如果您的持续时间为 0.3(如您的示例中所示),那么您可以将时间偏移设置为 0 到 0.3 之间的值。
实施
正如我上面所说,这个小技巧涉及的代码很少。
-
(可选)将持续时间设置为 1.0
将图层的
speed
(是的,它们符合CAMediaTiming
)或动画设置为0.0
在拖动手势或滑块期间(如我的示例)设置图层或动画的timeOffset
(取决于您在第 2 步中所做的操作)。
这就是我配置动画 + 形状层的方式
CABasicAnimation *morph = [CABasicAnimation animationWithKeyPath:@"path"];
morph.duration = 1.; // Step 1
morph.fromValue = (__bridge id)fromPath;
morph.toValue = (__bridge id)toPath;
[self.shapeLayer addAnimation:morph forKey:@"morph shape back and forth"];
self.shapeLayer.speed = 0.0; // Step 2
还有滑块动作:
- (IBAction)sliderChanged:(UISlider *)sender
self.shapeLayer.timeOffset = sender.value; // Step 3
您可以在下面看到最终结果。编码愉快!
【讨论】:
太棒了,谢谢。我不知道 timeOffset 的存在。如果您打算单独使用动画,您会怎么做? @tarmes 这取决于交互的细节。您仍然可以暂停动画并更改时间偏移(在这种情况下从 0 到 0.3)。您可以通过再次将速度设置回 1 来恢复动画。如果动画在您想要与之交互时正在运行,那么您可以使用[layer convertTime:CACurrentMediaTime() fromLayer:nil]
获取当前值。请参阅this answer 了解更多信息。
这个伟大的技术启发了我做一个带有 ►(播放)或 ❚❚(暂停)图标的按钮,可以很好地在两者之间变形。查看实际操作:instagram.com/p/l6a8uDHDk7 这是来源:gist.github.com/raphaelschaad/9734463
@DavidRönnqvist,我在我的代码上实现了你的答案..但它不起作用.. CABasicAnimation *morph = [CABasicAnimation animationWithKeyPath:@"path"]; morph.duration = 1.0; // 第一步 morph.fromValue = [NSValue valueWithCGPoint: CGPointMake([cell.imgView center].x - 5.0f, [cell.imgView center].y)]; morph.toValue = [NSValue valueWithCGPoint: CGPointMake([cell.imgView center].x + 5.0f, [cell.imgView center].y)]; // [cell.imgView.layer addAnimation:morph forKey:@"来回变形形状"];
@user 这真是一个新问题。也就是说,您正在为路径设置动画,但添加 points 作为 to 值和 from 值。以上是关于两个 CGPaths / UIBeziers 之间的补间 / 插值的主要内容,如果未能解决你的问题,请参考以下文章
使用 CGPaths 和 CAShapeLayers 动画绘制字母