CAAnimation的原理
在官方文档的章节 “Layer Trees Reflect Different Aspects of the Animation State” 中讲到了动画的原理,在任何一个Core Animation系统中都有三个Layer Tree
- Model Layer Tree : Model树,用来储存任何动画的Target Value,比如我要旋转ALayer的Transform,ALayer本身就是在这个树中,也是我们交互最多的
- Presentation Tree :展示树,虽然叫展示树,但是它并不是真是的显示在屏幕上,而是Model树的一份拷贝,当动画执行过程中,变动的是这个树上的数值,如果想要获取到实时的数值,可以通过属性presentationLayer来访问
- Render Tree:渲染树,这个才是最终显示在屏幕上使用的对象,它是Core Animation 的私有类,无法访问
可以看到官方文档给出的图解
通过文档解释我们可以了解到,每一个Layer动画在执行时,都存在三份,原本的Layer数据层Model,和动画的操作层Presentation,以及显示图层Render,这个概念会收到动画一些设定影响,比如 “isCumulative”
CAAnimation与CAMediaTiming
CAAnimation是所有动画的基类,其自身提供一些动画效果的控制能力,以及通过实现协议CAMediaTiming来完成一些通用动画设定
属性 | 能力 | 提供者 |
---|---|---|
timingFunction | timing控制函数 | CAAnimation |
isRemovedOnCompletion | 完成后是否移除动画图层 | CAAnimation |
delegate | 代理能力,用于获取begin和end | CAAnimation |
属性 | 能力 | 提供者 |
---|---|---|
beginTime | 显而易见~开始时间 | CAMediaTiming |
duration | 显而易见~持续时间 | CAMediaTiming |
speed | 显而易见~动画速度 | CAMediaTiming |
repeatCount | 显而易见~重复次数 | CAMediaTiming |
repeatDuration | 显而易见~重复时的持续时间 | CAMediaTiming |
timeOffset | 用于控制自身和父级Object的时间关系函数 | CAMediaTiming |
autoreverses | 是否自动倒放动画,即按照运动轨迹返回初始位置 | CAMediaTiming |
fillMode | 在超出了动画时间之后,展现哪个状态 | CAMediaTiming |
timeOffset的计算公式
1 | timeSelf = (timeParent - beginTime) * speed + timeOffset |
用于控制自身时间和父级时间的关系,在文档中说,一个实用的例子就是通过设置speed=0,然后设定一个timeOffset=5来达到暂停效果,让动画始终停止在5s时候的状态
fillMode的可选值
fillMode的可选值有四个 backwards(开始)、 forwards(结束) 、both (开始和结束)、removed(移除)
比较奇怪的是这个Both开始和结束,猜测是根据在动画结束后,当时处于何种状态就展示哪种状态,默认值为移除
CAPropertyAnimation
根据文章动画的继承树描述,我们可以得知 CAPropertyAnimation继承于CAAnimation,自身和基类主要提供了以下方法
属性 | 能力 | 提供者 |
---|---|---|
keyPath | 决定了在哪个属性上做动画,很重要!! | CAPropertyAnimation |
isAdditive | 是否影响到原图层Model Tree,参见动画的继承树 | CAPropertyAnimation |
isCumulative | 是否以前一个动画的结束值,作为当前动画的开始值 | CAPropertyAnimation |
valueFunction | value控制函数 | CAPropertyAnimation |
在 CAPropertyAnimation 的基础上,衍生出了关键帧动画(CAKeyframeAnimation) 和 基本动画 (CABasicAnimation)
CABasicAnimation
CABasicAnimation 提供了以下三个值,来控制动画,注意这三个值都是id类型的,是因为根据 CAPropertyAnimation中 keyPath的不同,会使用不同的单位
属性 | 范围 |
---|---|
fromValue | 从fromValue到Render Tree的当前Value |
toValue | 从Render Tree的当前Value到 toValue |
byValue | 从Render Tree的当前Value 到 当前Value加上byValue |
可以使用的组合方式分为两种
- fromValue + toValue : 这种很好理解,就是从最小值到最大值
- fromValue + byValue : byValue的意思是增量值,即从fromValue 到 fromValue+byValue
CAKeyframeAnimation
与Basic动画不同的是,KeyFrame动画是通过关键帧来控制的动画,其包括的属性如下
属性 | 类型 | 范围 |
---|---|---|
keyTimes | NSArray<NSNumber *> | 关键帧设定,是一个数组,但是必须是 由0到1组成 ,其会根据百分比与CAMediaTiming协议设定的duration进行换算 |
values | NSArray | 类似于Basic的value,但是是一个数组,对应每一个keyTimes |
path | CGPathRef | 与values二选一,会把path自动平分成value值 |
timingFunctions | NSArray | 时间函数,也是数组,可以针对不同的关键帧之间用不同的时间函数 |
calculationMode | NSString | 积累模式 |
tensionValues | NSArray | 一些状态控制参数,不太懂 |
continuityValues | NSArray | 一些状态控制参数,不太懂 |
biasValues | NSArray | 一些状态控制参数,不太懂 |
rotationMode | NSString | 可以设定auto' 和 autoReverse’ 默认是nil,用来控制什么tangent切角关系 |
上边一堆高大上的属性,只需要记住的是 前三个 keyTimes、values、path。其中values和path是二选一,而keyTimes的设置方式是
1 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; |
此时动画的设置时长是10秒,关键帧设置到了0、0.1、0.5、1.0就是 0秒、1秒、5秒、10秒四个时刻