Pop动画的学习

pop动画是facebook出品的动画框架,不是基于Core Animation

2016-06-02 | 阅读

Pop动画库的学习

pop是facebook开源的一套动画库,pop是使用Objective-C++编写的。pop通过CADisplayLink让动画实现了60FPS的流畅效果,是独立于Core Animation的动画方案。

Core Animation中,动画都是补间动画,其载体只能是CALayer。而Pop中也是补间动画,但载体可以是NSObject的对象,所以pop中可以设置任何值的属性跟随时间变化,还可以通过PopAnimatableProperty属性来进行复杂的属性赋值。

##start,stop & update

添加一个动画,直接添加到对象上,如:

POPSpringAnimation *anim = [POPSpringAnimation animation];
...
[layer pop_addAnimation:anim forKey:@"myKey"];

要终止一个动画,要将其从对象的上删除。要注意的是,在Core Animation中,动画中断会回到初始状态,而在pop中,会停留在当前状态.

[layer pop_removeAnimationForKey:@"myKey"];

动画是直接以key的形式添加到对象上的,所以也可以直接找到当前对象上的动画对象,然后还可以无缝的修改进行中的动画的toValue :

anim = [layer pop_animationForKey:@"myKey"];
if (anim) {
  /* update to value to new destination */
  anim.toValue = @(42.0);
} 

上面距离是使用UILayer距离的,但是事实上Pop的借口是在NSObjectcategory上的。

动画属性POPAnimatableProperty

在POP中,任何属性都可以作为动画使用,而一般来说,默认提供的动画在POPAnimatableProperty.h中可以看到。而如果想要对自己需要的属性进行动画,可以:

    POPAnimatableProperty *prop = [POPAnimatableProperty propertyWithName:@"com.lxm.Label.text" initializer:^(POPMutableAnimatableProperty *prop) {
        prop.readBlock = ^(UILabel *obj, CGFloat values[]) {
            values[0] = [obj.text floatValue];
        };
        // write value
        prop.writeBlock = ^(UILabel *obj, const CGFloat values[]) {
            [obj setText:[NSString stringWithFormat:@"%.2f",values[0]] ];
        };
        // dynamics threshold
        prop.threshold = 0.01;
    }];

通过POPAnimatableProperty,为属性设置一个readBlock和一个writeBlock,首先要明确一点,所有属性都是基于float类型的。这里例子是对一个UILabel的标题做动画,不断变化label的标题。在readBlock中,从对象上读出当前的属性的值,写入CGFloat数组中。在writeBlock中,将动画产生的新值放在CGFloat数组中作为参数传入,然后将值读取出来,写入当前要动画的对象中,以产生动画效果,这里就是直接设置UILabel的标题。属性threshold表示过滤的最小值,如果最新数值与之前的数值差小于threshold,则忽略,以避免过多无意义的动画对性能的消耗。

动画类型

pop中提供了4种动画类型 : spring ,decay ,basic ,custom

POPSpringAnimation

Spring动画,表示的是弹簧效果的动画。控制动画效果的主要参数包括:

  • springBounciness : 弹簧的振幅,与springSpeed结合使用,值越大导致振幅越大,范围是[0,20],默认是4.
  • springSpeed : 弹簧的速度,值越大减速效果大,会更快的让弹簧停下来。范围也是[0,20],默认值是12.
  • dynamicsTension : 动力学上的张力,张力决定的是最大振幅.
  • dynamicsFriction : 动力学的摩擦力,而摩擦力决定了弹簧震动削减的速率。
  • dynamicsMass : 动力学的质量,质量决定的是初始速度对应的惯性大小,质量越大,张力和摩擦力的影响也就越小。

对于Spring动画,要么使用配套的springBouncinessspringSpeed,要么使用动力学的三个参数进行设置,两种选择只能选择一种进行计算。最后设置的属性会修改userSpecifiedDynamics标记的值,告知动画使用哪种计算方式。简单来说,前者是对弹簧动画的简单抽象,而且可以设置初始速度,但是对于后者,动力学的设置时,默认初始速度是0 ,可以通过velocity属性来设置初始的速度。

