組合動畫

記錄一下最近的動畫實現(xiàn),通過文檔以及調(diào)試的知識tip積累。

1. 組合動畫對象盡量不要保存為全局屬性或者變量。

2.CAKeyframeAnimation .values?以及.keyTimes是一一對應(yīng), 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];

? ? ? ? }

? ? }

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容