之前做了一个仿苹果地图定位时的Annotation扩散动画
需求是做一组扩散动画在地图上表示紧急求助状态
网上也没有对应此类需求的动画效果 所以记录一下 希望可以帮助到需要的人
基于CAAnimationGroup 来做的一组动画 (动画参数调试比较费时)
代码
直接上代码吧 关于CAAnimation 的一些参数和API的使用在这里就不详细说了 网上一大堆 想研究的可以看看AE公司的开源项目Lottie的源码 CA动画绘制矢量动画的典例 很牛逼
后面会把一些关于地图的小东西和多地图框架做一个demo上传GitHub 供大家探讨
.h
/**
一个呼吸动画的layer
*/
+ (CAAnimationGroup *)pulseAnimationGroup;
/**
一个圆形色彩扩散动效的layer
@param size layer size
@param time annimation offset time
@return annimation layer
*/
+ (CALayer*)colorDotLayerWithSize:(CGSize)size WithBeginTime:(NSTimeInterval)time;
/**
一组扩散动效 layer 三个layer
*/
+ (CALayer *)groupLayerAnimationsWithSize:(CGSize )size;
.m
+ (CAAnimationGroup *)pulseAnimationGroup
{
CAAnimationGroup *pulseAnimationGroup = [CAAnimationGroup animation];
CAMediaTimingFunction *defaultCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
pulseAnimationGroup = [CAAnimationGroup animation];
pulseAnimationGroup.duration = 2;
pulseAnimationGroup.repeatCount = INFINITY;
pulseAnimationGroup.removedOnCompletion = NO;
pulseAnimationGroup.timingFunction = defaultCurve;
NSMutableArray *animations = [NSMutableArray new];
CABasicAnimation *pulseAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"];
pulseAnimation.fromValue = @0.0;
pulseAnimation.toValue = @1.0;
pulseAnimation.duration = 3;
[animations addObject:pulseAnimation];
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
animation.duration = 3;
animation.values = @[@0.45, @0.45, @0];
animation.keyTimes = @[@0, @0.2, @1];
animation.removedOnCompletion = NO;
[animations addObject:animation];
pulseAnimationGroup.animations = animations;
return pulseAnimationGroup;
}
+ (CALayer*)colorDotLayerWithSize:(CGSize)size WithBeginTime:(NSTimeInterval)time {
CALayer *colorDotLayer = [CALayer layer];
CGFloat width = size.width - 6;
colorDotLayer.bounds = CGRectMake(0, 0, width, width);
colorDotLayer.allowsGroupOpacity = YES;
colorDotLayer.backgroundColor = [UIColor colorWithRed:243 / 255.0
green:53 / 255.0
blue:43 / 255.0 alpha:1].CGColor;
colorDotLayer.cornerRadius = width/2;
colorDotLayer.position = CGPointMake(size.width/2, size.height/2);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
CAMediaTimingFunction *defaultCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.duration = 3;
animationGroup.repeatCount = INFINITY;
animationGroup.removedOnCompletion = NO;
// animationGroup.autoreverses = YES;
animationGroup.timingFunction = defaultCurve;
// animationGroup.speed = 1;
animationGroup.fillMode = kCAFillModeBoth;
animationGroup.timeOffset = time;
CABasicAnimation *pulseAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"];
pulseAnimation.fromValue = @0.25;
pulseAnimation.toValue = @1;
pulseAnimation.duration =3;
CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
opacityAnimation.fromValue = @1;
opacityAnimation.toValue = @0.;
opacityAnimation.duration = 3;
animationGroup.animations = @[pulseAnimation, opacityAnimation];
dispatch_async(dispatch_get_main_queue(), ^(void) {
[colorDotLayer addAnimation:animationGroup forKey:@"pulse"];
});
});
return colorDotLayer;
}
+ (CALayer *)groupLayerAnimationsWithSize:(CGSize )size
{
CALayer *groupLayer = [CALayer layer];
CGFloat width = size.width;
groupLayer.bounds = CGRectMake(0, 0, width, width);
groupLayer.allowsGroupOpacity = YES;
groupLayer.cornerRadius = width/2;
groupLayer.position = CGPointMake(size.width/2, size.height/2);
CALayer *oneLayer = [self colorDotLayerWithSize:size WithBeginTime:0];
CALayer *twoLayer = [self colorDotLayerWithSize:size WithBeginTime:1.];
CALayer *threeLayer = [self colorDotLayerWithSize:size WithBeginTime:2];
[groupLayer addSublayer:oneLayer];
[groupLayer addSublayer:twoLayer];
[groupLayer addSublayer:threeLayer];
return groupLayer;
}