iOS編程中CAEmitterLayer粒子動畫詳解

1綜述

你肯定見過很酷炫的iOS動畫吧,紅包雨芳来,下雪含末,煙花等,但是有時候確不知道從何下手即舌,iOS動畫內(nèi)容有很多佣盒,這次我們就來學(xué)習(xí)下酷炫的粒子動畫。

2.知識點(diǎn)

本文用了兩大知識點(diǎn)
1.CAGradientLayer 創(chuàng)建漸變的背景色
2.CAEmitterLayer顽聂、CAEmitterCell iOS中的粒子效果有兩部分組成肥惭,一部分為發(fā)射器CAEmitterLayer,另一部分是粒子單元CAEmitterCell紊搪,用于設(shè)置相應(yīng)的粒子屬性蜜葱。

3.代碼

CAEmitterLayer屬性:

emitterCells:CAEmitterCell對象的數(shù)組,用于把粒子投放到layer上耀石。
birthRate:粒子產(chǎn)生速度牵囤,默認(rèn)1個每秒。
lifetime:粒子純在時間滞伟,默認(rèn)1秒揭鳞。
emitterPosition:發(fā)射器在xy平面的中心位置。
emitterZPosition:發(fā)射器在z平面的位置梆奈。
preservesDepth:是否開啟三維效果野崇。
velocity:粒子運(yùn)動速度。
scale:粒子的縮放比例亩钟。
spin:自旋轉(zhuǎn)速度乓梨。
seed:用于初始化隨機(jī)數(shù)產(chǎn)生的種子。
emitterSize:發(fā)射器的尺寸清酥。
emitterDepth:發(fā)射器的深度督禽。
emitterShape:發(fā)射器的形狀
NSString * const kCAEmitterLayerPoint;//點(diǎn)的形狀,粒子從一個點(diǎn)發(fā)出
NSString * const kCAEmitterLayerLine;//線的形狀总处,粒子從一條線發(fā)出
NSString * const kCAEmitterLayerRectangle;//矩形形狀,粒子從一個矩形中發(fā)出
NSString * const kCAEmitterLayerCuboid;//立方體形狀睛蛛,會影響Z平面的效果
NSString * const kCAEmitterLayerCircle;//圓形鹦马,粒子會在圓形范圍發(fā)射
NSString * const kCAEmitterLayerSphere;//球型
emitterMode:發(fā)射器發(fā)射模式
NSString * const kCAEmitterLayerPoints;//從發(fā)射器中發(fā)出
NSString * const kCAEmitterLayerOutline;//從發(fā)射器邊緣發(fā)出
NSString * const kCAEmitterLayerSurface;//從發(fā)射器表面發(fā)出
NSString * const kCAEmitterLayerVolume;//從發(fā)射器中點(diǎn)發(fā)出
renderMode:發(fā)射器渲染模式
NSString * const kCAEmitterLayerUnordered;//粒子無序出現(xiàn)
NSString * const kCAEmitterLayerOldestFirst;//聲明久的粒子會被渲染在最上層
NSString * const kCAEmitterLayerOldestLast;//年輕的粒子會被渲染在最上層
NSString * const kCAEmitterLayerBackToFront;//粒子的渲染按照Z軸的前后順序進(jìn)行
NSString * const kCAEmitterLayerAdditive;//粒子混合


CAEmitterCell屬性:

emitterCell:初始化方法。
name:粒子的名字忆肾。
color:粒子的顏色荸频。
enabled:粒子是否渲染。
contents:渲染粒子客冈,是個CGImageRef的對象旭从,即粒子要展示的圖片。
contentsRect:渲染范圍。
birthRate:粒子產(chǎn)生速度和悦。

