酷炫登录动画效果

作者: Fendouzhe | 来源:发表于2018-01-22 15:34 被阅读207次

    登录效果:


    效果.gif

    登录界面背景使用CAGradientLayer实现,动画主要使用CAShapeLayer和UIBezierPath组合来实现,通过UIBezierPath改变CAShapeLayer的path实现形变动画,通过opacity实现渐变消失动画,有兴趣的朋友可以前往github下载查看,喜欢可以star谢谢!这里贴出登录按钮动画核心代码:

    #import "LRButton.h"
    
    @interface LRButton()
    
    //渲染层
    @property (nonatomic,strong) CAShapeLayer *maskLayer;
    
    @property (nonatomic,strong) CAShapeLayer *shapeLayer;
    
    @property (nonatomic,strong) CAShapeLayer *loadingLayer;
    
    @property (nonatomic,strong) CAShapeLayer *clickCicrleLayer;
    
    @property (nonatomic,strong) UIButton *button;
    
    @end
    
    
    @implementation LRButton
    
    -(instancetype)initWithFrame:(CGRect)frame{
        if(self = [super initWithFrame:frame]){
            _shapeLayer = [self drawMask:frame.size.height/2];
            _shapeLayer.fillColor = [UIColor clearColor].CGColor;
            _shapeLayer.strokeColor = [UIColor whiteColor].CGColor;
            _shapeLayer.lineWidth = 2;
            [self.layer addSublayer:_shapeLayer];
            
            [self.layer addSublayer:self.maskLayer];
            
            _button = [UIButton buttonWithType:UIButtonTypeCustom];
            _button.frame = self.bounds;
            [_button setTitle:@"SIGN IN" forState:UIControlStateNormal];
            [_button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
            _button.titleLabel.font = [UIFont systemFontOfSize:13.f];
            [self addSubview:_button];
            [_button addTarget:self action:@selector(clickBtn) forControlEvents:UIControlEventTouchUpInside];
        }
        return self;
    }
    
    -(CAShapeLayer *)maskLayer{
        if(!_maskLayer){
            _maskLayer = [CAShapeLayer layer];
            _maskLayer.opacity = 0;
            _maskLayer.fillColor = [UIColor whiteColor].CGColor;
            _maskLayer.path = [self drawBezierPath:self.frame.size.width/2].CGPath;
        }
        return _maskLayer;
    }
    
    -(void)layoutSubviews{
        [super layoutSubviews];
        
    }
    
    
    ///按钮点击
    -(void)clickBtn{
        [self clickAnimation];
    }
    
    -(void)clickAnimation{
        CAShapeLayer *clickCicrleLayer = [CAShapeLayer layer];
        clickCicrleLayer.position = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
        clickCicrleLayer.fillColor = [UIColor whiteColor].CGColor;
        clickCicrleLayer.path = [self drawclickCircleBezierPath:0].CGPath;
        [self.layer addSublayer:clickCicrleLayer];
        
        CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
        basicAnimation.duration = 0.15;
        basicAnimation.toValue = (__bridge id _Nullable)([self drawclickCircleBezierPath:(self.bounds.size.height - 10*2)/2].CGPath);
        basicAnimation.removedOnCompletion = NO;
        basicAnimation.fillMode = kCAFillModeForwards;
    
        [clickCicrleLayer addAnimation:basicAnimation forKey:@"clickCicrleAnimation"];
        
        _clickCicrleLayer = clickCicrleLayer;
        
        [self performSelector:@selector(clickNextAnimation) withObject:self afterDelay:basicAnimation.duration];
    }
    
    -(void)clickNextAnimation{
        _clickCicrleLayer.fillColor = [UIColor clearColor].CGColor;
        _clickCicrleLayer.strokeColor = [UIColor whiteColor].CGColor;
        _clickCicrleLayer.lineWidth = 10;
        
        CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
        //绘制大圆半径 self.bounds.size.height - 10*2
        CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
        basicAnimation.duration = 0.15;
        basicAnimation.toValue = (__bridge id _Nullable)([self drawclickCircleBezierPath:(self.bounds.size.height - 10*2)].CGPath);
        basicAnimation.removedOnCompletion = NO;
        basicAnimation.fillMode = kCAFillModeForwards;
        
        CABasicAnimation *basicAnimation1 = [CABasicAnimation animationWithKeyPath:@"opacity"];
        basicAnimation1.beginTime = 0.10;
        basicAnimation1.duration = 0.15;
        basicAnimation1.toValue = @0;
        basicAnimation1.removedOnCompletion = NO;
        basicAnimation1.fillMode = kCAFillModeForwards;
        
        animationGroup.duration = basicAnimation1.beginTime + basicAnimation1.duration;
        animationGroup.removedOnCompletion = NO;
        animationGroup.fillMode = kCAFillModeForwards;
        animationGroup.animations = @[basicAnimation,basicAnimation1];
        
        [_clickCicrleLayer addAnimation:animationGroup forKey:@"clickCicrleAnimation1"];
    
        [self performSelector:@selector(startMaskAnimation) withObject:self afterDelay:animationGroup.duration];
        
    }
    
    -(void)startMaskAnimation{
        _maskLayer.opacity = 0.15;
        CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
        basicAnimation.duration = 0.25;
        //绘制按钮形状
        basicAnimation.toValue = (__bridge id _Nullable)([self drawBezierPath:self.frame.size.height/2].CGPath);
        basicAnimation.removedOnCompletion = NO;
        basicAnimation.fillMode = kCAFillModeForwards;
        [_maskLayer addAnimation:basicAnimation forKey:@"maskAnimation"];
        
        [self performSelector:@selector(dismissAnimation) withObject:self afterDelay:basicAnimation.duration+0.2];
    }
    
    -(void)dismissAnimation{
        [self removeSubViews];
        
        CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
        
        CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
        basicAnimation.duration = 0.15;
        //变成一个圆
        basicAnimation.toValue = (__bridge id _Nullable)([self drawBezierPath:self.frame.size.width/2].CGPath);
        basicAnimation.removedOnCompletion = NO;
        basicAnimation.fillMode = kCAFillModeForwards;
        
        CABasicAnimation *basicAnimation1 = [CABasicAnimation animationWithKeyPath:@"opacity"];
        basicAnimation1.beginTime = 0.10;
        basicAnimation1.duration = 0.15;
        basicAnimation1.toValue = @0;
        basicAnimation1.removedOnCompletion = NO;
        basicAnimation1.fillMode = kCAFillModeForwards;
        
        animationGroup.animations = @[basicAnimation,basicAnimation1];
        animationGroup.duration = basicAnimation1.beginTime+basicAnimation1.duration;
        animationGroup.removedOnCompletion = NO;
        animationGroup.fillMode = kCAFillModeForwards;
        [_shapeLayer addAnimation:animationGroup forKey:@"dismissAnimation"];
        
        [self performSelector:@selector(loadingAnimation) withObject:self afterDelay:animationGroup.duration];
    }
    
    
    
    -(void)loadingAnimation{
        
        //旋转圆弧
        _loadingLayer = [CAShapeLayer layer];
        _loadingLayer.position = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
        _loadingLayer.fillColor = [UIColor clearColor].CGColor;
        _loadingLayer.strokeColor = [UIColor whiteColor].CGColor;
        _loadingLayer.lineWidth = 2;
        //绘制圆弧
        _loadingLayer.path = [self drawLoadingBezierPath].CGPath;
        [self.layer addSublayer:_loadingLayer];
    
        CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
        basicAnimation.fromValue = @(0);
        basicAnimation.toValue = @(M_PI*2);
        basicAnimation.duration = 0.5;
        basicAnimation.repeatCount = LONG_MAX;
        [_loadingLayer addAnimation:basicAnimation forKey:@"loadingAnimation"];
        
        [self performSelector:@selector(removeAllAnimation) withObject:self afterDelay:3];
    
    }
    
    -(void)removeAllAnimation{
        [self removeSubViews];
        if(self.translateBlock){
            self.translateBlock();
        }
    }
    
    -(void)removeSubViews{
        [_button removeFromSuperview];
        [_maskLayer removeFromSuperlayer];
        [_loadingLayer removeFromSuperlayer];
        [_clickCicrleLayer removeFromSuperlayer];
    }
    
    -(CAShapeLayer *)drawMask:(CGFloat)x{
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        shapeLayer.frame = self.bounds;
        shapeLayer.path = [self drawBezierPath:x].CGPath;
        return shapeLayer;
    }
    
    -(UIBezierPath *)drawBezierPath:(CGFloat)x{
        CGFloat radius = self.bounds.size.height/2 - 3;
        CGFloat rightCenterX = self.bounds.size.width-x;
        CGFloat leftCenterX = x;
        NSLog(@"leftCenterX = %lf rightCenterX = %lf radius = %lf",leftCenterX,rightCenterX,radius);
        UIBezierPath *bezierPath = [UIBezierPath bezierPath];
        bezierPath.lineJoinStyle = kCGLineJoinRound;
        bezierPath.lineCapStyle = kCGLineCapRound;
        
        [bezierPath addArcWithCenter:CGPointMake(rightCenterX, self.bounds.size.height/2) radius:radius startAngle:-M_PI/2 endAngle:M_PI/2 clockwise:YES];
        [bezierPath addArcWithCenter:CGPointMake(leftCenterX, self.bounds.size.height/2) radius:radius startAngle:M_PI/2 endAngle:-M_PI/2 clockwise:YES];
        [bezierPath closePath];
        
        return bezierPath;
    }
    
    
    -(UIBezierPath *)drawLoadingBezierPath{
        CGFloat radius = self.bounds.size.height/2 - 3;
        UIBezierPath *bezierPath = [UIBezierPath bezierPath];
        [bezierPath addArcWithCenter:CGPointMake(0,0) radius:radius startAngle:M_PI/2 endAngle:M_PI/2+M_PI/2 clockwise:YES];
        return bezierPath;
    }
    
    -(UIBezierPath *)drawclickCircleBezierPath:(CGFloat)radius{
        UIBezierPath *bezierPath = [UIBezierPath bezierPath];
        [bezierPath addArcWithCenter:CGPointMake(0,0) radius:radius startAngle:0 endAngle:M_PI*2 clockwise:YES];
        return bezierPath;
    }
    @end
    

    相关文章

      网友评论

        本文标题:酷炫登录动画效果

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