干货系列之手把手教你使用Core animation 做动画

源码下载:源码

最近在技术群里,有人发了一张带有动画效果的图片。觉得很有意思,便动手实现了一下。在这篇文章中你将会学到Core Animation显式动画中的关键帧动画、组合动画、CABasicAnimation动画。先上一张原图的动画效果。

点击此查看原图动画效果。

本文要实现的效果图如下:

 

实现的效果图.gif

把原动画gif动画在mac上使用图片浏览模式打开,我们可以看到动画每一帧的显示。从每一帧上的展示过程,可以把整体的动画进行拆分成两大部分。

第一部分(Part1)从初始状态变成取消状态(图片上是由横实线变成上线横线交叉的圆)。
第二部分(Part2)从取消状态变回初始状态。

下面我们先详细分析Part1是怎么实现的。根据动画图,把Part1再细分成三步。

Step1 : 中间横实线的由右向左的运动效果。这其实是一个组合动画。是先向左偏移的同时横线变短。先看一下实现的动态效果。

 

step1 Animation.gif

■ 向左偏移—使用基本动画中animationWithKeyPath键值对的方式来改变动画的值。我们这里使用position.x,同样可以使用transform.translation.x来平移。

■ 改变横线的大小—使用经典的strokeStartstrokeEnd。其实上横线长度的变化的由strokeStartstrokeEnd之间的值来共同来决定。改变strokeEnd的值由1.0到0.4,不改变strokeStart的值。横线的长度会从右侧方向由1.0倍长度减少到0.4倍长度。参见示意图的红色区域。

 

stroke示意图.png

Step2 : 由左向右的动画–向右偏移同时横线长度变长。看一下Step2要实现的动画效果。其思路和Step1是一样的。

 

step2 Animation.gif

Step3: 圆弧的动画效果和上下两个横实线的动画效果。

  1. 画圆弧,首先想到是使用UIBezierPath。画个示意图来分析动画路径。示意图如下:
 

step3 示意图.jpg

整个path路径是由三部分组成,ABC曲线CD圆弧DD′圆
使用UIBezierPath的方法

把三部分路径关联起来。详细讲解思路。

• ABC曲线就是贝塞尔曲线,可以根据A、B、C三点的位置使用方法

二次贝塞尔曲线示意图如下:

 

二次贝塞尔曲线.png

其中control point 点是从曲线上取 start point和end point 切点相交汇的所得到的交点。如下图:

 

control point .png

首先C点取圆上的一点,-30°。那么,

C点坐标为:

A点坐标为:

control point 为E点:

• CD圆弧的路径使用此方法确定

关于弧度问题,UIBezierPath的官方文档中的这张图:

 

弧度.jpg

StartAngle 弧度即C点弧度,EndAngel弧度即D点弧度。

• DD′圆的路径和上面2一样的方法确定。

StartAngle 弧度即D点弧度,EndAngel弧度即D′点弧度。

下面部分代码是所有path路径。

Path路径有了,接着实现动画效果。
圆弧的长度逐渐变长。我们还是使用经典的strokeStartstrokeEnd。但是圆弧是如何变长的呢?

(1) 初始圆弧有一段长度。
(2) 在原始长度的基础上逐渐变长,逐渐远离A点,同时要在D点停止。
(3) 长度逐渐变长,最终要在D与D′点交汇。

我们分别解决这个三个问题。

第一个问题,strokeEnd - strokeStart > 0这样能保证有一段圆弧。

第二个问题,逐渐变长,意味着strokeEnd值不断变大。远离A点意味着strokeStart的值不断变大。在D点停止,说明了strokeStart有上限值。

第三个问题,意味着strokeEnd值不断变大,最终值为1.0。

这三个问题说明了一个问题,strokeEndstrokeStart是一组变化的数据。

那么core animation 中可以控制一组值的动画是关键帧动画(CAKeyframeAnimation)。

为了更准确的给出strokeEndstrokeStart值,我们使用长度比来确定。

假设我们初始的长度就是曲线ABC的长度。但是贝塞尔曲线长度怎么计算?使用下面方法:

计算贝塞尔曲线所在的比例为:

初始的strokeStart = 0strokeEnd = orignPercent
最终的stokeStart = ?

实现动画的代码为

效果图为:

 

step3-1 Animation.gif

2.上下横线的动画效果。

此动画效果,需要使用transform.rotation.z转动角度。

上横线转动的角度顺序为 0 -> 10° -> (-55°) -> (-45°)
这是一组数据,使用关键帧处理动画。

下横线转动的角度顺序为0 -> (-10°) -> (55°) -> (45°)

你认为这么就结束了? 最终结束的动画如下:

 

step3-2 finished Animation.jpg

发现相交的直线没有居中,而是靠左显示。

向左平移,使用transform.translation.x

即旋转角度又发生偏移量,使用组合动画。

上横线组合动画

下横线组合动画

Part1到此结束。最终效果图

 

Part1 animation.gif

Part2的思路和Part1思路是一样的。你可以参考代码自己思考一下。核心代码

你可能感兴趣的:(IOS9)