简介:
好久没更新文章了,今天讲的是Facebook出的一款动效库Facebook-Pop。(部分内容摘自互联网,文章最后附有demo地址,有什么不对的地方,欢迎大家指正出来,大神勿喷,嘿嘿)
Pop是一个动画引擎,用以扩展iOS、OSX的动画类型。相较于iOS、OSX中的基本动画效果,Pop扩展后支持弹簧动画效果与衰减动画效果,你可以用Pop动画引擎来构建出真实的物理交互效果。它的API与Core Animation的API非常类似,使用起来非常容易。Pop动画引擎已经经过了良好的测试,Facebook在 Paper 应用中进行了大量使用。
官方Git地址:https://github.com/facebook/pop
iOS原生的Core Animation框架只提供了linear, ease-in, ease-out和ease-in-ease-out等4种静态动画:
而Pop在Core Animation基础上增加Spring、Decay和Custom 3种动态动画效果:
Spring(弹性)和Decay(衰减)可以让动画变得更灵动,而Custom这更为强大,可以给任何NSObject对象属性添加动画效果(待会有例子介绍)。
所以今天主要讲的就是4个动画效果
- POPBasicAnimation //基础动画
- POPSpringAnimation //弹性动画
- POPDecayAnimation //衰减动画
- POPCustomAnimation //自定义动画
使用
POPBasicAnimation
- POPBasicAnimation使用最广泛 提供固定时间间隔的动画(如淡入淡出效果)
其实只有3个步骤就能创建一个动画let animation = POPBasicAnimation(propertyNamed: kPOPLayerPositionX) animation.toValue = NSValue(CGPoint: CGPointMake(100, 200)) animation.duration = 2 animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) view.layer.pop_addAnimation(animation, forKey: "positionX")
1.创建对应的动画类型,这里我使用的是kPOPLayerPositionX来控制view的位置
2.设置动画的属性
toValue设置动画的最终值(对应的还有fromValue是设置动画的起始值,不写默认为当前值)
duration设置动画时长
timingFunction是系统预设的动画类型有以下5种:
1 | kCAMediaTimingFunctionLinear 线性,即匀速 |
这里使用的是EaseIn(先慢后快)
3.最后只需把动画add到对应视图的layer就完成,设置了key可以方便删除和修改动画,例如:
[layer pop_removeAnimationForKey:@”positionX”];
POPSpringAnimation
- POPSpringAnimation也许是大多数人使用POP的理由 其提供一个类似弹簧一般的动画效果(炫酷!)
1
2
3
4
5
6
7
8
9let animation = POPSpringAnimation(propertyNamed: kPOPLayerScaleXY)
animation!.toValue = NSValue(CGSize: CGSizeMake(5, 5))
animation!.springBounciness = 10 //[0-20] 弹力 越大则震动幅度越大
animation!.springSpeed = 20 //[0-20] 速度 越大则动画结束越快
//以下3个与物理力学模拟相关,没特殊需求不建议使用
// animation.dynamicsFriction = 0 //拉力
// animation.dynamicsFriction = 0 //摩擦
// animation.dynamicsMass = 0 //质量
view.layer.pop_addAnimation(animation, forKey: "scaleXY")
POPSpringAnimation是没有duration字段的 其动画持续时间由以上几个参数决定,简单的几个步骤就能实现非常炫酷灵动的效果了
POPDecayAnimation
- POPDecayAnimation提供一个过阻尼效果(其实Spring是一种欠阻尼效果) 可以实现类似UIScrollView的滑动衰减效果(是的 你可以靠它来自己实现一个UIScrollView)
1
2
3
4
5
6
7
8let animation = POPDecayAnimation(propertyNamed: kPOPLayerPositionX)
animation.velocity = 200 //速度
animation.deceleration = 0.998 // 衰减系数(越小则衰减得越快)
//目的状态toValue是通过velocity和deceleration计算,动态得到
view.layer.pop_addAnimation(animation, forKey: "decayPosition")
这是一个很简单的移动例子,当然强大的POP不止这些属性,在POPAnimatableProperty文件中还有很多可操作的属性,并且维护者还在不断增加:
1 | /** |
什么?你说这里面没有你需要的,别着急POP还有更强大的自定义属性功能
自定义属性
- POP默认支持的三种动画都继承自POPPropertyAnimation POPPropertyAnimation中定义了一个叫property的属性( 之前没有用到它是因为POP根据不同的默认动画属性帮你生成了默认的property) 而这个property则是用来驱动POP的动画效果中的重要一环
1
2
3
4
5
6
7
8
9
10
11
12POPAnimatableProperty *prop = [POPAnimatableProperty propertyWithName:@"prop" initializer:^(POPMutableAnimatableProperty *prop) {
// read value
prop.readBlock = ^(id obj, CGFloat values[]) {
};
// write value
prop.writeBlock = ^(id obj, const CGFloat values[]) {
};
// dynamics threshold
prop.threshold = 0.01;
}];
其组成就是一个readBlock一个writeBlock和一个threashold
readBlock告诉POP当前的属性值
writeBlock中修改变化后的属性值
threashold决定了动画变化间隔的阈值 值越大writeBlock的调用次数越少
POPAnimatableProperty其实是POP中一个比较重要的东西 像上面提到的POP自带的动画属性 查看源代码可以看到也只是POP自动帮你设置好了POPAnimatableProperty而已 其作用就是当动画的某个时间片被触发时 告诉系统如何根据当前时间片做出变化
直接上案例,我们要实现一个像系统的时钟APP里秒表计时的一个效果
1 | testLabel = UILabel(frame: CGRectMake(0,0,100,50)) |
效果如下:
从这个例子中有没有新的启发呢,POP可以做的事情远比CoreAnimation要多,它的强大毋庸置疑。
Demo地址:https://github.com/yueyeqi/Facebook-PopExample
小结
其实只需要熟练掌握POP自带的三种动画 即可完成大部分的动画效果 如果实在是无法满足你的需求的话 自定义动画也基本可以满足你的要求 可以说POP化繁为简的出现 极大的方便了我们这些苦逼的coder 本文主要只介绍了最基本的使用方法和思路,更多的知识和效果还待大家深入了解 完。