iOS-各种动画特效

661F567F-3399-4227-ACCD-3C0FB6EB966D.png

一、实现功能

  • 1. 广播跑马灯

  • 2. 弹幕动画

  • 3. 直播点赞动画

  • 4. 直播点赞图片动画

  • 5. 烟花动画

  • 6. 雪花动画

二、程序实现

1. 广播动画特效:

思路:

1. 初始化广播视图

2. 设置广播公告广告内容

3. 添加动画效果


初始化广播视图, 广播活动标题按钮 与 广播活动标题标签 控件大小一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
  * 设置广播视图
  */
- ( void )setupBroadcastingView {
     // 设置广播活动标题按钮
     UIButton *activityBtn = [UIButton buttonWithType:UIButtonTypeCustom];
     activityBtn.frame = CGRectMake(0, 64, [UIScreen mainScreen].bounds.size.width, 30);
     activityBtn.backgroundColor = [UIColor clearColor];
     [activityBtn addTarget:self action:@selector(activityDetail) forControlEvents:UIControlEventTouchUpInside];
     [self.view addSubview:activityBtn];
     self.activityBtn = activityBtn;
     
     // 设置广播活动标题文字
     UILabel *activityLb = [[UILabel alloc] init];
     activityLb.frame = activityBtn.bounds;
     [activityLb setFont:[UIFont boldSystemFontOfSize:14]];
     [activityLb setTextColor:[UIColor colorWithRed:115/255.0 green:125/255.0 blue:134/255.0 alpha:1.0]];
     [activityLb setBackgroundColor:[UIColor clearColor]];
     [activityBtn addSubview:activityLb];
     self.activityLb = activityLb;
     
     // 设置广播logo
     UIImageView *speaker = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@ "broadcasting" ]]];
     speaker.frame = CGRectMake(0, 5, 20, 20);
     speaker.backgroundColor = self.view.backgroundColor;
     [activityBtn addSubview:speaker];
     
     // 设置广播公告广告内容
     [self setActivityButtonTitle];
}

设置广播公告广告内容, 这里是以假数据填充,一般需求会是后台请求得来的活动内容.

添加动画效果: 当文字内容超过显示区域就滚动展示,未超过则居中展示.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
  * 设置广播公告广告内容
  */
- ( void )setActivityButtonTitle {
     
     // 广播公告广告内容(假数据)
     NSString *title = @ "广播公告广告内容(ZL测试内容)广播公告广告内容(测试内容)\r\n广播公告广告内容(测试内容)广播公告广告内容(测试内容)广播公告广告内容(测试内容)" ;
     
     title = [title stringByReplacingOccurrencesOfString:@ "\r\n"  withString:@ " " ];
     
     [self.activityLb setText:title];
     
     [self.activityLb sizeToFit];
     
     if  (self.activityLb.frame.size.width <= self.activityBtn.frame.size.width) {
         
         [self.activityLb setCenter:CGPointMake(self.activityBtn.frame.size.width/2, self.activityBtn.frame.size.height/2)];
         
     else  // 当文字内容超过显示区域就滚动展示
         
         CGRect frame = self.activityLb.frame;
         frame.origin.x = self.activityBtn.frame.size.width;
         frame.origin.y = self.activityBtn.frame.size.height * 0.5 - self.activityLb.bounds.size.height * 0.5;
         self.activityLb.frame = frame;
         
         [UIView beginAnimations:@ "testAnimation"  context:NULL];
         [UIView setAnimationDuration:frame.size.width/55.f];
         [UIView setAnimationCurve:UIViewAnimationCurveLinear];
         [UIView setAnimationRepeatAutoreverses:NO];
         [UIView setAnimationRepeatCount:INT_MAX];
         
         frame = self.activityLb.frame;
         frame.origin.x = - frame.size.width;
         self.activityLb.frame = frame;
         [UIView commitAnimations];
     }
}

当有活动链接时,需要添加点击效果; 如果没则不需要创建按钮及点击效果.

1
2
3
4
5
// 展示活动详情
- ( void )activityDetail {
     
     NSLog(@ "点击了广播活动公告详情" );
}

广播跑马灯.gif



2. 弹幕动画特效:

先自定义弹幕标签ZLScrollLabelView:

