###一、核心动画的基本概述html
CoreAnimation的是 Objective - C 的框架,它经过简单的动画编程接口来提供一套高性能的动画引擎。ios
一套简单的动画接口,可让你的动画运行在独立的线程里面,并能够 独立于主线程以外
。一旦动画配置完成并启动,核心动画彻底控制并独立完成相应的动画帧
。核心动画类(CAAnimation)包含CABasicAnimation(基本动画)、CATransition(转场动画)、CAKeyframeAnimation(关键帧动画)、CAAnimationGrup(动画组),动画的对象是图层(layer)。git
CABasicAnimation
:提供了在图层的属性值间简单的动画。CAKeyframeAnimation
: 提供支持关键帧动画。你指定动画的一个图层属性的关键路径,一个表示在动画的每一个阶段的价值的数组,还有一个关键帧时间的数组和时间函数。CATransition
:提供了一个影响整个图层的内容过渡效果。在动画显示过程当中采用淡出(fade)、推出(push)、显露(reveal)图层的内容。CAAnimationGroup
: 容许一系列动画效果组合在一块儿,并行显示动画。###二、基本动画(CABasicAnimation) CABasicAnimation 用于实现layer属性值从一个值(fromValue)到另一个值(toValue)变化的简单动画,好比旋转、缩放、逐渐透明、移动等。github
基本使用编程
CABasicAnimation *animation = [CABasicAnimation animation]; [animation setKeyPath:@"transform.scale"]; // 或者 CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.fromValue = @1.0; animation.toValue = @0.5; animation.duration = 0.5; animation.autoreverses = YES; animation.repeatCount = 10;
[aniView.layer addAnimation:animation forKey:@"ani_scale"];
动画的属性数组
fromValue
:属性的起始值,id类型。toValue
:属性的目标值,id类型。byValue
:属性要变化的值,也就是fromValue到toValue所改变的值。duration
:动画的持续时间。autoreverses
:动画是否有恢复动画。repeatCount
:动画重复次数,设置为HUGE_VALF表示无限次。removedOnCompletion
:是否回到初始状态,要设置fillMode为kCAFillModeForwards才起效果。fillMode
:非动画时的状态。speed
:动画的速度,默认1.0,设为2.0就是两倍的速度完成动画。timingFunction
:动画速度变化控制函数包含(Linear、EaseIn、EaseIn、EaseInEaseOut)。timeOffset
:动画的时间偏移。beginTime
:动画开始的时间,为CACurrentMediaTime() + 延迟秒数。CACurrentMediaTime()
:当前媒体时间,能够用于动画暂停和开始的时间记录。这个绝对时间就是将mach_absolute_time()(mach_absolute_time是一个CPU/总线依赖函数,返回一个基于系统启动后的时钟”嘀嗒”数。)转换成秒后的值.这个时间和系统的uptime有关,系统重启后CACurrentMediaTime()会被重置。暂停动画数据结构
- (void)pauseAnimation { CFTimeInterval stopTime = [_aniView.layer convertTime:CACurrentMediaTime() fromLayer:nil]; // 动画暂停时的媒体时间 _aniView.layer.timeOffset = stopTime; // 将偏移的时间定格在暂停时 _aniView.layer.speed = 0.0; // 将速度设为0 }
- (void)recoverAnimation { CFTimeInterval stopTime = _aniView.layer.timeOffset; _aniView.layer.timeOffset = 0; // 重置动画的时间偏移 _aniView.layer.speed = 1.0; // 恢复动画的速度 _aniView.layer.beginTime = 0; // 将beginTime清0 _aniView.layer.beginTime = [_aniView.layer convertTime:CACurrentMediaTime() fromLayer:nil] - stopTime; // 重新设置beginTime,这个时间就是暂停了多久的秒数。 }
参考:How to pause the animation of a layer treeapp
###三、关键帧动画(CAKeyframeAnimation) CAKeyframeAnimation 能够给一个图层提供多个目标值(values)或者一个指定路径(path)的动画。关键帧动画有以下几个重要参数:框架
**values
:**指定图层属性(position、scale、rotation...)的多个目标值,这个图层就会由这些指定的值进行动画。函数
**path
:**一个CGPathRef
类型的路径,指定图层就会沿着这个路径进行动画。
**keyTimes
:**关键帧指定对应的时间点,其取值范围为0到1.0。也就是keyTimes中的每个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间平分。
**calculationMode
:**关键帧之间的插值计算模式,有以下几种:
kCAAnimationLinear(线性的,两帧之间连续显示) kCAAnimationDiscrete(离散的,只在关键帧处显示) kCAAnimationPaced(强制步调一致的,keyTimes和timingFunctions设置无效) kCAAnimationCubic(两帧过分是圆滑曲线的) kCAAnimationCubicPaced(圆滑过分而且步调一致)
多个目标值的动画:
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; animation.duration = duration; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards; animation.repeatCount = 10;
NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(0, TSreenHeight/2)]; NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(TSreenWeight/2, 0)]; NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(TSreenWeight, TSreenHeight/2)]; NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(TSreenWeight/2, TSreenHeight)]; NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(0, TSreenHeight/2)]; NSArray *values = @[value1,value2,value3,value4,value5]; animation.values = values; animation.keyTimes = @[@0,@.3,@.6,@.7,@1];
[_ballImageView.layer addAnimation:rotationAnim forKey:nil];
指定路径的动画:
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; animation.duration = duration; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards; animation.repeatCount = 10;
UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(0, 160)]; CGPoint endPoint1 = CGPointMake(160, 160); CGPoint endPoint2 = CGPointMake(320, 160); CGPoint controlPoint = CGPointMake(80, 0); CGPoint controlPoint2 = CGPointMake(240, 320); [path addQuadCurveToPoint:endPoint1 controlPoint:controlPoint]; [path addQuadCurveToPoint:endPoint2 controlPoint:controlPoint2]; animation.path = path;
[imgView.layer addAnimation:keyAnimation forKey:nil];
###四、转场动画(CATransition) CATransition 用于视图的页面切换、页面更新时的转场动画,提供了多种type和subType转场效果。
type属性: 转场动画效果(API中公开的效果只有fade、moveIn、push、reveal四种,其余为私有
)。
fade
淡出效果moveIn
进入效果push
推出效果reveal
移出效果cube
立方体翻转效果suckEffect
抽走效果rippleEffect
水波效果pageCurl
翻开页效果pageUnCurl
关闭页效果cameraIrisHollowOpen
相机镜头打开效果cameraIrisHollowClose
相机镜头关闭效果subType属性: 转场的动画方向
fromLeft
或 kCATransitionFromLeft
从左过分fromRight
或 kCATransitionFromRight
从右过分fromTop
或 kCATransitionFromTop
从上过分fromBottom
或 kCATransitionFromBottom
从下过分实例代码:
CATransition *animation = [CATransition animation]; animation.duration = 0.5; animation.type = @"moveIn"; // 或者 animation.type = kCATransitionMoveIn; animation.subtype = @"fromLeft"; // 或者 animation.subtype = kCATransitionFromLeft [self.photoView.layer addAnimation:self.animation forKey:nil];
###五、动画组(CAAnimationGrup) CAAnimationGrup 能够为一个layer添加多个动画效果,要实现复杂的动画可使用用动画组的方式给layer添加动画。
实例代码
// 旋转动画 CABasicAnimation *rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; rotation.duration = 3; rotation.byValue = @(2 * M_PI); // 缩放动画 CABasicAnimation *scale = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; scale.duration = 3; scale.byValue = @2; // 变透明动画 CABasicAnimation *opacity = [CABasicAnimation animationWithKeyPath:@"opacity"]; opacity.duration = 3; opacity.byValue = @-1; // 圆角变化动画 CABasicAnimation *cornerRadius = [CABasicAnimation animationWithKeyPath:@"cornerRadius"]; cornerRadius.duration = 3; cornerRadius.byValue = @75; // 关键帧动画 CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; keyAnimation.duration = 3; NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(0, TSreenHeight/2)]; NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(TSreenWeight/2, 0)]; NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(TSreenWeight, TSreenHeight/2)]; NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(TSreenWeight/2, TSreenHeight)]; NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(0, TSreenHeight/2)]; NSArray *values = @[value1,value2,value3,value4,value5]; keyAnimation.values = values; keyAnimation.calculationMode = kCAAnimationCubic;
CAAnimationGroup *aniGroup = [CAAnimationGroup animation]; aniGroup.duration = 3; aniGroup.repeatCount = HUGE_VALF; aniGroup.animations = @[rotation, scale, opacity, cornerRadius, keyAnimation]; [self.aniView.layer addAnimation:aniGroup forKey:nil];
###六、动画画轨迹(CAShapeLayer添加动画)
CAShapeLayer 是 CALayer 的子类,能够根据设定的path画出对应的图形、曲线等,还能够添加动画,实现动画画图。
CAShapeLayer属性:
path
: 图像所依赖的路径,CGPathRef类型fillColor
: 图形填充颜色fillRule
: 填充的类型strokeColor
:**描边的颜色lineWidth
:线条的宽度lineCap
: 线条端点的样式lineJoin
: 两个连接点的样式miterLimit
: 两条线链接时斜接的长度strokeStart
: 绘制的起点,取值范围[0~1],默认0strokeEnd
: 绘制的终点,取值范围[0~2],默认1CAShapeLayer画图:
// 1.建立条内切圆路径 UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 200)]; // 2.建立CAShapeLayer图层并设置属性 CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.frame = CGRectMake(0, 0, 200, 200); shapeLayer.path = path.CGPath; shapeLayer.fillColor = [UIColor clearColor].CGColor; shapeLayer.strokeColor = [UIColor redColor].CGColor; shapeLayer.lineWidth = 10.0f; shapeLayer.lineCap = kCALineCapRound; shapeLayer.strokeStart = 0.25; shapeLayer.strokeEnd = 1; // 3.添加图层 [self.view.layer addSublayer:shapeLayer];
// 4.给shapeLayer的strokeStart 或者 strokeEnd 属性添加动画,就能够实现动画画图了。 CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards; animation.duration = 3; animation.fromValue = @0; animation.toValue = @1; [shapeLayer addAnimation:animation forKey:@"ani_strokeStart"];
###七、核心动画Demo
####Demo下载地址:https://github.com/fuqinglin/CoreAnimationDemos.git