从CoreAnimation到Pop

pop是Facebook在开源的一款动画引擎,看下其官方的介绍:

Pop是一款在iOS、tvOS和OS X平台通用的可扩展动画引擎。它在基本静态动画的基础上,增加了弹性以及衰减动画,这在创建真实有物里性的交互很有用。其API能够快速的整合进已有的Objective-C工程,可以对任意对象的任意属性做动画。这是一个成熟且经过测试的框架,在Paper这款优秀的app中有广泛的应用。(iOS7之后苹果也提供了Spring动画(不过CASpringAnimation iOS9才提供)以及UIDynamic物理引擎(比如碰撞以及重力等物理效果不错,有兴趣可以玩玩))

那Pop动画引擎跟CoreAnimation有啥区别?我们先来简单了解一下苹果的CoreAnimation:

CoreAnimation

先看下CoreAnimation在框架中所处的位置:


CoreAnimation.png

可以看出视图的渲染以及动画都是基于CoreAnimation框架(看名字容易以为只是动画相关),其地位还是相当重要。我们来看下iOS在视图的渲染以及动画的各个阶段都发生了虾米,这其中涉及到应用内部以及应用外部:

应用内部4个阶段:

  • 布局
    这个阶段是用户在程序内部设置组织视图或图层的关系,比如设置view的backgroundColor、frame等属性;

  • 显示
    这是图层的寄宿图片被绘制的阶段,比如实现了-drawRect:或-drawLayer:inContext:方法,这些方法会这这个阶段执行,这些绘制方法是由CPU在应用内部同步地完成,属于离屏渲染。

  • 准备
    这个阶段,CoreAnimation框架会将渲染视图的各种属性以及动画的参数等数据准备好;同时这个阶段还会解压需要渲染的image。

  • 提交
    这是在应用内部发生的最后阶段,CoreAnimation打包准备好的所有视图/图层以及动画的属性,然后通过IPC(进程间通信)发送到render server进行显示,可以看到其实视图的渲染以及动画是在另外一个进程处理的。在iOS5和之前的版本是SpringBoard进程(同时管理着iOS的主屏),在iOS6之后的版本中叫做BackBoard。

应用外部2个阶段:
一旦这些打包好的数据到达render server,这些数据会被反序列化成另一个叫做渲染树的图层树,根据这个树状结构,render server做如下工作:

  • 根据layer的属性值,如果图层包含动画,则计算其属性的中间插值,然后设置OpenGL几何形状(纹理化的三角形)来执行渲染
  • 在屏幕上渲染可见的三角形

所以整个阶段包含六个阶段,如果有动画,最后两个阶段会重复的执行。前五个阶段都是通过CPU处理的,只有最后一个阶段使用GPU。而且你能控制的只有前面两个阶段:布局和显示,剩下都是CoreAnimation框架在内部进行处理。

简单了解完CoreAnimaton的工作方式之后,我们在来看看pop实现动画的方式。

pop

CADisplayLink是一个和屏幕刷新率(每秒60帧)相同的定时器,pop实现的动画就是基于该定时器,它在每一帧计根据指定的time function计算出动画的中间值,然后将计算好的值赋给视图或图层(可以是任意对象)的属性(比如透明度、frame等),当属性发生变化之后,我们知道Core Animation会通过IPC把这些变化通知render server进行渲染,因此整个动画过程变成是你的应用内部驱动的,render server则被动接受数据进行渲染,跟上面提到的Core Animation动画方式有所不同;另一个不同是pop在动画过程中改变的是model layer的状态,不像Core Animation作用的是渲染树的图层树,Core Animation动画会在动画结束后回到起始位置, model layer, presentation layer 和 render layer的区别有兴趣可以去了解。


core_animation_basics_sublayer_hierarchies.png
Animate View

pop提供了几种动画,包括basic、Spring(弹簧)、Deacy(衰减)以及自定义的动画

其API跟Core Animation提供的API类似,我们来看看如何使用pop,包括以下几个步骤:

// 1 选择动画类型 (POPBasicAnimation  POPSpringAnimation POPDecayAnimation)
POPSpringAnimation *springAnimation = [POPSpringAnimation animation];
springAnimation.springBounciness=16;
springAnimation.springSpeed=6;

// 2 选择要对视图或者图层的属性做动画,比如我们想要缩放动画,我们可以选择:kPOPViewScaleXY。
//pop提供了一些属性,包括视图属性:kPOPViewAlpha kPOPViewBackgroundColor kPOPViewBounds kPOPViewCenter kPOPViewFrame等,
//图层属性:kPOPLayerBackgroundColor kPOPLayerBounds kPOPLayerScaleXY kPOPLayerSize kPOPLayerOpacity kPOPLayerPosition等,具体可以查看POPAnimatableProperty.m文件
springAnimation.property = [POPAnimatableProperty propertyWithName:kPOPViewScaleXY];

// 3 设置动画的终点值
springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(1.3, 1.3)];

// 4 为动画指定代理POPAnimatorDelegate(可选),
springAnimation.delegate = self;

// 5 将动画添加到视图或图层中,开始做动画
[_testView pop_addAnimation:springAnimation forKey:@"springAnimation"];

 


posted on 2016-07-13 19:13  奉灬孝  阅读(175)  评论(0编辑  收藏  举报

导航