如何沿UIBezierPath动画完整CALayer动画的百分比?

时间:2015-10-05 02:04:32

标签: ios caanimation cakeyframeanimation

我设法沿着UIBezierPath为CALayer制作动画。

我想要完成的是仅为路径的一定百分比设置动画,例如,仅为路径的25%,并且该层保持在该位置(25%)。

这样做的方法是什么?这是我的代码,它总是为完整路径设置动画。

let aPath = UIBizierPath(CGPath: somePath)
let anim = CAKeyframeAnimation(keyPath: "position")
anim.path = aPath.CGPath
anim.rotationMode = kCAAnimationRotateAuto
anim.repeatCount = 1
anim.fillMode = kCAFillModeForwards
anim.removedOnCompletion = false
anim.duration = 3.0
anim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)

ticker.addAnimation(anim, forKey: "animate_ticker")

4 个答案:

答案 0 :(得分:2)

简单更改一个属性:

anim.repeatCount = 0.25    

以下是 excellent article on animation timing,您可以了解如何对动画进行更精细的控制。

附加:
1.要实现您想要的,最接近的方法是拥有25%的子路径,这里有一些helper method

2.如果你能忍受速度差异,请使用上面的方法,并在动画结束时设置回位置:

ticker.position = ticker.presentationLayer().position

答案 1 :(得分:1)

不仅CGPath不透明,而且CAAnimation也不支持正在进行的动画的任何更新或通知(即在开始之后但在完成之前)。涉及的唯一实体是动画本身和CALayer - 它应用于。

所以,选项是:

(有些选项可能听起来太吓人了,但事实并非如此,所以我做了一个示例项目,见下文)

repeatCount

正如wj2061所提及的那样his answer你可以调整动画的repeatCount。缺点是动画时间为0.25,而不是路径的0.25。

CAShapeLayer

如果您有任何机会代表ticker CAShapeLayer段,那么您可以为strokeStartstrokeEnd设置动画,这样看起来就像路径

聪明的repeatCount

您可以计算动画将在路径的0.25处停止的repeatCount值。

  • 抓住一些bezier lib
  • 使用getControlPointAtIndex:
  • 从计时功能中提取bezier
  • 解决bezier获取其“进度值”(通常名为t),其bezier的'y'值将与您的“必需进度”匹配(0.25)
  • 计算该t的bezier'''值 - 这是您需要的repeatCount的确切值

使用CAAnimation制作动画,全部由你自己

有点先进

  • 抓住一些bezier lib
  • 使用动态属性创建自定义CALayer子类,假设为rideProgress
  • 为bezier路径(从bezier lib,而不是CGPath)和子层(比如rideLayer)添加合成属性到动画
  • needsDisplayForKey:键覆盖rideProgress,为所有引入的属性覆盖initWithLayer:但是使用self.rideLayer?.presentationLayer()代替复制rideLayer
  • 覆盖其中一个:drawInContext:并在其中绘制您需要的内容;或者(更好)display,在display中从rideProgress检索当前presentationLayer值并更新子图层,然后调用super。无论哪种方式,使用bezier lib根据当前rideProgress值计算子层的位置和旋转
  • 在设置任何图层的任何可动画属性之前不要忘记CATransaction.setDisableActions(true)
  • 最后,在rideProgress属性
  • 上使用任何类型的CAAnimation或隐式动画

拆分路径

再次,由wj2061建议。您可以拆分路径,使其中一半代表原始

的0.25

Here是EXCEPT“Split path”上面所有内容的示例实现。我没有对这段代码进行任何现场测试,这只是一个有效的概念。 XCode 7.3.1,Swift。

使用的材料:Wiki on Cubic functionGreat article about operations on beziersCubic equations solving method line-by-line

答案 2 :(得分:0)

您是否尝试设置 fromValue toValue 属性?如果您将 fromValue 设置为 0.0 toValue 设置为 0.25

答案 3 :(得分:0)

我遇到了同样的问题,我想要绘制一个Path的绘图,但只有一部分动画。

我最终做的是将图层的strokeStart和strokeEnd设置为与动画相同的浮点值。

因此,在您的示例中,请尝试设置anim.fromValue = 0.0f,anim.toValue = 0.6f以及ticker.strokeStart=0.0fticker.strokeEnd = 0.6f

这只成功地吸引了60%的路径并将其设置为动画!