核心动画(CAAnimation)代码详解

核心动画,很早之前就想整理了,一直没整理,今天有时间,整理了下.官方文档是这么说的:下图就介绍了各个animation之间的关系


,官方文档中给了我们很多这个基础动画可以改变的属性,如下:



我自己整理了几个常用的属性

    //CATransform3D Key Paths : (example)transform.rotation.z
      //rotation.x
      //rotation.y
      //rotation.z
      //rotation 旋轉
      //scale.x
      //scale.y
      //scale.z
      //scale 缩放
      //translation.x
      //translation.y
      //translation.z
      //translation 平移
      //CGPoint Key Paths : (example)position.x
      //x
      //y
      //CGRect Key Paths : (example)bounds.size.width
      //origin.x
      //origin.y
      //origin
      //size.width
      //size.height
      //size
      //opacity
      //backgroundColor
      //cornerRadius 
      //borderWidth
      //contents 
      //Shadow Key Path:
      //shadowColor 
      //shadowOffset 
      //shadowOpacity 
      //shadowRadius
官方文档中的geg
代码如下:

static NSString *position = @"position";
static NSString *opacity = @"opacity";
static NSString *transformX = @"transform.scale.x";
static NSString *backgroundColor = @"backgroundColor";
static NSString *transformY = @"transform.scale.y";

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self addSubview:self.mLabel];
        [self addSubview:self.mButton];

        CABasicAnimation *positionAni= [CABasicAnimation animationWithKeyPath:position];
        positionAni.fromValue = @[@200,@70];
        positionAni.toValue = @[@200,@200];
        positionAni.duration = 2.f;
        /*
         Determines if the receiver’s presentation is frozen or removed once its active duration has completed.
         动画周期完成后动画的状态,
         
         /* `fillMode' options.
            kCAFillModeForwards  //forwards -----show(视觉上)
            kCAFillModeBackwards //backwards-----remove(视觉上)
            kCAFillModeBoth      //show
            kCAFillModeRemoved   //default remove
         */
        positionAni.fillMode = kCAFillModeForwards;
        /* When true, the animation is removed from the render tree once its
         * active duration has passed. Defaults to YES.  动画时间到了之后删除动画*/
        positionAni.removedOnCompletion = NO;
       // timingFunction:动画的时间节奏控制
       /*
 timingFunctionName的enum值如下:
     kCAMediaTimingFunctionLinear 匀速
     kCAMediaTimingFunctionEaseIn 慢进
     kCAMediaTimingFunctionEaseOut 慢出
     kCAMediaTimingFunctionEaseInEaseOut 慢进慢出
     kCAMediaTimingFunctionDefault 默认值(慢进慢出)
     */
        positionAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        [_mLabel.layer addAnimation:positionAni forKey:position];
        
        
        //backgroundColor //这里有一个坑,创建控件的时候不能设置背景色,不然没法通过这个属性改变动画了
        CABasicAnimation *backAni = [CABasicAnimation animationWithKeyPath:backgroundColor];
        backAni.fromValue = (__bridge id _Nullable)([[UIColor blueColor]CGColor]);
        backAni.toValue = (__bridge id _Nullable)([[UIColor lightGrayColor] CGColor]);
        
        backAni.fromValue = CFBridgingRelease([[UIColor blueColor] CGColor]);
        backAni.toValue = CFBridgingRelease([[UIColor lightGrayColor] CGColor]);
        
        backAni.removedOnCompletion = NO;
        backAni.fillMode = kCAFillModeForwards;
        backAni.duration = 2.f;
        [_mLabel.layer addAnimation:backAni forKey:backgroundColor];
        
        //opacity
        CABasicAnimation *opacityAni = [CABasicAnimation animationWithKeyPath:opacity];
        opacityAni.fromValue = @1.f;
        opacityAni.toValue = @0.2f;
        opacityAni.duration = 2.f;
        opacityAni.removedOnCompletion = NO;
        opacityAni.fillMode = kCAFillModeForwards;
        [_mLabel.layer addAnimation:opacityAni forKey:opacity];
        
        //transform____X 这个transform.scale.x的变化意思是控件宽的多少倍
        CABasicAnimation *transAniX = [CABasicAnimation animationWithKeyPath:transformX];
        transAniX.fromValue = @1;
        transAniX.toValue = @1.5; //原控件宽的1.5倍放大
        transAniX.duration = 2.f;
        transAniX.removedOnCompletion = NO;
        transAniX.fillMode = kCAFillModeForwards;
        [_mLabel.layer addAnimation:transAniX forKey:transformX];
       
        //transform____Y 这个transform.scale.x的变化意思是控件高的多少倍
        CABasicAnimation *transAniY = [CABasicAnimation animationWithKeyPath:transformY];
        transAniY.fromValue = @1;
        transAniY.toValue = @2;//原控件高的2倍放大
        transAniY.duration = 2.f;
        transAniY.removedOnCompletion = NO;
        transAniY.fillMode = kCAFillModeForwards;
        [_mLabel.layer addAnimation:transAniY forKey:transformY];
        
          //移除动画
        [_mLabel.layer removeAllAnimations];
        [_mLabel.layer removeAnimationForKey:opacity];
        
                
        //values改变动画
        
        CAKeyframeAnimation *keyframeAni = [CAKeyframeAnimation animationWithKeyPath:position];
        keyframeAni.duration = 5.f;
        NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
        NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(150, 200)];
        NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(150, 300)];
        NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(100, 300)];
        NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
        NSArray *valueArr = @[value1,value2,value3,value4,value5];
        keyframeAni.values = valueArr;
        keyframeAni.fillMode = kCAFillModeForwards;
        keyframeAni.removedOnCompletion = NO;
     //   [_mLabel.layer addAnimation:keyframeAni forKey:position];
        
        
        //path改变动画
        
        CAKeyframeAnimation *pathKeyframeAni = [CAKeyframeAnimation animationWithKeyPath:position];
        pathKeyframeAni.duration = 5.f;
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddEllipseInRect(path, NULL, CGRectMake(140, 200, 100, 100));
        pathKeyframeAni.path = path;
        CGPathRelease(path);
        pathKeyframeAni.removedOnCompletion = NO;
        pathKeyframeAni.fillMode = kCAFillModeForwards;
     //   [_mLabel.layer addAnimation:pathKeyframeAni forKey:position];
        
        //group  可以把几种动画放到一个数组中给group
        CAAnimationGroup *group = [CAAnimationGroup animation];
        group.animations = @[positionAni,opacityAni,backAni];
        group.duration = 5.f;
        group.fillMode = kCAFillModeForwards;
        group.removedOnCompletion = NO;
        group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        [_mLabel.layer addAnimation:group forKey:@""];
    }
    return self;
}

