• CAKeyframeAnimation——关键帧动画和动画组~


    •关键帧动画,也是CAPropertyAnimation的子类,与CABasicAnimation的区别是:
    –CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值
    •属性说明:
    –values:上述的NSArray对象。里面的元素称为“关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧
    –path:可以设置一个CGPathRef、CGMutablePathRef,让图层按照路径轨迹移动。path只对CALayer的anchorPoint和position起作用。如果设置了path,那么values将被忽略
    –keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧。如果没有设置keyTimes,各个关键帧的时间是平分的
    •CABasicAnimation可看做是只有2个关键帧的CAKeyframeAnimation
    ==========================
     
    •在关键帧动画中还有一个非常重要的参数,那便是calculationMode,所谓计算模式:其主要针对的是每一帧的内容为一个座标点的情况,也就是对anchorPoint和 position进行的动画
    •当在平面座标系中有多个离散的点的时候,可以是离散的,也可以直线相连后进行插值计算,也可以使用圆滑的曲线将他们相连后进行插值计算
    •calculationMode目前提供如下几种模式:
    –kCAAnimationLinear 默认值,表示当关键帧为座标点的时候,关键帧之间直接直线相连进行插值计算
    –kCAAnimationDiscrete 离散的,不进行插值计算,所有关键帧直接逐个进行显示
    –kCAAnimationPaced 使得动画均匀进行,而不是按keyTimes设置的或者按关键帧平分时间,此时keyTimes和timingFunctions无效
    –kCAAnimationCubic 对关键帧为座标点的关键帧进行圆滑曲线相连后插值计算,这里的主要目的是使得运行的轨迹变得圆滑
    –kCAAnimationCubicPaced 看这个名字就知道和kCAAnimationCubic有一定联系,其实就是在kCAAnimationCubic的基础上使得动画运行变得均匀,就是系统时间内运动的距离相同,此时keyTimes以及timingFunctions也是无效的
    •注意:就目前而言,此属性研究的意义不大,知道有这么一个属性即可,只有再做复杂动画,同时动画效果不够理想的时候,才需要考虑使用这一属性
     
    ===========================================
     
    关键帧动画添加完途经点以后,中间状态有系统自动计算完成,下面是一个很简单的添加帧动画的demo
    // 增加一个中间点
        // 中心点用个随机点
        // 1. 动画
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        
        NSValue *p1 = [NSValue valueWithCGPoint:self.center];
        NSValue *p2 = [NSValue valueWithCGPoint:[self randomPoint]];
        NSValue *p3 = [NSValue valueWithCGPoint:to];
        
        anim.values = @[p1, p2, p3];
        
        anim.duration = 1.0f;
        
        anim.removedOnCompletion = NO;
        anim.fillMode = kCAFillModeForwards;
        
        anim.delegate = self;
        
        [self.layer addAnimation:anim forKey:nil];

    下面是一个用帧动画做出摇动动画的demo

    - (void)shake
    {
        // 1. 动画
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
        
        // 2. 设置角度
        CGFloat angle = M_PI_4 / 10;
        
        anim.values = @[@(-angle), @(angle), @(-angle)];
        
        anim.duration = 0.2f;
        anim.repeatCount = HUGE_VALF;
        
        [self.layer addAnimation:anim forKey:nil];
    }

    关键帧动画还可以沿着CGPath类型的路径进行动画

    #pragma mark - 按照路径平移的关键帧动画
    - (CAKeyframeAnimation *)moveWithPath:(CGPathRef)path duration:(NSTimeInterval)duration
    {
        // 1. 动画
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        
        // 2. 设置路径
        anim.path = path;
        
        // 3. 设置时长
        anim.duration = duration;
        
        return anim;
    }

    动画组是一组动画的合成,他可以合并多个动画,然后添加到图层上,让多个动画同时执行

    下面是一个动画组的小demo

    - (void)groupDemo
    {
        /**
         群组动画可以将一组动画继承在一起,并发执行,产生更加复杂的动画效果
         
         需要注意的是,群组中的动画,不能修改同一个keyPath
         */
        // 实例化一个动画组
        CAAnimationGroup *group = [[CAAnimationGroup alloc] init];
        
        // 透明度动画
        CABasicAnimation *alpha = [CABasicAnimation animationWithKeyPath:@"opacity"];
        
        alpha.fromValue = @(1.0);
        alpha.toValue = @(0.5);
        
        // 旋转动画
        CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
        
        rotate.toValue = @(2 * M_PI);
        
        // 关键帧动画
        CAKeyframeAnimation *keyAnim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddEllipseInRect(path, NULL, CGRectMake(100, 100, 200, 300));
        
        keyAnim.path = path;
        
        // 释放路径
        CGPathRelease(path);
        
        group.animations = @[alpha, keyAnim, rotate];
        group.duration = 1.0f;
        
        [_myView.layer addAnimation:group forKey:nil];
    }
  • 相关阅读:
    Redis--过期键策略(惰性删除、定期删除)
    Redis--数据库(个数16、键空间、过期字典、过期策略)
    Redis--事件(serverCron)
    ArrayList是如何扩容的?
    Java的四大引用类型
    类加载机制,双亲委派模型及其优点
    GC调优思路
    modcount的作用
    JVM的常见的垃圾收集器
    什么是临界区?如何解决冲突(也就是临界区的调度原则)?
  • 原文地址:https://www.cnblogs.com/xyzaijing/p/3855177.html
Copyright © 2020-2023  润新知