美文网首页
iOS编程中CAEmitterLayer粒子动画详解

iOS编程中CAEmitterLayer粒子动画详解

作者: 单线程Jack | 来源:发表于2019-07-17 13:38 被阅读0次

    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
    

    相关文章

      网友评论

          本文标题:iOS编程中CAEmitterLayer粒子动画详解

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