POPDecayAnimation

decay动画,表示的是逐渐衰弱的动画。这个动画中的参数velocity速率,一般并不是用于物体自发动画,而多是用于用户的交互,用户给一个初始速度,然后动画逐渐衰减。decay动画只有fromValue没有toValue。常用属性有:

  • deceleration : 减速率,值越小,减速越明显,越快停止运动。范围在[0,1],默认值是0.998 。
  • velocity :速率,是id类型,如果对于Float属性的动画,则velocity可以是@(100),这样的速度,而对于一个点CGPoint,其速度就是在二维平面上的,应该由两个Float表示,如果对于CGRect`则应该由4个Float表示。但对于一个CGPoint`属性的动画,如下设置可以正常运作:

      POPDecayAnimation *decay = [POPDecayAnimation animationWithPropertyNamed:kPOPViewCenter];
      // x 速度100 ,y 速度200
      decay.velocity = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
      // x速度 100 ,y速度200,而忽略 100和1000.
      decay.velocity = [NSValue valueWithCGRect:CGRectMake(100, 200, 100, 1000)];
      // x速度为100 ,y速度为0
      decay.velocity = @100;
      decay.deceleration = 0.999;
    

结合上面的POPAnimatableProperty就可以知道,所有可以动画的属性通过一个CGFLoat数组与Pop交换数据,则对于速率,最终在pop也是一个CGfloat`数组,所以在上面传入的三个速度中,pop依次获取自己需要的速度,即取数组中的第一个值作为x轴速度,第二个值作为y轴速度。没有值取0,多了忽略,所以上面三种形式的velocity`都可以正常使用。

POPBasicAnimation

basic动画,就是Core Animation中的基础动画了,常用属性:

  • duration : 动画时间,默认为0.4
  • timingFunction : 动画时间函数,默认为kCAMediaTimingFunctionDefault

时间函数,与Core Animation中一样,这里简单介绍一下:

  • kCAMediaTimingFunctionLinear 线性动画,时间匀速
  • kCAMediaTimingFunctionEaseIn 慢进, 一开始慢慢加速
  • kCAMediaTimingFunctionEaseOut 慢出,一开始全速,然后慢慢减速到停止
  • kCAMediaTimingFunctionEaseInEaseOut 慢进慢出,最常用的时间函数,慢慢加速再慢慢减速到停止。
  • kCAMediaTimingFunctionDefault 这个默认的时间函数,类似与慢进慢出,但加速和减速的过程比 EaseInEaseOut要短要快。

POPAnimation中提供的接口

  • name :名称,可选的属性,用来标记动画.
  • beginTime : 开始时间,默认是0,即立即开始.
  • delegate : 设置一个委托
  • tracer : 设置一个POPAnimationTracer对象,用于追踪动画以满足某些测试目的.
  • animationDidStartBlock,animationDidReachToValueBlock, completionBlock , animationDidApplyBlock : 4个block,与delegate中的方法对应.
  • removedOnCompletion : 在动画完成时,是否从对象上自动释放,默认是YES.
  • paused : 暂停动画属性,设置该属性可以让动画暂停. 一开始初始化时,是暂停的.而如果没有设置removedOnCompletion,在动画结束时,也是会设置暂停的.
  • autoreverses : 在动画完成时,是否以完全相反的方式收回动画,以回归初始状态. 设置autoreverses后,动画间隔时间依旧是正向动画的执行时间,即一次动画完整的时间变成了两倍duration.
  • repeatCount : 重复次数 ,0或者1表示不重复,但是0并不表示不执行动画.
  • repeatForever : 是否无限重播.

POPPropertyAnimation

  • property : 属性,可以使用自己实现的POPAnimatableProperty类型.
  • fromValue : 初始值
  • toValue : 目标值
  • roundingFactor : 对动画的value进行进位的因子.默认是0,不进行舍入.当为1表示进位成整数.
  • clampMode : 设置动画的范围.默认是kPOPAnimationClampNone,不设置范围,kPOPAnimationClampStart设置值都大于fromValue,而kPOPAnimationClampEnd设置值都小于toValue.