.h 文件露出开始/停止/暂停/恢复弹幕动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@interface ZLScrollLabelView : UIView
// 代理协议
@property (nonatomic, weak) id <ZLScrollLabelViewDelegate> delegate;
// 速度
@property (nonatomic) CGFloat speed;
// 方向
@property (nonatomic) ScrollDirectionType barrageDirection;
// 容器
- ( void )addContentView:(UIView *)view;
// 开始
- ( void )startAnimation;
// 停止
- ( void )stopAnimation;
// 暂停
- ( void )pauseAnimation;
// 恢复
- ( void )resumeAnimation;
@end

.m 文件初始化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
- (instancetype)initWithFrame:(CGRect)frame {
     
     if  (self = [super initWithFrame:frame]) {
         
         _width = frame.size.width;
         _height = frame.size.height;
         
         self.speed = 1.f;
         self.barrageDirection = FromLeftType;
         self.layer.masksToBounds = YES;
         self.animationView = [[UIView alloc] initWithFrame:CGRectMake(_width, 0, _width, _height)];
         [self addSubview:self.animationView];
     }
     
     return  self;
}
- ( void )addContentView:(UIView *)view {
     
     [_contentView removeFromSuperview];
     
     view.frame = view.bounds;
     _contentView = view;
     self.animationView.frame = view.bounds;
     [self.animationView addSubview:_contentView];
     
     _animationViewWidth = self.animationView.frame.size.width;
     _animationViewHeight = self.animationView.frame.size.height;
}

开始弹幕动画:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- ( void )startAnimation {
     
     [self.animationView.layer removeAnimationForKey:@ "animationViewPosition" ];
     _stoped = NO;
     
     CGPoint pointRightCenter = CGPointMake(_width + _animationViewWidth / 2.f, _animationViewHeight / 2.f);
     CGPoint pointLeftCenter  = CGPointMake(-_animationViewWidth / 2, _animationViewHeight / 2.f);
     CGPoint fromPoint = self.barrageDirection == FromLeftType ? pointRightCenter : pointLeftCenter;
     CGPoint toPoint = self.barrageDirection == FromLeftType ? pointLeftCenter  : pointRightCenter;
     
     self.animationView.center = fromPoint;
     UIBezierPath *movePath = [UIBezierPath bezierPath];
     [movePath moveToPoint:fromPoint];
     [movePath addLineToPoint:toPoint];
     
     CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@ "position" ];
     moveAnimation.path = movePath.CGPath;
     moveAnimation.removedOnCompletion = YES;
     moveAnimation.duration = _animationViewWidth / 30.f * (1 / self.speed);
     moveAnimation.delegate = self;
     [self.animationView.layer addAnimation:moveAnimation forKey:@ "animationViewPosition" ];
}

停止弹幕动画:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- ( void )stopAnimation {
     
     _stoped = YES;
     [self.animationView.layer removeAnimationForKey:@ "animationViewPosition" ];
}
 
- ( void )animationDidStop:(CAAnimation *)anim finished:( BOOL )flag {
     
     if  (self.delegate && [self.delegate respondsToSelector:@selector(barrageView:animationDidStopFinished:)]) {
         
         [self.delegate barrageView:self animationDidStopFinished:flag];
     }
     
     if  (flag && !_stoped) {
         
         [self startAnimation];
     }
}

暂停弹幕动画:

1
2
3
4
5
6
7
8
9
10
11
- ( void )pauseAnimation {
     
     [self pauseLayer:self.animationView.layer];
}
 
- ( void )pauseLayer:(CALayer*)layer {
     
     CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
     layer.speed = 0.0;
     layer.timeOffset = pausedTime;
}

恢复弹幕动画:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- ( void )resumeAnimation {
     
     [self resumeLayer:self.animationView.layer];
}
 
- ( void )resumeLayer:(CALayer*)layer {
     
     CFTimeInterval pausedTime = layer.timeOffset;
     layer.speed = 1.0;
     layer.timeOffset = 0.0;
     layer.beginTime = 0.0;
     CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
     layer.beginTime = timeSincePause;
}

在所需控制器里, 添加代理ZLScrollLabelViewDelegate实现开始动画方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- ( void )viewDidLoad {
     [super viewDidLoad];
     self.navigationItem.title = @ "弹幕动画" ;
     self.view.backgroundColor = [UIColor grayColor];
     
     ZLScrollLabelView *barrageView0 = [[ZLScrollLabelView alloc] initWithFrame:CGRectMake(0, 104, self.view.frame.size.width, 20)];
     barrageView0.delegate = self;
     // add
     [self.view addSubview:barrageView0];
     // text
     [barrageView0 addContentView:[self createLabelWithText:@ "超喜欢赵丽颖,只因她的踏实!"
                                                      textColor:[self randomColor]]];
     // start
     [barrageView0 startAnimation];
}

