iOS编程中CAEmitterLayer粒子动画详解

2019-07-17  本文已影响0人  单线程Jack

1综述

你肯定见过很酷炫的iOS动画吧,红包雨,下雪,烟花等,但是有时候确不知道从何下手,iOS动画内容有很多,这次我们就来学习下酷炫的粒子动画。

2.知识点

本文用了两大知识点
1.CAGradientLayer 创建渐变的背景色
2.CAEmitterLayer、CAEmitterCell iOS中的粒子效果有两部分组成,一部分为发射器CAEmitterLayer,另一部分是粒子单元CAEmitterCell,用于设置相应的粒子属性。

3.代码

CAEmitterLayer属性:

emitterCells:CAEmitterCell对象的数组,用于把粒子投放到layer上。
birthRate:粒子产生速度,默认1个每秒。
lifetime:粒子纯在时间,默认1秒。
emitterPosition:发射器在xy平面的中心位置。
emitterZPosition:发射器在z平面的位置。
preservesDepth:是否开启三维效果。
velocity:粒子运动速度。
scale:粒子的缩放比例。
spin:自旋转速度。
seed:用于初始化随机数产生的种子。
emitterSize:发射器的尺寸。
emitterDepth:发射器的深度。
emitterShape:发射器的形状
NSString * const kCAEmitterLayerPoint;//点的形状,粒子从一个点发出
NSString * const kCAEmitterLayerLine;//线的形状,粒子从一条线发出
NSString * const kCAEmitterLayerRectangle;//矩形形状,粒子从一个矩形中发出
NSString * const kCAEmitterLayerCuboid;//立方体形状,会影响Z平面的效果
NSString * const kCAEmitterLayerCircle;//圆形,粒子会在圆形范围发射
NSString * const kCAEmitterLayerSphere;//球型
emitterMode:发射器发射模式
NSString * const kCAEmitterLayerPoints;//从发射器中发出
NSString * const kCAEmitterLayerOutline;//从发射器边缘发出
NSString * const kCAEmitterLayerSurface;//从发射器表面发出
NSString * const kCAEmitterLayerVolume;//从发射器中点发出
renderMode:发射器渲染模式
NSString * const kCAEmitterLayerUnordered;//粒子无序出现
NSString * const kCAEmitterLayerOldestFirst;//声明久的粒子会被渲染在最上层
NSString * const kCAEmitterLayerOldestLast;//年轻的粒子会被渲染在最上层
NSString * const kCAEmitterLayerBackToFront;//粒子的渲染按照Z轴的前后顺序进行
NSString * const kCAEmitterLayerAdditive;//粒子混合


CAEmitterCell属性:

emitterCell:初始化方法。
name:粒子的名字。
color:粒子的颜色。
enabled:粒子是否渲染。
contents:渲染粒子,是个CGImageRef的对象,即粒子要展示的图片。
contentsRect:渲染范围。
birthRate:粒子产生速度。

lifetime:生命周期。
lifetimeRange:生命周期增减范围。
velocity:粒子运动速度。
velocityRange:速度范围。
spin:粒子旋转角度。
spinrange:粒子旋转角度范围。
scale:缩放比例。
scaleRange:缩放比例范围。
scaleSpeed:缩放比例速度。
alphaRange::一个粒子的颜色alpha能改变的范围。
alphaSpeed::粒子透明度在生命周期内的改变速度。
redRange:一个粒子的颜色red能改变的范围。
redSpeed:粒子red在生命周期内的改变速度。
blueRange:一个粒子的颜色blue能改变的范围。
blueSpeed:粒子blue在生命周期内的改变速度。
greenRange:一个粒子的颜色green能改变的范围。
greenSpeed:粒子green在生命周期内的改变速度。
xAcceleration:粒子x方向的加速度分量。
yAcceleration:粒子y方向的加速度分量。
zAcceleration:粒子z方向的加速度分量。
emissionRange:粒子发射角度范围。
emissionLongitude:粒子在xy平面的发射角度。
emissionLatitude:发射的z轴方向的发射角度。
#import "ViewController.h"
 
//获得屏幕的宽高
#define mainW [UIScreen mainScreen].bounds.size.width
#define mainH [UIScreen mainScreen].bounds.size.height
 
@interface ViewController ()
 
@property (nonatomic, strong) CAEmitterLayer *noteEmitter;
@property (nonatomic, strong) CAEmitterLayer *petalEmitter;
@property (nonatomic, strong) CAEmitterLayer *sunEmitter;
 
@end
 
@implementation ViewController
 
- (void)viewDidLoad {
    [super viewDidLoad];
 
    self.view.backgroundColor = [UIColor whiteColor];
    
    //创建控件
    [self creatControl];
}
 
- (void)creatControl
{
    //唱歌小人背景
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake((mainW - 170) * 0.5, mainH - 350, 170, 230)];
    imageView.image = [UIImage imageNamed:@"bj.jpg"];
    [self.view addSubview:imageView];
    
    //按钮标题数组
    NSArray *titleArray = @[@"唱歌", @"花瓣", @"太阳", @"停止"];
    //按钮宽度
    CGFloat btnWidth = 70;
    //按钮间距
    CGFloat padding = (mainW - btnWidth * titleArray.count) / (titleArray.count + 1);
    //创建按钮
    for (int i = 0; i < titleArray.count; i++) {
        UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(padding + (padding + btnWidth) * i, CGRectGetMaxY(imageView.frame) + 20, btnWidth, 30)];
        [btn setTitle:titleArray[i] forState:UIControlStateNormal];
        [btn setBackgroundColor:[UIColor orangeColor]];
        btn.tag = i;
        [btn addTarget:self action:@selector(btnOnClick:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:btn];
    }
}
 
