美文网首页
组合动画

组合动画

作者: sjwu | 来源:发表于2020-08-07 12:44 被阅读0次

记录一下最近的动画实现,通过文档以及调试的知识tip积累。

1. 组合动画对象尽量不要保存为全局属性或者变量。

2.CAKeyframeAnimation .values 以及.keyTimes是一一对应, keyTimes 的取值是【0~1】,这里是按照时间取值的。

3.CAAnimationGroup 这个动画组的时间是所有动画的总时间, 多余的时间会被CAAnimationGroup 的duration裁剪。

NSString * const AnimationKey = @"AnimationKey";

NSString * const TwelveFrameAnimation      = @"TwelveFrameAnimation";

NSString * const FourteenFrameAnimation    = @"FourteenFrameAnimation";

NSString * const EightteenFrameAnimation    = @"EightteenFrameAnimation";

NSString * const ThirtyFrameAnimation      = @"ThirtyFrameAnimation";

NSString * const SixteenFrameAnimation      = @"SixteenFrameAnimation";

NSString * const CircleImageViewValue      = @"CircleImageViewValue";

NSString * const FAGuideAnimationXPath      = @"transform.translation.x";

NSString * const FAGuideAnimationYPath      = @"transform.translation.y";

NSString * const FAGuideAnimationZPath      = @"transform.rotation.z";

NSString * const FAGuideAnimationOpacity    = @"opacity";

NSString * const FAGuideAnimationPath      = @"path";

NSInteger const frame = 24.000;

@interface GestureGuideView ()<CAAnimationDelegate>

/// 手势图片

@property (nonatomic, strong) UIImageView *handImageView;

@property (nonatomic, strong) CAShapeLayer *radarLayer;

/// 描述

@property (nonatomic, strong) UILabel *desLabel;

@property (nonatomic, copy) void(^complete)(void);

@end

@implementation GestureGuideView

- (instancetype)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    if (self)

    {

        [self addSubview:self.handImageView];

        [self addSubview:self.desLabel];

        self.backgroundColor = [UIColor redColor];

        [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickGesGudieView)]];

    }

    return self;

}

- (UILabel *)desLabel

{

    if (!_desLabel)

    {

        _desLabel = [[UILabel alloc] init];

        _desLabel.textColor = HexColor(0xFFFFFF);

        _desLabel.top = self.handImageView.bottom+10.0f;

        _desLabel.width = self.width;

        _desLabel.height = 14.0f;

        _desLabel.textAlignment = NSTextAlignmentCenter;

    }

    return _desLabel;

}

- (CGFloat)handViewX

{

    return self.centerX + 12.0f - self.handImageView.width/2.0f;

}

- (CGFloat)handViewY

{

    return self.height/3.0 - self.handImageView.height;

}

- (UIImageView *)handImageView

{

    if (!_handImageView)

    {

        _handImageView = [[UIImageView alloc] init];

        UIImage *image = FAIMAGE(@"fx_hander_click");

        _handImageView.image = image;

        _handImageView.width = image.size.width;

        _handImageView.height = image.size.height;

        _handImageView.x = [self handViewX];

        _handImageView.y = [self handViewY];

        _handImageView.alpha = 0;

        [self addSubview:_handImageView];

    }

    return _handImageView;

}

- (CAShapeLayer *)radarLayer

{

    if (!_radarLayer)

    {

        _radarLayer = [CAShapeLayer layer];

        CGPoint centerPoint = CGPointMake([self handViewX] - 12, [self handViewY] - 18);

        UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:centerPoint

                                                            radius:10

                                                        startAngle:0

                                                          endAngle:2 * M_PI

                                                        clockwise:YES];

        _radarLayer.frame = CGRectMake(centerPoint.x, centerPoint.y, 10, 10);

        _radarLayer.fillColor = [UIColor whiteColor].CGColor;

        _radarLayer.opacity = 0;

        _radarLayer.path = path.CGPath;

        [self.layer insertSublayer:_radarLayer above:0];

    }

    return _radarLayer;

}

- (void)clickGesGudieView

{

    if (self.superview)

    {

        [self removeFromSuperview];

        if (self.complete)

        {

            self.complete();

        }

        [self.handImageView.layer removeAllAnimations];

        [self.radarLayer removeAllAnimations];

    }

}

- (void)startAnimation:(void(^)(void))complete

{

    self.complete = complete;

    [self startAnima];

}

- (void)startAnima

{

    self.handImageView.layer.anchorPoint = CGPointMake(0.5, 1);

    self.handImageView.layer.position = CGPointMake(self.handImageView.centerX, [self handViewY]+self.handImageView.height);

    [self handImageViewAnimation];

}

- (void)shapeLayerAnimation