代理ZLScrollLabelViewDelegate:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- (UILabel *)createLabelWithText:(NSString *)text textColor:(UIColor *)textColor {
     
     NSString *string = [NSString stringWithFormat:@ " %@ " , text];
     CGFloat width = [string widthWithStringAttribute:@{NSFontAttributeName : [UIFont systemFontOfSize:14.f]}];
     UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 20)];
     label.font = [UIFont systemFontOfSize:14.f];
     label.text = string;
     label.textColor = textColor;
     return  label;
}
 
#pragma mark - ZLScrollLabelViewDelegate
 
- ( void )barrageView:(ZLScrollLabelView *)barrageView animationDidStopFinished:( BOOL )finished {
     
     [barrageView stopAnimation];
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
         [barrageView addContentView:[self createLabelWithText:[self randomString]
                                                         textColor:[self randomColor]]];
         [barrageView startAnimation];
     });
}
 
- (NSString *)randomString {
     
     NSArray *array = @[@ "猜猜我是谁?" ,
                        @ "哈哈" ,
                        @ "猜不着吧" ,
                        @ "我是程序媛" ,
                        @ "噜啦啦啦啦~" ];
     return  array[arc4random() % array.count];
}

弹幕动画.gif


3. 直播点赞效果

先自定义ZLLiveHeartView,露出liveHeartAnimateInView方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
- ( void )liveHeartAnimateInView:(UIView *)view {
     
     NSTimeInterval totalAnimationDuration = 8;
     CGFloat heartSize = CGRectGetWidth(self.bounds);
     CGFloat heartCenterX = self.center.x;
     CGFloat viewHeight = CGRectGetHeight(view.bounds);
     
     // Pre-Animation setup
     self.transform = CGAffineTransformMakeScale(0, 0);
     self.alpha = 0;
     
     // Bloom
     [UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.6 initialSpringVelocity:0.8 options:UIViewAnimationOptionCurveEaseOut animations:^{
         self.transform = CGAffineTransformIdentity;
         self.alpha = 0.9;
     } completion:NULL];
     
     NSInteger i = arc4random_uniform(2);
     // -1 OR 1
     NSInteger rotationDirection = 1 - (2 * i);
     NSInteger rotationFraction = arc4random_uniform(10);
     [UIView animateWithDuration:totalAnimationDuration animations:^{
         self.transform = CGAffineTransformMakeRotation(rotationDirection * M_PI / (16 + rotationFraction * 0.2));
     } completion:NULL];
     
     UIBezierPath *heartTravelPath = [UIBezierPath bezierPath];
     [heartTravelPath moveToPoint:self.center];
     
     // random end point
     CGPoint endPoint = CGPointMake(heartCenterX + (rotationDirection) * arc4random_uniform(2 * heartSize), viewHeight/6.0 + arc4random_uniform(viewHeight / 4.0));
     
     // random Control Points
     NSInteger j = arc4random_uniform(2);
     NSInteger travelDirection = 1- (2*j);
     
     // randomize x and y for control points
     CGFloat xDelta = (heartSize/2.0 + arc4random_uniform(2*heartSize)) * travelDirection;
     CGFloat yDelta = MAX(endPoint.y ,MAX(arc4random_uniform(8*heartSize), heartSize));
     CGPoint controlPoint1 = CGPointMake(heartCenterX + xDelta, viewHeight - yDelta);
     CGPoint controlPoint2 = CGPointMake(heartCenterX - 2*xDelta, yDelta);
     
     [heartTravelPath addCurveToPoint:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2];
     
     CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@ "position" ];
     keyFrameAnimation.path = heartTravelPath.CGPath;
     keyFrameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
     keyFrameAnimation.duration = totalAnimationDuration + endPoint.y/viewHeight;
     [self.layer addAnimation:keyFrameAnimation forKey:@ "positionOnPath" ];
     
     // Alpha & remove from superview
     [UIView animateWithDuration:totalAnimationDuration animations:^{
         self.alpha = 0.0;
     } completion:^( BOOL  finished) {
         [self removeFromSuperview];
     }];
     
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
- ( void )drawRect:(CGRect)rect {
     
     [_strokeColor setStroke];
     [_fillColor setFill];
     
     CGFloat drawingPadding = 4.0;
     CGFloat curveRadius =  floor ((CGRectGetWidth(rect) - 2*drawingPadding) / 4.0);
     
     // Creat path
     UIBezierPath *heartPath = [UIBezierPath bezierPath];
     
     // Start at bottom heart tip
     CGPoint tipLocation = CGPointMake( floor (CGRectGetWidth(rect) / 2.0), CGRectGetHeight(rect) - drawingPadding);
     [heartPath moveToPoint:tipLocation];
     
     // Move to top left start of curve
     CGPoint topLeftCurveStart = CGPointMake(drawingPadding,  floor (CGRectGetHeight(rect) / 2.4));
     
     [heartPath addQuadCurveToPoint:topLeftCurveStart controlPoint:CGPointMake(topLeftCurveStart.x, topLeftCurveStart.y + curveRadius)];
     
     // Create top left curve
     [heartPath addArcWithCenter:CGPointMake(topLeftCurveStart.x + curveRadius, topLeftCurveStart.y) radius:curveRadius startAngle:M_PI endAngle:0 clockwise:YES];
     
     // Create top right curve
     CGPoint topRightCurveStart = CGPointMake(topLeftCurveStart.x + 2*curveRadius, topLeftCurveStart.y);
     [heartPath addArcWithCenter:CGPointMake(topRightCurveStart.x + curveRadius, topRightCurveStart.y) radius:curveRadius startAngle:M_PI endAngle:0 clockwise:YES];
     
     // Final curve to bottom heart tip
     CGPoint topRightCurveEnd = CGPointMake(topLeftCurveStart.x + 4*curveRadius, topRightCurveStart.y);
     [heartPath addQuadCurveToPoint:tipLocation controlPoint:CGPointMake(topRightCurveEnd.x, topRightCurveEnd.y + curveRadius)];
     
     [heartPath fill];
     heartPath.lineWidth = 1;
     heartPath.lineCapStyle = kCGLineCapRound;
     heartPath.lineJoinStyle = kCGLineCapRound;
     [heartPath stroke];
}