- (void)btnOnClick:(UIButton *)btn
{
    //唱歌按钮点击事件
    if (btn.tag == 0) {
        //重复点击先清空发射器
        [_noteEmitter removeFromSuperlayer];
        _noteEmitter = nil;
        
        //初始化发射器
        _noteEmitter = [[CAEmitterLayer alloc] init];
        //粒子发射位置
        _noteEmitter.emitterPosition = CGPointMake(mainW * 0.5 + 15, 390);
        //发射源的尺寸大小
        _noteEmitter.emitterSize = CGSizeMake(10, 10);
        //发射模式
        _noteEmitter.renderMode = kCAEmitterLayerUnordered;
        //发射源的形状
        _noteEmitter.emitterMode = kCAEmitterLayerSurface;
        
        //发射单元
        NSMutableArray *cellArray = [NSMutableArray array];
        for (int i = 0; i < 3; i++) {
            CAEmitterCell *note = [CAEmitterCell emitterCell];
            //粒子产生速度
            note.birthRate = 0.7 + 0.5 * i;
            note.speed = 0.5;
            //粒子移动速度
            note.velocity = 100;
            //在原属性上增减的范围,现在粒子速度范围是100 - 30 ~ 100 + 30(70 ~ 130),其他属性后加Range同理
            note.velocityRange = 30;
            //粒子生命周期
            note.lifetime = 0.8;
            note.lifetimeRange = 0.1;
            //粒子旋转速度
            note.spin = 1;
            //粒子缩放比例
            note.scale = 0.1;
            note.scaleSpeed = 1;
            //粒子透明度变化速度
//            note.alphaSpeed = -0.8;
            //粒子发射角度
            note.emissionLongitude = M_PI + M_PI_2;
            note.emissionRange = M_PI_2;
            //随机生成图片名字
            NSString *str = [NSString stringWithFormat:@"note%d", arc4random_uniform(4)];
            note.contents = (__bridge id)[[UIImage imageNamed:str] CGImage];
            //粒子展示的图片
            NSString *name = [NSString stringWithFormat:@"note%d", i];
            //粒子的名字
            note.name = name;
            [cellArray addObject:note];
        }
        _noteEmitter.emitterCells = cellArray;
        //添加到layer层
        [self.view.layer addSublayer:_noteEmitter];
        
    //花瓣按钮点击事件
    }else if (btn.tag == 1) {
        [_petalEmitter removeFromSuperlayer];
        _petalEmitter = nil;
        
        _petalEmitter = [[CAEmitterLayer alloc] init];
        _petalEmitter.emitterPosition = CGPointMake(0, 0);
        _petalEmitter.emitterSize = CGSizeMake(mainW, 1);
        _petalEmitter.renderMode = kCAEmitterLayerOldestLast;
        _petalEmitter.emitterMode = kCAEmitterLayerPoints;
        _petalEmitter.emitterShape = kCAEmitterLayerRectangle;
        
        NSMutableArray *cellArray = [NSMutableArray array];
        for (int i = 0; i < 5; i++) {
            CAEmitterCell *petal = [CAEmitterCell emitterCell];
            petal.birthRate = 0.5 + 0.2 * i;
            petal.velocity = 100;
            petal.velocityRange = 100;
            petal.lifetime = 10;
            petal.spin = 0.5;
            petal.emissionLongitude = -M_PI - M_PI_2;
            petal.emissionRange = M_PI_2;
            NSString *str = [NSString stringWithFormat:@"petal%d", arc4random_uniform(5)];
            petal.contents = (__bridge id)[[UIImage imageNamed:str] CGImage];
            NSString *name = [NSString stringWithFormat:@"petal%d", i];
            petal.name = name;
            [cellArray addObject:petal];
        }
        _petalEmitter.emitterCells = cellArray;
        [self.view.layer addSublayer:_petalEmitter];
    
    //太阳按钮点击事件
    }else if (btn.tag == 2) {
        [_sunEmitter removeFromSuperlayer];
        _sunEmitter = nil;
        
        _sunEmitter = [CAEmitterLayer layer];
        _sunEmitter.frame = self.view.bounds;
        _sunEmitter.emitterPosition = CGPointMake(0, 0);
        _sunEmitter.renderMode = kCAEmitterLayerAdditive;
        
        CAEmitterCell *sun = [[CAEmitterCell alloc] init];
        sun.contents = (__bridge id)[UIImage imageNamed:@"petal4"].CGImage;
        sun.birthRate = 800;
        sun.lifetime = 2.0;
        sun.color = [UIColor colorWithRed:1 green:0.5 blue:0.1 alpha:1.0].CGColor;
        sun.alphaSpeed = -0.4;
        sun.velocity = 50;
        sun.velocityRange = 10;
        sun.emissionRange = M_PI * 2.0;
        _sunEmitter.emitterCells = @[sun];
        [self.view.layer addSublayer:_sunEmitter];
        
    //停止按钮点击事件
    }else if (btn.tag == 3) {
        [_noteEmitter removeFromSuperlayer];
        _noteEmitter = nil;
        [_petalEmitter removeFromSuperlayer];
        _petalEmitter = nil;
        [_sunEmitter removeFromSuperlayer];
        _sunEmitter = nil;
    }
}
 
@end
上一篇下一篇

猜你喜欢

热点阅读