{

    [self.radarLayer addAnimation:[self cicleAnimationGroup:0] forKey:CircleImageViewValue];

    [self.radarLayer addAnimation:[self cicleAnimationGroup:4/frame] forKey:CircleImageViewValue];

}

- (void)handImageViewAnimation

{

    [NSObject cancelPreviousPerformRequestsWithTarget:self];

    [self.handImageView.layer addAnimation:[self twelveFrameAnimation] forKey:TwelveFrameAnimation];

}

- (CAAnimationGroup *)thirtyFrameAnimation

{

    CGFloat duration = 12.000/frame;

    CAKeyframeAnimation *animationY = [CAKeyframeAnimation animationWithKeyPath:FAGuideAnimationYPath];

    animationY.duration = duration;

    animationY.values = @[@(-18.0f),@(0)];

    animationY.keyTimes = @[@(0), @(1)];

    CAKeyframeAnimation *animationX = [CAKeyframeAnimation animationWithKeyPath:FAGuideAnimationXPath];

    animationX.duration = duration;

    animationX.values = @[@(-12.0f), @(0)];

    animationX.keyTimes = @[@(0), @(1)];

    CAKeyframeAnimation *animationOpacity = [CAKeyframeAnimation animationWithKeyPath:FAGuideAnimationOpacity];

    animationOpacity.duration = duration;

    animationOpacity.values = @[@(1), @(0)];

    animationOpacity.keyTimes = @[@(0), @(1)];

    CAAnimationGroup *group = [CAAnimationGroup animation];

    group.animations = @[animationY,animationX, animationOpacity];

    group.duration = duration;

    group.repeatCount = 1;

    group.beginTime = CACurrentMediaTime();

    group.delegate = self;

    group.fillMode = kCAFillModeForwards;

    group.removedOnCompletion = NO;

    [group setValue:ThirtyFrameAnimation forKey:AnimationKey];

    return group;

}

- (CAKeyframeAnimation *)eightteenFrameAnimation

{

    CGFloat duration = 2.000/frame;

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:FAGuideAnimationZPath];

    animation.duration = duration;

    animation.beginTime = CACurrentMediaTime();

    animation.values = @[@(M_PI/9),@(0)];

    animation.keyTimes = @[@(0),@(1)];

    animation.fillMode = kCAFillModeForwards;

    animation.removedOnCompletion = NO;

    animation.delegate = self;

    [animation setValue:EightteenFrameAnimation forKey:AnimationKey];

    return animation;

}

- (CAKeyframeAnimation *)sixteenFrameAnimation

{

    CGFloat duration = 2.000/frame;

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:FAGuideAnimationZPath];

    animation.duration = duration;

    animation.beginTime = CACurrentMediaTime();

    animation.values = @[@(0),@(M_PI/9)];

    animation.keyTimes = @[@(0),@(1)];

    animation.fillMode = kCAFillModeForwards;

    animation.removedOnCompletion = NO;

    [animation setValue:SixteenFrameAnimation forKey:AnimationKey];

    animation.delegate = self;

    return animation;

}

- (CAKeyframeAnimation *)fourteenFrameAnimation

{

    CGFloat duration = 2.000/frame;

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:FAGuideAnimationZPath];

    animation.duration = duration;

    animation.beginTime = CACurrentMediaTime();

    animation.values = @[@(M_PI/9),@(0)];

    animation.keyTimes = @[@(0),@(1)];

    animation.fillMode = kCAFillModeForwards;

    animation.removedOnCompletion = NO;

    animation.delegate = self;

    [animation setValue:FourteenFrameAnimation forKey:AnimationKey];

    return animation;

}

- (CAAnimationGroup *)twelveFrameAnimation

{

    CGFloat duration = 12.000/frame;

    CAKeyframeAnimation *rotation = [CAKeyframeAnimation animationWithKeyPath:FAGuideAnimationZPath];

    rotation.duration = duration;

    rotation.values = @[@(0),@(M_PI/9)];

    rotation.keyTimes = @[@(0),@(1)];

    CAKeyframeAnimation *animationY = [CAKeyframeAnimation animationWithKeyPath:FAGuideAnimationYPath];

    animationY.duration = duration;

    animationY.values = @[@(0),@(-18.0f)];

    animationY.keyTimes = @[@(0), @(1)];

    CAKeyframeAnimation *animationX = [CAKeyframeAnimation animationWithKeyPath:FAGuideAnimationXPath];

    animationX.duration = duration;

    animationX.values = @[@(0), @(-12.0f)];

    animationX.keyTimes = @[@(0), @(1)];

    // 透明值

    CAKeyframeAnimation *animationOpacity = [CAKeyframeAnimation animationWithKeyPath:FAGuideAnimationOpacity];

    animationOpacity.duration = duration;

    animationOpacity.values = @[@(0), @(1)];

    animationOpacity.keyTimes = @[@(0), @(1)];

    CAAnimationGroup *group = [CAAnimationGroup animation];

    group.animations = @[rotation,animationY,animationX, animationOpacity];

    group.duration = duration;

    group.repeatCount = 1;

    group.delegate = self;

    group.beginTime = CACurrentMediaTime();

    group.fillMode = kCAFillModeForwards;

    group.removedOnCompletion = NO;

    group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

    [group setValue:TwelveFrameAnimation forKey:AnimationKey];

    return group;

}