再在所需控制器里添加ZLLiveHeartView.

1
2
3
4
5
6
7
8
- ( void )showLiveHeartView {
     
     ZLLiveHeartView *heart = [[ZLLiveHeartView alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
     [self.view addSubview:heart];
     CGPoint fountainSource = CGPointMake(self.view.frame.size.width - 80, self.view.bounds.size.height - 30 / 2.0 - 10);
     heart.center = fountainSource;
     [heart liveHeartAnimateInView:self.view];
}

直播点赞动画.gif


4. 直播图片点赞动画

先自定义ZLLikeAnimation,animatePictureInView方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
- ( void )animatePictureInView:(UIView *)view Image:(UIImage *)image {
     
     self.imageView.image = image;
     NSTimeInterval totalAnimationDuration = 8;
     CGFloat heartSize = CGRectGetWidth(self.bounds);
     CGFloat heartCenterX = self.center.x;
     CGFloat viewHeight = CGRectGetHeight(view.bounds);
     
     // Pre-Animation setup
     self.transform = CGAffineTransformMakeScale(0, 0);
     self.alpha = 0;
     
     // Bloom
     [UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.6 initialSpringVelocity:0.8 options:UIViewAnimationOptionCurveEaseOut animations:^{
         self.transform = CGAffineTransformIdentity;
         self.alpha = 0.9;
     } completion:NULL];
     
     NSInteger i = arc4random_uniform(2);
     // -1 OR 1
     NSInteger rotationDirection = 1 - (2 * i);
     NSInteger rotationFraction = arc4random_uniform(10);
     [UIView animateWithDuration:totalAnimationDuration animations:^{
         self.transform = CGAffineTransformMakeRotation(rotationDirection * M_PI / (16 + rotationFraction * 0.2));
     } completion:NULL];
     
     UIBezierPath *heartTravelPath = [UIBezierPath bezierPath];
     [heartTravelPath moveToPoint:self.center];
     
     // random end point
     CGPoint endPoint = CGPointMake(heartCenterX + (rotationDirection) * arc4random_uniform(2 * heartSize), viewHeight/6.0 + arc4random_uniform(viewHeight / 4.0));
     
     // random Control Points
     NSInteger j = arc4random_uniform(2);
     NSInteger travelDirection = 1 - (2 * j);
     
     // randomize x and y for control points
     CGFloat xDelta = (heartSize / 2.0 + arc4random_uniform(2 * heartSize)) * travelDirection;
     CGFloat yDelta = MAX(endPoint.y ,MAX(arc4random_uniform(8 * heartSize), heartSize));
     CGPoint controlPoint1 = CGPointMake(heartCenterX + xDelta, viewHeight - yDelta);
     CGPoint controlPoint2 = CGPointMake(heartCenterX - 2 * xDelta, yDelta);
     
     [heartTravelPath addCurveToPoint:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2];
     
     CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@ "position" ];
     keyFrameAnimation.path = heartTravelPath.CGPath;
     keyFrameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
     keyFrameAnimation.duration = totalAnimationDuration + endPoint.y / viewHeight;
     [self.layer addAnimation:keyFrameAnimation forKey:@ "positionOnPath" ];
     
     // Alpha & remove from superview
     [UIView animateWithDuration:totalAnimationDuration animations:^{
         self.alpha = 0.0;
     } completion:^( BOOL  finished) {
         [self removeFromSuperview];
     }];
     
}

再在所需控制器里添加ZLLikeAnimation.

1
2
3
4
5
6
7
8
9
- ( void )showLikePictureView {
     
     ZLLikeAnimation *heart = [[ZLLikeAnimation alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
     [self.view addSubview:heart];
     CGPoint fountainSource = CGPointMake(self.view.frame.size.width - 80, self.view.bounds.size.height - 30 / 2.0 - 10);
     heart.center = fountainSource;
     int  count = round(random() % 12);
     [heart animatePictureInView:self.view Image:[UIImage imageNamed:[NSString stringWithFormat:@ "resource.bundle/heart%d.png" ,count]]];
}

直播点赞图片动画.gif


5. 烟花特效:

设置烟花

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
- ( void )setupFireworks {
     
     self.caELayer = [CAEmitterLayer layer];
     
     // 发射源
     self.caELayer.emitterPosition = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height - 50);
     // 发射源尺寸大小
     self.caELayer.emitterSize = CGSizeMake(50, 0);
     // 发射源模式
     self.caELayer.emitterMode = kCAEmitterLayerOutline;
     // 发射源的形状
     self.caELayer.emitterShape = kCAEmitterLayerLine;
     // 渲染模式
     self.caELayer.renderMode = kCAEmitterLayerAdditive;
     // 发射方向
     self.caELayer.velocity = 1;
     // 随机产生粒子
     self.caELayer.seed = (arc4random() % 100) + 1;
     
     // cell
     CAEmitterCell *cell = [CAEmitterCell emitterCell];
     // 速率
     cell.birthRate = 1.0;
     // 发射的角度
     cell.emissionRange = 0.11 * M_PI;
     // 速度
     cell.velocity = 300;
     // 范围
     cell.velocityRange = 150;
     // Y轴 加速度分量
     cell.yAcceleration = 75;
     // 声明周期
     cell.lifetime  = 2.04;
     // 是个CGImageRef的对象,既粒子要展现的图片
     cell.contents = (id)[[UIImage imageNamed:@ "ring" ] CGImage];
     // 缩放比例
     cell.scale = 0.2;
     // 粒子的颜色
     cell.color = [[UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:1.0] CGColor];
     // 一个粒子的颜色green 能改变的范围
     cell.greenRange = 1.0;
     // 一个粒子的颜色red 能改变的范围
     cell.redRange = 1.0;
     // 一个粒子的颜色blue 能改变的范围
     cell.blueRange = 1.0;
     // 子旋转角度范围
     cell.spinRange = M_PI;
     
     // 爆炸
     CAEmitterCell *burst = [CAEmitterCell emitterCell];
     // 粒子产生系数
     burst.birthRate = 1.0;
     // 速度
     burst.velocity = 0;
     // 缩放比例
     burst.scale = 2.5;
     // shifting粒子red在生命周期内的改变速度
     burst.redSpeed = -1.5;
     // shifting粒子blue在生命周期内的改变速度
     burst.blueSpeed= +1.5;
     // shifting粒子green在生命周期内的改变速度
     burst.greenSpeed = +1.0;
     // 生命周期
     burst.lifetime = 0.35;
     
     
     // 火花 and finally, the sparks
     CAEmitterCell *spark = [CAEmitterCell emitterCell];
     // 粒子产生系数,默认为1.0
     spark.birthRate = 400;
     // 速度
     spark.velocity = 125;
     // 360 deg //周围发射角度
     spark.emissionRange = 2 * M_PI;
     // gravity //y方向上的加速度分量
     spark.yAcceleration = 75;
     // 粒子生命周期
     spark.lifetime = 3;
     // 是个CGImageRef的对象,既粒子要展现的图片
     spark.contents = (id)
     [[UIImage imageNamed:@ "fireworks" ] CGImage];
     // 缩放比例速度
     spark.scaleSpeed = -0.2;
     // 粒子green在生命周期内的改变速度
     spark.greenSpeed = -0.1;
     // 粒子red在生命周期内的改变速度
     spark.redSpeed = 0.4;
     // 粒子blue在生命周期内的改变速度
     spark.blueSpeed = -0.1;
     // 粒子透明度在生命周期内的改变速度
     spark.alphaSpeed = -0.25;
     // 子旋转角度
     spark.spin = 2 * M_PI;
     // 子旋转角度范围
     spark.spinRange = 2 * M_PI;
     
     self.caELayer.emitterCells = [NSArray arrayWithObject:cell];
     cell.emitterCells = [NSArray arrayWithObjects:burst, nil];
     burst.emitterCells = [NSArray arrayWithObject:spark];
     [self.view.layer addSublayer:self.caELayer];
}

烟花效果.gif


6. 雪花特效:

设置雪花

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
- ( void )setupSnowflake {
     
     // 创建粒子Layer
     CAEmitterLayer *snowEmitter = [CAEmitterLayer layer];
     
     // 粒子发射位置
     snowEmitter.emitterPosition = CGPointMake(120,0);
     
     // 发射源的尺寸大小
     snowEmitter.emitterSize = self.view.bounds.size;
     
     // 发射模式
     snowEmitter.emitterMode = kCAEmitterLayerSurface;
     
     // 发射源的形状
     snowEmitter.emitterShape = kCAEmitterLayerLine;
     
     // 创建雪花类型的粒子
     CAEmitterCell *snowflake = [CAEmitterCell emitterCell];
     
     // 粒子的名字
     snowflake.name = @ "snow" ;
     
     // 粒子参数的速度乘数因子
     snowflake.birthRate = 20.0;
     snowflake.lifetime = 120.0;
     
     // 粒子速度
     snowflake.velocity = 10.0;
     
     // 粒子的速度范围
     snowflake.velocityRange = 10;
     
     // 粒子y方向的加速度分量
     snowflake.yAcceleration = 2;
     
     // 周围发射角度
     snowflake.emissionRange = 0.5 * M_PI;
     
     // 子旋转角度范围
     snowflake.spinRange = 0.25 * M_PI;
     snowflake.contents  = (id)[[UIImage imageNamed:@ "snow" ] CGImage];
     
     // 设置雪花形状的粒子的颜色
     snowflake.color = [[UIColor whiteColor] CGColor];
     snowflake.redRange = 1.5f;
     snowflake.greenRange = 2.2f;
     snowflake.blueRange = 2.2f;
     
     snowflake.scaleRange = 0.6f;
     snowflake.scale = 0.7f;
     
     snowEmitter.shadowOpacity = 1.0;
     snowEmitter.shadowRadius = 0.0;
     snowEmitter.shadowOffset = CGSizeMake(0.0, 0.0);
     
     // 粒子边缘的颜色
     snowEmitter.shadowColor = [[UIColor whiteColor] CGColor];
     
     // 添加粒子
     snowEmitter.emitterCells = @[snowflake];
     
     // 将粒子Layer添加进图层中
     [self.view.layer addSublayer:snowEmitter];
     
     // 形成遮罩
     UIImage *image = [UIImage imageNamed:@ "alpha" ];
     _layer = [CALayer layer];
     _layer.frame = (CGRect){CGPointZero, self.view.bounds.size};
     _layer.contents = (__bridge id)(image.CGImage);
     _layer.position = self.view.center;
     snowEmitter.mask = _layer;
}

雪花效果.gif

三、压缩文件截图

1、压缩文件截图

C13A68F1-C6FC-492B-A7DC-B0D28285B032.png

2.项目截图:

0E1F6A16-FEC9-4B57-9D09-C1F268860182.png

四、其他补充

持续更新添加动画特效~

界面性问题可以根据自己项目需求调整即可, 具体可参考代码, 项目能够直接运行!


如需看源码,请点击这里下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值