三、动画实战<一>

作者: iLees | 来源:发表于2017-01-12 14:41 被阅读27次

<h4>简述</h4>

今天来实现一个爱奇艺的加载动画效果,大概思路如下:
1、绘制一个三角形,并对其播放旋转两周的动画;
2、绘制一个98%的环形,首先播放正向轨迹动画,再对其播放反向轨迹动画。

<h4>效果是这样</h4>

loading.gif

<h4>No code no bibi</h4>

<h6>SZPlayLoadingView.h文件</h6>

#import <UIKit/UIKit.h>

@interface SZPlayTriangleView : UIView

@end

@interface SZPlayLoadingView : UIView

- (void)showLoading;

@end

<h6>SZPlayLoadingView.m文件</h6>

#import "SZPlayLoadingView.h"

static NSString * const kCircleAnimationName = @"circleAnimationEnd";
static NSString * const kCircleHideAnimationName = @"circleAnimationStart";
static NSString * const kTrangleAnimationName = @"kTrangleAnimationName";

static const CGFloat kAnimationDuration = 0.6;

@interface SZPlayTriangleView()
/** 三角形layer */
@property (nonatomic, strong) CAShapeLayer *triangleLayer;
@end

@implementation SZPlayTriangleView

- (void)layoutSubviews {
    [super layoutSubviews];
    [_triangleLayer removeFromSuperlayer];
    _triangleLayer = nil;
    
    [self.layer addSublayer:self.triangleLayer];
}

- (CAShapeLayer *)triangleLayer {
    if (!_triangleLayer) {
        // 1、创建三角形path
        CGFloat width = self.frame.size.width*0.65;
        CGFloat width2=width/(sqrt(3));
        
        CGFloat centerX =self.frame.size.width/2;
        CGFloat centerY =self.frame.size.width/2;
        
        CGPoint PointA=CGPointMake(centerX+(width*(2/3.0)), centerY);
        CGPoint PointB=CGPointMake(PointA.x-width, PointA.y-width2);
        CGPoint PointC=CGPointMake(PointB.x, PointB.y+2*width2);
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:PointA];
        [path addLineToPoint:PointB];
        [path addLineToPoint:PointC];
        [path closePath];
        // 2、创建layer
        _triangleLayer = [CAShapeLayer layer];
        _triangleLayer.path = path.CGPath;
        _triangleLayer.fillColor = [UIColor colorWithRed:0.52f green:0.76f blue:0.07f alpha:1.00f].CGColor;
    }
    return _triangleLayer;
}

@end


@interface SZPlayLoadingView()<CAAnimationDelegate>

/** Circle view */
@property (nonatomic, strong) CAShapeLayer *circleLayer;
/** Circle view aniation */
@property (nonatomic, strong) CABasicAnimation *circleLayerAnimation;
/** Circle view hide aniation */
@property (nonatomic, strong) CABasicAnimation *circleLayerHideAnimation;
/** 三角形 */
@property (nonatomic, strong) SZPlayTriangleView *triangleView;
/** 三角形动画 */
@property (nonatomic, strong) CABasicAnimation *triangleAnimation;
@end

@implementation SZPlayLoadingView

#pragma mark - Outer method

- (void)showLoading {
    
    [self showCircle];
    
}

#pragma mark - Inner method

- (void)showCircle {

    [_circleLayer removeAllAnimations];
    [_triangleView removeFromSuperview];
    
    [self addSubview:self.triangleView];

    [self.layer addSublayer:self.circleLayer];
    self.circleLayer.strokeStart = 0;
    self.circleLayer.strokeEnd = 0.98;
    [self.circleLayer addAnimation:self.circleLayerAnimation forKey:kCircleAnimationName];
}

- (void)hideCircle {
    self.circleLayer.strokeStart = 0.98;
    [self.circleLayer addAnimation:self.circleLayerHideAnimation forKey:kCircleHideAnimationName];
}

- (void)showTriangleAmimation {
    [self.triangleView.layer addAnimation:self.triangleAnimation forKey:kTrangleAnimationName];
}

#pragma mark - Animation delegate

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    if ([[anim valueForKey:@"animationName"] isEqualToString:kCircleHideAnimationName]) {
        [self.triangleView.layer removeAllAnimations];
        [self showCircle];
    } else if ([[anim valueForKey:@"animationName"] isEqualToString:kCircleAnimationName]) {
        [self showTriangleAmimation];
        [self hideCircle];
    }
}

#pragma mark - Property

- (CAShapeLayer *)circleLayer {
    if (!_circleLayer) {
        _circleLayer = [CAShapeLayer layer];
        // 1、设置path
        UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:self.bounds];
        _circleLayer.path = circlePath.CGPath;
        // 2、设置颜色
        _circleLayer.fillColor = [UIColor clearColor].CGColor;
        _circleLayer.strokeColor = [UIColor colorWithRed:0.52 green:0.76 blue:0.07 alpha:1].CGColor;
        // 3、设置线条宽度和cap
        _circleLayer.lineWidth = 1;
        _circleLayer.lineCap = kCALineCapRound;
        // 4、设置翻转
        _circleLayer.transform = CATransform3DRotate(_circleLayer.transform, -M_PI_2, 0, 0, 1);
        _circleLayer.transform = CATransform3DTranslate(_circleLayer.transform, -self.bounds.size.width, 0, 0);
    }
    return _circleLayer;
}

- (CABasicAnimation *)circleLayerAnimation {
    if (!_circleLayerAnimation) {
        _circleLayerAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
        _circleLayerAnimation.fromValue = @(0);
        _circleLayerAnimation.duration = kAnimationDuration;
        [_circleLayerAnimation setValue:kCircleAnimationName forKey:@"animationName"];
        _circleLayerAnimation.delegate = self;
    }
    return _circleLayerAnimation;
}

- (CABasicAnimation *)circleLayerHideAnimation {
    if (!_circleLayerHideAnimation) {
        _circleLayerHideAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
        _circleLayerHideAnimation.fromValue = @(0);
        _circleLayerHideAnimation.duration = kAnimationDuration;
        [_circleLayerHideAnimation setValue:kCircleHideAnimationName forKey:@"animationName"];
        _circleLayerHideAnimation.delegate = self;
    }
    return _circleLayerHideAnimation;
}

- (SZPlayTriangleView *)triangleView {
    if (!_triangleView) {
        _triangleView = [SZPlayTriangleView new];
        _triangleView.frame = CGRectMake(0, 0, self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
        _triangleView.center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
        _triangleView.backgroundColor = [UIColor clearColor];
    }
    return _triangleView;
}

- (CABasicAnimation *)triangleAnimation {
    if (!_triangleAnimation) {
        _triangleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
        _triangleAnimation.toValue = @(M_PI * 2);
        _triangleAnimation.duration = kAnimationDuration;
        [_triangleAnimation setValue:kTrangleAnimationName forKey:@"animationName"];
    }
    return _triangleAnimation;
}

@end

相关文章

网友评论

    本文标题:三、动画实战<一>

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