lifetime:生命周期退疫。
lifetimeRange:生命周期增減范圍。
velocity:粒子運(yùn)動速度鸽素。
velocityRange:速度范圍褒繁。
spin:粒子旋轉(zhuǎn)角度。
spinrange:粒子旋轉(zhuǎn)角度范圍馍忽。
scale:縮放比例棒坏。
scaleRange:縮放比例范圍。
scaleSpeed:縮放比例速度遭笋。
alphaRange::一個粒子的顏色alpha能改變的范圍坝冕。
alphaSpeed::粒子透明度在生命周期內(nèi)的改變速度。
redRange:一個粒子的顏色red能改變的范圍瓦呼。
redSpeed:粒子red在生命周期內(nèi)的改變速度喂窟。
blueRange:一個粒子的顏色blue能改變的范圍。
blueSpeed:粒子blue在生命周期內(nèi)的改變速度吵血。
greenRange:一個粒子的顏色green能改變的范圍谎替。
greenSpeed:粒子green在生命周期內(nèi)的改變速度。
xAcceleration:粒子x方向的加速度分量蹋辅。
yAcceleration:粒子y方向的加速度分量钱贯。
zAcceleration:粒子z方向的加速度分量。
emissionRange:粒子發(fā)射角度范圍侦另。
emissionLongitude:粒子在xy平面的發(fā)射角度秩命。
emissionLatitude:發(fā)射的z軸方向的發(fā)射角度。
#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];
    
    //創(chuàng)建控件
    [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];
    
    //按鈕標(biāo)題數(shù)組
    NSArray *titleArray = @[@"唱歌", @"花瓣", @"太陽", @"停止"];
    //按鈕寬度
    CGFloat btnWidth = 70;
    //按鈕間距
    CGFloat padding = (mainW - btnWidth * titleArray.count) / (titleArray.count + 1);
    //創(chuàng)建按鈕
    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
{
    //唱歌按鈕點(diǎn)擊事件
    if (btn.tag == 0) {
        //重復(fù)點(diǎn)擊先清空發(fā)射器
        [_noteEmitter removeFromSuperlayer];
        _noteEmitter = nil;
        
        //初始化發(fā)射器
        _noteEmitter = [[CAEmitterLayer alloc] init];
        //粒子發(fā)射位置
        _noteEmitter.emitterPosition = CGPointMake(mainW * 0.5 + 15, 390);
        //發(fā)射源的尺寸大小
        _noteEmitter.emitterSize = CGSizeMake(10, 10);
        //發(fā)射模式
        _noteEmitter.renderMode = kCAEmitterLayerUnordered;
        //發(fā)射源的形狀
        _noteEmitter.emitterMode = kCAEmitterLayerSurface;
        
        //發(fā)射單元
        NSMutableArray *cellArray = [NSMutableArray array];
        for (int i = 0; i < 3; i++) {
            CAEmitterCell *note = [CAEmitterCell emitterCell];
            //粒子產(chǎn)生速度
            note.birthRate = 0.7 + 0.5 * i;
            note.speed = 0.5;
            //粒子移動速度
            note.velocity = 100;
            //在原屬性上增減的范圍褒傅,現(xiàn)在粒子速度范圍是100 - 30 ~ 100 + 30(70 ~ 130),其他屬性后加Range同理
            note.velocityRange = 30;
            //粒子生命周期
            note.lifetime = 0.8;
            note.lifetimeRange = 0.1;
            //粒子旋轉(zhuǎn)速度
            note.spin = 1;
            //粒子縮放比例
            note.scale = 0.1;
            note.scaleSpeed = 1;
            //粒子透明度變化速度
//            note.alphaSpeed = -0.8;
            //粒子發(fā)射角度
            note.emissionLongitude = M_PI + M_PI_2;
            note.emissionRange = M_PI_2;
            //隨機(jī)生成圖片名字
            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];
        
    //花瓣按鈕點(diǎn)擊事件
    }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];
    
    //太陽按鈕點(diǎn)擊事件
    }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];
        
    //停止按鈕點(diǎn)擊事件
    }else if (btn.tag == 3) {
        [_noteEmitter removeFromSuperlayer];
        _noteEmitter = nil;
        [_petalEmitter removeFromSuperlayer];
        _petalEmitter = nil;
        [_sunEmitter removeFromSuperlayer];
        _sunEmitter = nil;
    }
}
 
@end
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末弃锐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子殿托,更是在濱河造成了極大的恐慌霹菊,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件支竹,死亡現(xiàn)場離奇詭異旋廷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)礼搁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門饶碘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人馒吴,你說我怎么就攤上這事扎运∩” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵豪治,是天一觀的道長洞拨。 經(jīng)常有香客問我,道長鬼吵,這世上最難降的妖魔是什么扣甲? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮齿椅,結(jié)果婚禮上琉挖,老公的妹妹穿的比我還像新娘。我一直安慰自己涣脚,他們只是感情好示辈,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著遣蚀,像睡著了一般矾麻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芭梯,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天险耀,我揣著相機(jī)與錄音,去河邊找鬼玖喘。 笑死甩牺,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的累奈。 我是一名探鬼主播贬派,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼澎媒!你這毒婦竟也來了搞乏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤戒努,失蹤者是張志新(化名)和其女友劉穎请敦,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體储玫,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侍筛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了缘缚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡敌蚜,死狀恐怖桥滨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤齐媒,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布蒲每,位于F島的核電站,受9級特大地震影響喻括,放射性物質(zhì)發(fā)生泄漏邀杏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一唬血、第九天 我趴在偏房一處隱蔽的房頂上張望望蜡。 院中可真熱鬧,春花似錦拷恨、人聲如沸脖律。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽小泉。三九已至,卻和暖如春冕杠,著一層夾襖步出監(jiān)牢的瞬間微姊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工分预, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兢交,地道東北人。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓噪舀,卻偏偏與公主長得像魁淳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子与倡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容