从CoreAnimation到Facebook‘s Pop(1)

来源:互联网 发布:远程网络教育毕业证 编辑:程序博客网 时间:2024/05/19 22:44

从CoreAnimation到Facebook‘s Pop(1)

相信所有开发者在开发阶段都会接触到动画,简单的从UIView层的动画一直到layer层的动画,抑或通过重绘实现的动画。在恰当场景使用合适的动画不仅可以让你的app交互更加新奇有趣,而且能够体现出作者的实力。实在是居家旅行的必备。
其实最理想的动画应该是专门负责交互的设计师使用Quartz Composer或者AE之类的设计工具,设计完之后告诉你时间节点,动画样式之类的数据,然后你直接利用代码转换,然后据我所知,国内的大部分公司(至少9成)是没有这样的流程的,大部分动画都靠凑出来。可能是工程师通过一次次调校代码的参数调出来的。
国内的app开发者可能不是太重视这方面的开发,所以很少有给我那种第一次见到paper(facebook出品)或者是Taasky,City Guides那种震撼感觉的。

这是Taasky的
这是Taasky的
这是国家地理杂志出的City guide
这是国家地理杂志出的City guide
这是Paper
这是Paper

这个系列的博客主要讲的是Layer层动画的实现,因为View层的动画实际上并不难掌握,相信大家也都使用的很熟练了。
每个view都有一个layer,layer主要负责渲染,view只是在layer的基础上增加了Event Handle一类的东西,实际上你调整view的frame也好,调backgroundcolor也罢,这类负责展示的属性实际上都是在调整layer的对应属性。动画无非就是layer层的再次渲染。
这篇博客将通过这个例子告诉大家CABasicanimation的基本用法.

我们的目标
我们的目标

看到别人的交互第一个想法应该是拆解,因为一个优秀的动画肯定不是由一个单元的效果,或者单一的时间线(timingfuntion)组成的。肯定是由多种不同的效果组成。
我们来试着拆解一下上图的圆球动画效果。

  1. 第一步最明显的肯定是小圆从小变到大。
  2. 那么我们应该可以想到是做了makescale,而且在做scale之前要先修改view的cornerRadius以使这个view变成一个圆形。
  3. 然后最明显的变化就是这个圆变成了椭圆。可能这个地方会有人断了思路,仔细想想其实不难。makescale需要传参数。

    CATransform3DMakeScale(0.1, 0.1, 1)

4.这三个参数分别代表在x,y,z轴压缩的比例,当x,y轴压缩比率相同的情况下view的宽高缩放比例相同,那么只改变Y轴缩放比例,让Y轴缩放比例大于X轴缩放比例那么一个圆不就变成了椭圆么。

5.想到这其实第二个动画的实现也呼之欲出。我们只需要在小圆同比率变大到一定程度之后,只改变Y 轴的放大比率就行了。
我们先实现第一个拆解的动画,就是X,Y轴同比率缩放。

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];animation.duration = 3.;animation.fromValue = @(0.1);animation.toValue = @(1.);return animation;

这个地方我想多说几句的是这个叫做animationWithKeyPath的东西。这个keyPath到底是什么?
一句话,就是CALayer的所有属性。如图展示了一部分属性

CALayer的一部分属性
CALayer的一部分属性

这样,你们可以自己写一个CABasicAnimation 然后在keypath里分别填入下面的属性,自己试试效果。(连shadowColor都可以用basicanimation做动画哦!)
我们来看看第一个拆解动画的效果。


然后第二个拆解动画,我们只改变Y轴压缩率。

- (CABasicAnimation *)createScaleYAnimation{CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale.y"];animation.duration = 3.;animation.fromValue = @(1);animation.toValue = @(2.);return animation;}

效果如图所示:


那么问题来了,我们只是单独的实现了两个动画,怎么才能把他组合起来呢,而且这两个动画是有先后次序的。
很简单,苹果早已为我们准备了这个叫做CAGroupAnimation的东西。他可以组合多个CAAnimation,并且分配他们的开始时间和动画时长。
代码如下。

- (CAAnimationGroup *)createGroupAnimation{CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];animation.duration = 3.;animation.fromValue = @(0.1);animation.toValue = @(1.);CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"transform.scale.y"];animation2.duration = 3.;animation2.fromValue = @(1);animation2.toValue = @(2.);animation2.beginTime = 3.;CAAnimationGroup *group = [CAAnimationGroup animation];group.duration = 6.;group.animations = @[animation,animation2];return group;}

这里唯一需要解释的可能就是animation2比animation多了一个beginTime,很简单,beginTime就是动画开始的时间,既然第一个动画持续时间是3秒,那么第二个动画应当在第一个动画结束的时候执行,那么就是第三3秒钟开始了。(当然,你也可以让两个动画同时执行,比如把beginTime设置为2,那么当第一个动画执行到2秒还没完的时候第二个动画就开始执行了。)
我们看看效果。


现在我们完成了基本的动画,现在唯一的问题就是把动画和tableview的offset联系起来。直接贴代码。你们感受一下。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{NSLog(@"offset is %@",NSStringFromCGPoint(_mTableView.contentOffset));CGFloat delta = 8./-150;if (_mTableView.contentOffset.y>-150) {    [animationView setAnimationProgress:(_mTableView.contentOffset.y*delta)];}else{    [animationView setAnimationProgress:8.];}}

然后我们最后的效果如下。


最后放上我们的github地址: https://github.com/pingguo-zangqilong/CoreAnimationLesson1

0 0