- (CAAnimationGroup *)cicleAnimationGroup:(CGFloat)delay

{

    CABasicAnimation *basicAnimation = [CABasicAnimation animation];

    basicAnimation.keyPath = FAGuideAnimationPath;

    CGPoint center = CGPointMake(self.radarLayer.bounds.size.width/2, self.radarLayer.bounds.size.height/2);

    UIBezierPath *path1 = [UIBezierPath bezierPathWithArcCenter:center radius:10 startAngle:0 endAngle:2 * M_PI clockwise:YES];

    UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:center radius:18 startAngle:0 endAngle:2 * M_PI clockwise:YES];

    UIBezierPath *path3 = [UIBezierPath bezierPathWithArcCenter:center radius:25 startAngle:0 endAngle:2 * M_PI clockwise:YES];

    basicAnimation.fromValue = (__bridge id _Nullable)(path1.CGPath);

    basicAnimation.byValue = (__bridge id _Nullable)(path2.CGPath);

    basicAnimation.toValue = (__bridge id _Nullable)(path3.CGPath);

    basicAnimation.fillMode = kCAFillModeForwards;

    CABasicAnimation *opacityAnimation = [CABasicAnimation animation];

    opacityAnimation.keyPath = FAGuideAnimationOpacity;

    opacityAnimation.fromValue = @(0.3);

    opacityAnimation.toValue = @(0);

    opacityAnimation.fillMode = kCAFillModeForwards;

    CAAnimationGroup *group = [CAAnimationGroup animation];

    group.animations = @[basicAnimation,opacityAnimation];

    group.duration = 6.000/frame;

    group.beginTime = CACurrentMediaTime() + delay;

    group.repeatCount = 1;

    group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

    group.removedOnCompletion = YES;

    return group;

}

#pragma - delegate

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag

{

    if (flag)

    {

        NSString *animationName = [NSString stringWithFormat:@"%@",[anim valueForKey:AnimationKey]];

        if ([animationName isEqualToString:ThirtyFrameAnimation])

        {

            [self performSelector:@selector(handImageViewAnimation) withObject:nil afterDelay:.2];

        }

        else if ([animationName isEqualToString:TwelveFrameAnimation])

        {

            [self.handImageView.layer addAnimation:[self fourteenFrameAnimation] forKey:FourteenFrameAnimation];

        }

        else if ([animationName isEqualToString:FourteenFrameAnimation])

        {

            [self.handImageView.layer addAnimation:[self sixteenFrameAnimation] forKey:SixteenFrameAnimation];

            [self shapeLayerAnimation];

        }

        else if ([animationName isEqualToString:SixteenFrameAnimation])

        {

            [self.handImageView.layer addAnimation:[self eightteenFrameAnimation] forKey:EightteenFrameAnimation];

        }

        else if ([animationName isEqualToString:EightteenFrameAnimation])

        {

            [self.handImageView.layer addAnimation:[self thirtyFrameAnimation] forKey:TwelveFrameAnimation];

            [self shapeLayerAnimation];

        }

    }

}

相关文章

  • 第十五章 动画机制(二)

    一、组合动画(AnimatorSet 类) 实现 组合动画 的功能:AnimatorSet类 java中 xml中...

  • 动画组合

  • 组合动画

    记录一下最近的动画实现,通过文档以及调试的知识tip积累。 1. 组合动画对象尽量不要保存为全局属性或者变量。 2...

  • 组合动画

    1.在res包下创建anim 2.主页中在布局中

  • 动画2

    [.m]文件夹下 basicAnimation的学习 帧动画 组合动画

  • 写给小白——Android动画之组合动画

    之前我已经讲过了所有的Android属性动画,今天就讲讲,将这些动画组合起来使用。其实说到组合动画,总共就两种情况...

  • ReactNative动画

    目录 1)基本动画 2)插值器 3)动画类型 4)组合动画 5)Animated.event-Scroll动画 1...

  • IOS 动画组合

    在iOS开发中,动画主要有2种: 1. UIView的动画: 在IOS4.0以前,用begin和commit模...

  • Flutter 组合动画

    https://book.flutterchina.club/chapter9/stagger_animation...

  • Flutter 组合动画

    主要包含了一个拖拽效果,以及松开之后的组合动画。 拖拽效果使用了组件 Draggable,组合动画使用到了Curv...

网友评论

      本文标题:组合动画

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