- (UILabel *)mLabel {
    if (!_mLabel) {
        _mLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 400, 150, 50)];
        _mLabel.backgroundColor = [UIColor redColor];
        _mLabel.text = @"This is a label";
        _mLabel.userInteractionEnabled = YES;
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelTapClick:)];
        [_mLabel addGestureRecognizer:tap];
    }
    return _mLabel;
}

- (UIButton *)mButton {
    if (!_mButton) {
        _mButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _mButton.backgroundColor = [UIColor blueColor];
        [_mButton setFrame:CGRectMake(30, 300, 59, 40)];
        [_mButton setTitle:@"button" forState:UIControlStateNormal];
        [_mButton addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _mButton;
}

- (UIImageView *)mImageView {
    if (!_mImageView) {
        _mImageView = [[UIImageView alloc] initWithFrame:CGRectMake(50, 100, 100, 50)];
        [_mImageView setImage:[UIImage imageNamed:@"wade.jpg"]];
        _mImageView.userInteractionEnabled = YES;
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapClick:)];
        [_mImageView addGestureRecognizer:tap];
    }
    return _mImageView;
}

#pragma mark === private func

- (void)btnClick:(UIButton *)sender {
    CASpringAnimation *spring = [CASpringAnimation animationWithKeyPath:@"bounds"];
    spring.toValue = [NSValue valueWithCGRect:CGRectMake(self.mButton.frame.origin.x, self.mButton.frame.origin.y, CGRectGetWidth(self.mButton.frame)*1.5, CGRectGetHeight(self.mButton.frame)*1.5)];
    spring.mass = 10; //质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大
    spring.damping = 100; //阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快(刹车片)
    spring.initialVelocity = 5;//开始的速率,速率为正,速度方向和运动方向一致,速率为负,相反
    spring.stiffness = 5000; //刚度系数,刚度系数越大,形变产生的力就越大,运动越快
    spring.duration = spring.settlingDuration;
    [self.mButton.layer addAnimation:spring forKey:spring.keyPath];
}

- (void)tapClick:(UITapGestureRecognizer *)tap {
     /* Common transition types.
        kCATransitionFade
        kCATransitionMoveIn
        kCATransitionPush
        kCATransitionReveal
     */
    
    /* Common transition subtypes.
        kCATransitionFromRight
        kCATransitionFromLeft
        kCATransitionFromTop
        kCATransitionFromBottom
    */
    
   /* //转场动画
    CATransition *transition = [CATransition animation];
    transition.type = kCATransitionPush;
    transition.subtype = kCATransitionFromLeft;
    transition.startProgress = 0.1;
    transition.endProgress = 1.f;
    transition.duration = 0.f; //导航跳转
    transition.fillMode = kCAFillModeForwards;
    transition.removedOnCompletion = NO;
     _mImageView.image = [UIImage imageNamed:@"kb.jpg"];
    [_mImageView.layer addAnimation:transition forKey:@"transition"];
    */
    // 弹簧效果
    CASpringAnimation *spring = [CASpringAnimation animationWithKeyPath:@"bounds"];
    spring.toValue = [NSValue valueWithCGRect:CGRectMake(self.mImageView.frame.origin.x, self.mImageView.frame.origin.y, CGRectGetWidth(self.mImageView.frame)*1.5, CGRectGetHeight(self.mImageView.frame)*1.5)];
    spring.mass = 10;
    spring.damping = 100;
    spring.initialVelocity = 5;
    spring.stiffness = 5000;
    spring.duration = spring.settlingDuration;
    spring.removedOnCompletion = YES;
    spring.fillMode = kCAFillModeBoth;
    [self.mImageView.layer addAnimation:spring forKey:spring.keyPath];
    
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值