沿着贝塞尔曲线的一部分为UIView制作动画

时间:2018-01-14 18:17:04

标签: ios swift animation uiview core-animation

我试图沿着bezier路径的一部分动画UIView。我找到了一种方法,使用以下代码将视图移动到路径的任何部分:

let animation = CAKeyframeAnimation(keyPath: "position")

animation.path = trackPath.cgPath

animation.rotationMode = kCAAnimationRotateAuto
animation.speed = 0
animation.timeOffset = offset
animation.duration = 1
animation.calculationMode = kCAAnimationPaced
square.layer.add(animation, forKey: "animate position along path")

但是,这只会将视图移动到所需的点并且不会对其进行动画处理。如何在Bezier路径的一部分上为视图设置动画?

由于

2 个答案:

答案 0 :(得分:10)

你可以通过修改"完成"的时间来实现这一目标。动画和包装它的动画组。

为了说明这种动画的时间是如何工作的,想象一下 - 而不是沿路径设置动画的位置 - 颜色是动画的。然后,从一种颜色到另一种颜色的完整动画可以这样说明,其中右边的值是稍后的时间 - 所以最左边是起始值,最右边是结束值:

The complete animation

请注意"时间"这个动画是线性的。这是故意的,因为"时间"最终结果将在稍后配置。

在这个动画中,想象一下我们只想动画中间三分之一,动画的这一部分:

Part of the animation

只有几个步骤可以动画动画的这一部分。

首先,配置"完成"动画具有线性定时(或者在沿着路径的动画的情况下;具有起搏的计算模式)并且具有"完成"持续时间。

例如:如果您要动画动画的三分之一, 需要1秒,请将完整动画配置为3秒。

let relativeStart = 1.0/3.0
let relativeEnd   = 2.0/3.0

let duration      = 1.0
let innerDuration = duration / (relativeEnd - relativeStart) // 3 seconds

// configure the "complete" animation
animation.duration = innerDuration

这意味着当前动画如下所示(完整动画):

The full animation

接下来,动画"开始"进入完整动画的三分之一,我们"偏移"它的时间是持续时间的三分之一:

animation.timeOffset = relativeStart * innerDuration

现在动画如下所示,从最终值到其起始值进行偏移和包装:

The animation with its time offset

接下来,我们只显示此动画的一部分,我们创建一个具有所需持续时间的动画组,并仅添加"完成"动画到它。

let group = CAAnimationGroup()
group.animations = [animation]
group.duration = duration

即使这个组包含3秒长的动画,它也会在1秒后结束,这意味着偏移的2秒"完成"动画将永远不会显示。

现在,群组动画就像这样说明,在完成"完成"之后的三分之一时间结束。动画:

Group animation

如果你仔细观察,你会发现这个(没有被淡出的部分)是"完成"的中间三分之一。动画。

现在,该组为所需值之间的动画设置动画,可以进一步配置它(组),然后将其添加到图层。例如,如果你想要这个" partial"动画反转,重复,并有一个时间曲线,您将在组中配置这些东西:

group.repeatCount = HUGE
group.autoreverses = true
group.timingFunction = CAMediaTimingFunction(name: "easeInEaseOut")

使用此附加配置,动画组将如下所示:

Part of the animation, auto reversing and repeated

作为一个更具体的例子,这是我使用这种技术创建的动画(实际上所有代码都来自该示例),它像钟摆一样来回移动图层。在这种情况下,"完成"动画是一个"位置"沿着一个完整圆圈的路径动画

A layer moving back and forth like a pendulum

答案 1 :(得分:2)

我几天前做过类似的动画:

// I want the animation to go along the circular path of the oval shape
let flightAnimation = CAKeyframeAnimation(keyPath: "position")
flightAnimation.path = ovalShapeLayer.path
// I set this one to make the animation go smoothly along the path
flightAnimation.calculationMode = kCAAnimationPaced
flightAnimation.duration = 1.5
flightAnimation.rotationMode = kCAAnimationRotateAuto
airplaneLayer.add(flightAnimation, forKey: nil)

我看到你将speed设置为零和时间偏移。你为什么需要它们? 我建议只使用上面代码中的参数来尝试动画,然后尝试从它们中调整它。