美文网首页
CoreAnimation

CoreAnimation

作者: 傲骨天成科技 | 来源:发表于2020-04-03 15:46 被阅读0次

    一、核心动画介绍

    CoreAnimation框架是基于OpenGL与CoreGraphics图像处理框架的一个跨平台的动画框架。
    在CoreAnimation中大部分的动画都是通过Layer层来实现的,通过CALayer,我们可以组织复杂的层级结构。
    在CoreAnimation中,大多数的动画效果是添加在图层属性的变化上,例如,改变图层的位置,大小,颜色,圆角半径等。Layer层并不决定视图的展现,它只是存储了视图的几何属性状态。

    下图展示了我们常用的核心动画的继承关系


    截屏2020-04-03下午2.01.16.png

    CAAnimation:核心动画的基础类,不能直接使用,负责动画运行时间、速度的控制。
    CAPropertyAnimation: 属性动画的基础类。
    CABasicAnimation: 基础动画,通过属性修改来控制动画,不能控制动画的中间状态。
    CAKeyframAnimation: 关键帧动画,通过属性进行控制动画,但是可以控制动画的中间状态。
    CASpringAnimation: 弹簧动画。
    CAAnimationGroup: 动画组,可以动过它来实现一组动画一起播放。

    二、动画的各个属性介绍

    fromValue : 动画的开始值(Any类型, 根据动画不同可以是CGPoint、NSNumber等)

    toValue: 动画的结束值, 和fromValue类似

    beginTime: 动画的开始时间

    duration : 动画的持续时间

    repeatCount : 动画的重复次数

    fillMode: 动画的运行场景

    isRemovedOnCompletion: 完成后是否删除动画,当制作loading的时候,需要设置为NO,默认YES,当动画执行完成之后就移除动画

    autoreverses: 执行的动画按照原动画返回执行

    path:关键帧动画中的执行路径

    values: 关键帧动画中的关键点数组

    animations: 组动画中的动画数组

    delegate : 动画代理, 封装了动画的执行和结束方法

    timingFunction: 控制动画的显示节奏, 系统提供五种值选择,分别是:

    kCAMediaTimingFunctionDefault( 默认,中间快)
    kCAMediaTimingFunctionLinear (线性动画)
    kCAMediaTimingFunctionEaseIn (先慢后快 慢进快出)
    kCAMediaTimingFunctionEaseOut (先块后慢快进慢出)
    kCAMediaTimingFunctionEaseInEaseOut (先慢后快再慢)
    type: 过渡动画的动画类型,系统提供了多种过渡动画, 分别是:

    fade (淡出 默认)
    moveIn (覆盖原图)
    push (推出)
    fade (淡出 默认)
    reveal (底部显示出来)
    cube (立方旋转)
    suck (吸走)
    oglFlip (水平翻转 沿y轴)
    ripple (滴水效果)
    curl (卷曲翻页 向上翻页)
    unCurl (卷曲翻页返回 向下翻页)
    caOpen (相机开启)
    caClose (相机关闭)
    subtype : 过渡动画的动画方向, 系统提供了四种,分别是:

    fromLeft( 从左侧)
    fromRight (从右侧)
    fromTop (有上面)
    fromBottom (从下面)
    mass: 质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大

    stiffness:弹簧动画的刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快

    damping:阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快

    initialVelocity:初始速率,动画视图的初始速度大小
    速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反

    settlingDuration:结算时间 返回弹簧动画到停止时的估算时间,根据当前的动画参数估算

    三、CoreAnimation使用

    1.基础动画 CABasicAnimation

    基础动画主要提供了对于CALayer对象中的可变属性进行简单动画的操作。比如:位移、旋转、缩放、透明度、背景色等。
    基础动画根据 keyPath 来区分不同的动画, 系统提供了多个类型,如:
    基础动画根据 keyPath 来区分不同的动画, 系统提供了多个类型,如: transform.scale (比例转换)、transform.scale.x、transform.scale.y、 transform.rotation(旋转) 、transform.rotation.x(绕x轴旋转)、transform.rotation.y(绕y轴旋转)、transform.rotation.z(绕z轴旋转)、opacity (透明度)、margin、backgroundColor(背景色)、cornerRadius(圆角)、borderWidth(边框宽)、bounds、contents、contentsRect、cornerRadius、frame、hidden、mask、masksToBounds、shadowColor(阴影色)、shadowOffset、shadowOpacity, 在使用时候, 需要根据具体的需求选择合适的。

    旋转动画

    CABasicAnimation *animation = [[CABasicAnimation alloc] init];
        
        animation.keyPath = @"transform.rotation.z";
        
        animation.toValue = @(M_PI/180.0 * 50.0);
        
        animation.duration = 1.0;
        animation.repeatCount = MAXFLOAT;
        animation.fillMode = @"forwards"; //只在前台
        [animation setRemovedOnCompletion:NO]; //切出界面再回来动画不会停止
        [self.moveView.layer addAnimation:animation forKey:@""];
    

    位移动画

    CABasicAnimation *animation = [[CABasicAnimation alloc] init];
        
        animation.keyPath = @"position";
        
        animation.fromValue = [NSValue valueWithCGPoint:self.moveView.center];
        
        animation.toValue = [NSValue valueWithCGPoint:CGPointMake(150, 400)];
        
        animation.duration = 1.0;
        
        [self.moveView.layer addAnimation:animation forKey:@""];
    

    2.关键帧动画 CAKeyframAnimation

    CAKeyframeAnimation 和 CABasicAnimation 都属于CAPropertyAnimatin 的子类。不同的是 CABasicAnimation 只能从一个数值(fromValue)变换成另一个数值(toValue),而 CAKeyframeAnimation 则会使用一个数组(values) 保存一组关键帧, 也可以给定一个路径(path)制作动画。

    CAKeyframeAnimation主要有 三个 重要属性:

    values:存放关键帧(keyframe)的数组,动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧 .
    path:可以设置一个 CGPathRef 或 CGMutablePathRef,让层跟着路径移动. path 只对 CALayer 的 anchorPoint 和 position 起作用, 如果设置了path,那么values将被忽略.
    keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0, keyTimes 中的每一个时间值都对应 values 中的每一帧.当 keyTimes 没有设置的时候,各个关键帧的时间是根据 duration 平分的。

    路径动画

    CAKeyframeAnimation *animation = [[CAKeyframeAnimation alloc] init];
        // 设置的是路径
        animation.keyPath = @"position";
        
        // 持续时间
        animation.duration = 2.0;
        
        // 重复次数
        animation.repeatCount = 3;
    
        
        /*
         timingFunction: 控制动画的显示节奏, 系统提供五种值选择,分别是:
    
         kCAMediaTimingFunctionDefault( 默认,中间快)
         kCAMediaTimingFunctionLinear (线性动画)
         kCAMediaTimingFunctionEaseIn (先慢后快 慢进快出)
         kCAMediaTimingFunctionEaseOut (先块后慢快进慢出)
         kCAMediaTimingFunctionEaseInEaseOut (先慢后快再慢)
         */
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
        
        // 路径圆形
    //    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(kScreenW/2.0, kScreenH/2.0) radius:60 startAngle:0.0 endAngle:M_PI * 2 clockwise:YES];
        
        // 二次曲线
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:self.moveView.center];
        [path addQuadCurveToPoint:CGPointMake(40, kScreenH - 80) controlPoint:CGPointMake(80, 0)];
        
        // 添加路径
        animation.path = path.CGPath;
        
        // 添加动画  这个key其实就是个标记,可以随意些
        [self.moveView.layer addAnimation:animation forKey:@"pathAnimation"];
    

    设置关键点动画

    CAKeyframeAnimation *animation = [[CAKeyframeAnimation alloc] init];
        // 设置的是路径 这个keyPath其实就是layer的属性
        animation.keyPath = @"position";
        
        // 设置关键的点坐标
        CGPoint point0 = CGPointMake(kScreenW, 100);
        CGPoint point1 = CGPointMake(kScreenW - 20, 50);
        CGPoint point2 = CGPointMake(kScreenW - 100, 30);
        CGPoint point3 = CGPointMake(150, 50);
        CGPoint point4 = CGPointMake(120, 150);
        CGPoint point5 = CGPointMake(40, kScreenH - 80);
        
        // 将关键点添加进数组
        animation.values = @[[NSValue valueWithCGPoint:point0], [NSValue valueWithCGPoint:point1], [NSValue valueWithCGPoint:point2], [NSValue valueWithCGPoint:point3], [NSValue valueWithCGPoint:point4], [NSValue valueWithCGPoint:point5]];
        
        animation.duration = 2;
        
        // 这个key其实就是个标记,可以随意些
        [self.moveView.layer addAnimation:animation forKey:@"keyFrameAnimation"];
    

    3.弹簧动画

    CASpringAnimation *animation = [[CASpringAnimation alloc] init];
        animation.keyPath = @"position.x";
        // 阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快
        animation.damping = 5;
        
        // 弹簧动画的刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快
        animation.stiffness = 100;
        
        // 质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大
        animation.mass = 1;
        
        // 初始速率,动画视图的初始速度大小
        // 速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反
        animation.initialVelocity = 0;
        
        animation.fromValue = [NSNumber numberWithFloat:self.moveView.layer.position.x];
        
        animation.toValue = [NSNumber numberWithFloat:self.moveView.layer.position.x + 50];
        
        // 结算时间 返回弹簧动画到停止时的估算时间,根据当前的动画参数估算
        // 通常弹簧动画的时间使用结算时间比较准确
        animation.duration = animation.settlingDuration;
        
        [self.moveView.layer addAnimation:animation forKey:@""];
    

    4.动画组 CAAnimationGroup

    CAAnimationGroup 是 CAAnimation 的子类,可以保存一组动画对象,可以保存基础动画、关键帧动画等,数组中所有动画对象可以同时并发运行, 也可以通过实践设置为串行连续动画.

    同时动画

    CAKeyframeAnimation *animation = [[CAKeyframeAnimation alloc] init];
        // 设置的是路径 这个keyPath其实就是layer的属性
        animation.keyPath = @"position";
        
        // 设置关键的点坐标
        CGPoint point0 = CGPointMake(kScreenW, 100);
        CGPoint point1 = CGPointMake(kScreenW - 20, 50);
        CGPoint point2 = CGPointMake(kScreenW - 100, 30);
        CGPoint point3 = CGPointMake(150, 50);
        CGPoint point4 = CGPointMake(120, 150);
        CGPoint point5 = CGPointMake(40, kScreenH - 80);
        
        // 将关键点添加进数组
        animation.values = @[[NSValue valueWithCGPoint:point0], [NSValue valueWithCGPoint:point1], [NSValue valueWithCGPoint:point2], [NSValue valueWithCGPoint:point3], [NSValue valueWithCGPoint:point4], [NSValue valueWithCGPoint:point5]];
        // 如果设置单独设置了时长,则CAAnimationGroup设置的时长无效
    //    animation.duration = 2;
        
        
        
        
        CABasicAnimation *animation1 = [[CABasicAnimation alloc] init];
        
        animation1.keyPath = @"transform.scale";
        
        animation1.toValue = @(2);
        // 如果设置单独设置了时长,则CAAnimationGroup设置的时长无效
    //    animation1.duration = 1.0;
        
        CAAnimationGroup *animationGroup = [[CAAnimationGroup alloc] init];
        animationGroup.animations = @[animation, animation1];
        animationGroup.duration = 5;
        
        [self.moveView.layer addAnimation:animationGroup forKey:@""];
    

    连续动画
    注意:使用了CACurrentMediaTime()和animation.beginTime

    // 当前时间
        CFTimeInterval currentTime = CACurrentMediaTime();
        
        CAKeyframeAnimation *animation = [[CAKeyframeAnimation alloc] init];
        // 设置的是路径 这个keyPath其实就是layer的属性
        animation.keyPath = @"position";
        
        // 设置关键的点坐标
        CGPoint point0 = CGPointMake(kScreenW, 100);
        CGPoint point1 = CGPointMake(kScreenW - 20, 50);
        CGPoint point2 = CGPointMake(kScreenW - 100, 30);
        CGPoint point3 = CGPointMake(150, 50);
        CGPoint point4 = CGPointMake(120, 150);
        CGPoint point5 = CGPointMake(40, kScreenH - 80);
        
        // 将关键点添加进数组
        animation.values = @[[NSValue valueWithCGPoint:point0], [NSValue valueWithCGPoint:point1], [NSValue valueWithCGPoint:point2], [NSValue valueWithCGPoint:point3], [NSValue valueWithCGPoint:point4], [NSValue valueWithCGPoint:point5]];
        
        animation.duration = 1;
        /// 动画开始时间
        animation.beginTime = currentTime;
        [self.moveView.layer addAnimation:animation forKey:@""];
        
        
        
        CABasicAnimation *animation1 = [[CABasicAnimation alloc] init];
        animation1.keyPath = @"transform.scale";
        animation1.toValue = @(2);
        // 如果设置单独设置了时长,则CAAnimationGroup设置的时长无效
        animation1.duration = 1.0;
        
        // 动画开始时间
        animation1.beginTime = currentTime + 1;
        
        [self.moveView.layer addAnimation:animation1 forKey:@""];
    

    5.过渡动画 CATransition

    CATransition 是 CAAnimation 的子类,用于做过渡动画或者 转场 动画,能够为层提供移出屏幕和移入屏幕的动画效果。

    过渡动画通过 type 设置不同的动画效果, CATransition 有多种过渡效果, 但其实 Apple 官方的SDK只提供了四种:

    fade 淡出 默认
    moveIn 覆盖原图
    push 推出
    reveal 底部显示出来
    但私有API提供了其他很多非常炫的过渡动画,如 cube(立方旋转)、suckEffect(吸走)、oglFlip(水平翻转 沿y轴)、 rippleEffect(滴水效果)、pageCurl(卷曲翻页 向上翻页)、pageUnCurl(卷曲翻页 向下翻页)、cameraIrisHollowOpen(相机开启)、cameraIrisHollowClose(相机关闭)等。
    注: 因 Apple 不提供维护,并且有可能造成你的app审核不通过, 所以不建议开发者们使用这些私有API.

    /// 过渡动画
        CATransition *animation = [[CATransition alloc] init];
        
        /// 立体旋转,私有的API
        animation.type = @"cube";
        
        /// 翻转方向
        animation.subtype = @"fromRight";
        
        animation.duration = 1.0;
        
        [self.moveView.layer addAnimation:animation forKey:@""];
    

    三、总结

    所有的复杂动画都是这些简单的动画组成的,结合动画组使用就能实现你需要的效果。

    相关文章

      网友评论

          本文标题:CoreAnimation

          本文链接:https://www.haomeiwen.com/subject/vdnhphtx.html