导语
这段时间我们部门组织学习分享Core Animation,所以我就稍微整理了下关于动画这块的分享。
Core Animation其实是一个令人误解的命名,大多数人认为它只是用来做动画的,但实际上市一个叫做Layer Kit演变而来,所以动画只是Core Animation特性的冰山一角而已,接下来我们就讨论下这个冰山一角的常规用法,纯粹是抛砖引玉。
一、基础知识
1、动画的本质
- 一定时间内属性值的变化,属性为位置、透明度、旋转等
2、动画实现方式
- 逐帧:需要处理动画的每一帧,这样的实现动画的方式叫做逐帧动画
- 关键帧:我们只需给定几个关键帧的画面,其余过度帧都由计算机自动生成
二、动画实现
关键帧动画
1、CABasicAnimation
1、动画的属性
2、属性值的解释
- repeatCount:一直不断重复:swift:Float.infinity,OC:HUGE_VALF
- timingFunction:
kCAMediaTimingFunctionLinear:匀速改变
kCAMediaTimingFunctionEaseIn:渐入
kCAMediaTimingFunctionEaseOut: 渐出
kCAMediaTimingFunctionEaseInEaseOut:渐入渐出
kCAMediaTimingFunctionDefault:隐式动画更加适合
使用方法
pathAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
- fillMode
kCAFillModeForwards:动画开始之后layer的状态将保持在动画的最后一帧,而removedOnCompletion的默认属性值是 YES,所以为了使动画结束之后layer保持结束状态,应将removedOnCompletion设置为NO。
kCAFillModeBackwards:将会立即执行动画的第一帧,不论是否设置了 beginTime属性。观察发现,设置该值,刚开始视图不见,还不知道应用在哪里。
kCAFillModeBoth:该值是 kCAFillModeForwards 和kCAFillModeBackwards的组合状态
kCAFillModeRemoved:动画将在设置的 beginTime 开始执行(如没有设置beginTime属性,则动画立即执行),动画执行完成后将会layer的改变恢复原状。
示例
- 旋转动画
-
位移动画
- 背景颜色变化动画、背景图片变化动画、圆角变化动画
- 比例缩放动画
- size大小缩放、透明值变化动画(可用作闪烁效果)
2、CAKeyframeAnimation
CAKeyframeAnimation是核心动画里面的帧动画,它提供了按照指定的一串值进行动画,好像拍电影一样的一帧一帧的效果
UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(50, 100, 250, 250)];
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:tempView.frame];
UIView *animView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 70, 80)];
animView.backgroundColor = [UIColor redColor];
[self.view addSubview:animView];
CAKeyframeAnimation *orbitAnim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
orbitAnim.duration = 5;
orbitAnim.path = bezierPath.CGPath;
orbitAnim.calculationMode = kCAAnimationPaced;
orbitAnim.fillMode = kCAFillModeForwards;
orbitAnim.repeatCount = INFINITY;
orbitAnim.rotationMode = kCAAnimationRotateAutoReverse;
[animView.layer addAnimation:orbitAnim forKey:@"orbitAnim"];
CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
shapeLayer.strokeColor = [UIColor purpleColor].CGColor;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.lineWidth = 0.5;
shapeLayer.lineJoin = kCALineJoinRound;
shapeLayer.lineCap = kCALineCapRound;
shapeLayer.path = bezierPath.CGPath;
[self.view.layer addSublayer:shapeLayer];
- 示例
3、CATransition
主要用于转场动画从一个场景以动画的形式过渡到另一个场景
另外还有一些系统未公开的动画效果:
["cube", "suckEffect", "rippleEffect", "pageCurl", "pageUnCurl", "oglFlip", "cameraIrisHollowOpen", "cameraIrisHollowClose", "spewEffect","genieEffect","unGenieEffect","twist","tubey","swirl","charminUltra", "zoomyIn", "zoomyOut", "oglApplicationSuspend"]
代码示例:
CATransition *pageCurlAnim = [[CATransition alloc] init];
pageCurlAnim.delegate = self;
pageCurlAnim.duration = 1.0;
pageCurlAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
pageCurlAnim.type = animArr[index];
pageCurlAnim.subtype = kCATransitionFromLeft;
pageCurlAnim.repeatCount = 1;
[pageCurlAnim setValue:@"transitionAnim" forKey:@"anim"];
[transitionLab.layer addAnimation:pageCurlAnim forKey:@"transition"];
4、CASpringAnimation
iOS9才引入的动画类,在以前我们都是使用facebook的pop来做这种弹簧效果,它继承于CABaseAnimation,用于制作弹簧动画
参数说明
- mass:质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大,动画的速度变慢,并且波动幅度变大
- stiffness:刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快
- damping:阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快
- initialVelocity:初始速率,动画视图的初始速度大小速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反如果
- settlingDuration:结算时间 返回弹簧动画到停止时的估算时间,根据当前的动画参数估算通常弹簧动画的时间使用结算时间比较准确
-
示例
逐帧动画
实际就是周期性的(CADisplayLink)对UIView背后的CALayer的修改
著名的facebook的pop动画框架,就是使用CADisplayLink这种逐帧绘制的方式。
三、关键帧与逐帧对比
- 关键帧:只需要修改某个属性值,简单方便,但涉及深层次内容较多,需要更多的理解和联系。
- 逐帧:实现原理简单,但绘制动画的过程复杂,处理的事情多开销大,绘制过程中需要数学、物理学知识计算中间量。
四、一些有意思的动画
-
曲线划线动画
利用正弦曲线做的,也是逐帧动画,相信很多人都做过:
- 粒子动画