最近有點(diǎn)時(shí)間孽水,研究了一下CAEmitterLayer
粒子動(dòng)畫效果相艇,分享出來唯笙,以備自己以后使用肌访,先看一下基本的效果吧:
首先找默,說一下CALayer
經(jīng)常使用到的一些類
然后說一下管理
CALayer
內(nèi)容的幾個(gè)函數(shù)
addSublayer: 添加子圖層
removeFromSuperlayer將自己從父圖層中移除
insertSublayer:atIndex:在自己子圖層數(shù)組中的第idx位置添加圖層
insertSublayer:above: 將圖層layer添加在子圖層的上面
insertSublayer:below: 將圖層layer添加在子圖層的下面
replaceSublayer:with: 將圖層layer替換另一個(gè)layer
CALayer
的動(dòng)畫操作
addAnimation:forKey: 增加某一屬性的動(dòng)畫
animationForKey:獲取某一屬性的動(dòng)畫
removeAllAnimations移除所有動(dòng)畫
removeAnimationForKey:移除某一屬性的動(dòng)畫
animationKeys獲取所有的屬性動(dòng)畫
CALayer
就介紹到這里,想要了解更多的吼驶,請點(diǎn)我惩激。
今天主要介紹一下CAEmitterLayer
CAEmitterLayer
是CALayer
的一個(gè)子類,CAEmitterLayer
是用于實(shí)現(xiàn)基于Core Animation
的粒子發(fā)生器系統(tǒng),可以用來做一些酷炫的效果蟹演,比如我的demo里面的都是用CAEmitterLayer
做的一些效果风钻。
說道CAEmitterLayer
,我們不得不提到的就是CAEmitterCell
酒请, 剛才我們說CAEmitterLayer
是粒子發(fā)生器系統(tǒng)魄咕,那么CAEmitterCell
就是我們具體發(fā)射的粒子了;粒子動(dòng)畫原理其實(shí)挺簡單的蚌父,就是我們需要了解他的一些屬性哮兰,做出一些效果來毛萌,比如紅包雨這個(gè)動(dòng)畫,代碼如下:
- (void)createRedPacketSuperView:(UIView *)superView {
//設(shè)置EmitterLayer
CAEmitterLayer *redPacketLayer = [CAEmitterLayer layer];
[superView.layer addSublayer:redPacketLayer];
self.emitterlayer = redPacketLayer;
redPacketLayer.emitterShape = kCAEmitterLayerLine;// 發(fā)射源的形狀
redPacketLayer.emitterMode = kCAEmitterLayerSurface;//發(fā)射模式
redPacketLayer.emitterSize = superView.frame.size;//發(fā)射源的size 決定了發(fā)射源的大小
redPacketLayer.emitterPosition = CGPointMake(superView.frame.size.width * 0.5, superView.frame.origin.y);//發(fā)射源的位置
redPacketLayer.birthRate = 0.0f; // 每秒產(chǎn)生的粒子數(shù)量的系數(shù)
//配置EmitterCell
CAEmitterCell *emitterCell = [CAEmitterCell emitterCell];
NSString *path = [[NSBundle mainBundle] pathForResource:@"Emitter.bundle/red_packet.png" ofType:nil];
NSData *data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:path]];
emitterCell.contents = (id)[[UIImage imageWithData:data] CGImage];// 粒子的內(nèi)容 是CGImageRef類型
emitterCell.birthRate = 10.0f;// 每秒產(chǎn)生的粒子數(shù)量
emitterCell.lifetime = 20.0f;// 粒子的生命周期
emitterCell.velocity = 8.f; // 粒子的速度
emitterCell.yAcceleration = 1000.f; // 粒子再y方向的加速的
emitterCell.scale = 0.8f; // 粒子的縮放比例
redPacketLayer.emitterCells = @[emitterCell];
}
代碼很簡單喝滞,看CAEmitterLayer
和CAEmitterCell
你會(huì)發(fā)現(xiàn)阁将,這里面有好多相似的屬性,你可能會(huì)迷糊右遭,但是API說明的很清楚做盅,CAEmitterLayer的這些屬性會(huì)作為CAEmitterCell相同屬性的系數(shù),舉個(gè)例子窘哈,如果CAEmitterCell
的birthRate = 20
(每秒產(chǎn)生的粒子數(shù)量)吹榴,其所屬的CAEmitterLayer
的birthRate = 2
,那么在其他參數(shù)默認(rèn)的情況下,這個(gè)CAEmitterCell
總的每秒產(chǎn)生的粒子數(shù)量是20 * 2 = 40
滚婉。也就是每秒會(huì)產(chǎn)生20個(gè)這樣的粒子图筹。
然后我們分別來說明一下他們的屬性作用吧:
1、CAEmitterLayer
@property(nullable, copy) NSArray<CAEmitterCell *> *emitterCells; //存放例子
@property float birthRate; // 每秒產(chǎn)生的粒子數(shù)量的系數(shù)让腹,默認(rèn)為1/s
@property float lifetime;//粒子的生命周期系數(shù)远剩,默認(rèn)為1s
@property CGPoint emitterPosition;// 發(fā)射器在xy平面的中心位置
@property CGFloat emitterZPosition;// 發(fā)射器在Z平面的位置
@property CGSize emitterSize;// 發(fā)射器的尺寸大小
@property CGFloat emitterDepth;// 發(fā)射器的深度,在某些模式下會(huì)產(chǎn)生立體效果
@property(copy) CAEmitterLayerEmitterShape emitterShape;// 發(fā)射器的形狀
@property(copy) CAEmitterLayerEmitterMode emitterMode;// 發(fā)射器的發(fā)射模式
@property(copy) CAEmitterLayerRenderMode renderMode;// 發(fā)射器渲染模式
@property BOOL preservesDepth; //是否開啟三維空間效果
@property float velocity;//粒子的運(yùn)動(dòng)速度系數(shù)骇窍,默認(rèn)為1
@property float scale;//粒子的縮放比例系數(shù)瓜晤,默認(rèn)為1
@property float spin;//粒子的旋轉(zhuǎn)位置,默認(rèn)為1
@property unsigned int seed;// 隨機(jī)數(shù)發(fā)生器
這就是CAEmitterLayer
的一些屬性
其中emitterShape
包括這幾種
CA_EXTERN CAEmitterLayerEmitterShape const kCAEmitterLayerPoint
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//點(diǎn)的形狀腹纳,粒子從一個(gè)點(diǎn)發(fā)出
CA_EXTERN CAEmitterLayerEmitterShape const kCAEmitterLayerLine
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//線的形狀痢掠,粒子從一條線發(fā)出
CA_EXTERN CAEmitterLayerEmitterShape const kCAEmitterLayerRectangle
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//矩形形狀,粒子從一個(gè)矩形中發(fā)出
CA_EXTERN CAEmitterLayerEmitterShape const kCAEmitterLayerCuboid
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//立方體形狀嘲恍,這里要生效的話需要設(shè)置z方向的數(shù)據(jù)志群,如果不設(shè)置就同矩形狀
CA_EXTERN CAEmitterLayerEmitterShape const kCAEmitterLayerCircle
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//圓形,粒子會(huì)在圓形范圍發(fā)射
CA_EXTERN CAEmitterLayerEmitterShape const kCAEmitterLayerSphere
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//立體圓形(3D)蛔钙,三維的圓形,同樣需要設(shè)置z方向數(shù)據(jù)荠医,不設(shè)置則通二維一樣
emitterMode
有這幾種
CA_EXTERN CAEmitterLayerEmitterMode const kCAEmitterLayerPoints
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));////從發(fā)射器中發(fā)出
CA_EXTERN CAEmitterLayerEmitterMode const kCAEmitterLayerOutline
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));///從發(fā)射器邊緣發(fā)出
CA_EXTERN CAEmitterLayerEmitterMode const kCAEmitterLayerSurface
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//從發(fā)射器表面發(fā)出
CA_EXTERN CAEmitterLayerEmitterMode const kCAEmitterLayerVolume
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//相對于3D形狀的“球體內(nèi)”或“立方體內(nèi)”發(fā)射,從發(fā)射器中點(diǎn)發(fā)出
renderMode
有這幾種模式
CA_EXTERN CAEmitterLayerRenderMode const kCAEmitterLayerUnordered
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//粒子是無序出現(xiàn)的吁脱,多個(gè)發(fā)射源將混合
CA_EXTERN CAEmitterLayerRenderMode const kCAEmitterLayerOldestFirst
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//聲明久的粒子會(huì)被渲染在最上層
CA_EXTERN CAEmitterLayerRenderMode const kCAEmitterLayerOldestLast
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//剛開始的粒子會(huì)被渲染在最上層
CA_EXTERN CAEmitterLayerRenderMode const kCAEmitterLayerBackToFront
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//粒子的渲染按照Z軸的前后順序進(jìn)行
CA_EXTERN CAEmitterLayerRenderMode const kCAEmitterLayerAdditive
API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//這種模式會(huì)進(jìn)行粒子混合
好了,這基本上就是CAEmitterLayer
的所有屬性了彬向,然后我們說一下CAEmitterCell
的屬性兼贡、方法。
2娃胆、CAEmitterCell
+ (instancetype)emitterCell;//類方法創(chuàng)建發(fā)射粒子
+ (nullable id)defaultValueForKey:(NSString *)key;//獲取某一屬性的值
- (BOOL)shouldArchiveValueForKey:(NSString *)key;//返回指定的屬性值是否可以歸檔遍希。基本上不用
@property(nullable, copy) NSString *name;//設(shè)置發(fā)射粒子的名稱
@property(getter=isEnabled) BOOL enabled;//是否允許發(fā)射粒子渲染
@property float birthRate;//發(fā)射粒子的產(chǎn)生率里烦,默認(rèn)0
@property float lifetime;//發(fā)射粒子的生命周期,以秒為單位凿蒜。默認(rèn)0
@property float lifetimeRange;//發(fā)射粒子的生命周期范圍,以秒為單位禁谦。默認(rèn)0
@property CGFloat emissionLatitude;//發(fā)射粒子的指定緯度,緯度角代表了在x-z軸平面坐標(biāo)系中與x軸之間的夾角,也就是粒子在Z軸方向的發(fā)射角度废封,默認(rèn)0
@property CGFloat emissionLongitude;//發(fā)射粒子的指定經(jīng)度,經(jīng)度角代表了在x-y軸平面坐標(biāo)系中與x軸之間的夾角州泊,也就是粒子在xy平面的發(fā)射角度,默認(rèn)0:
@property CGFloat emissionRange;//發(fā)射粒子角度范圍,默認(rèn)0漂洋,以錐形分布開的發(fā)射角度遥皂。角度用弧度制。粒子均勻分布在這個(gè)錐形范圍內(nèi);
@property CGFloat velocity;//發(fā)射粒子的速度 刽漂,默認(rèn)0
@property CGFloat velocityRange;//發(fā)射粒子的速度范圍 演训,默認(rèn)0
@property CGFloat xAcceleration;//發(fā)射粒子x方向的加速度,默認(rèn)0
@property CGFloat yAcceleration;//發(fā)射粒子y方向的加速度贝咙,默0
@property CGFloat zAcceleration;//發(fā)射粒子z方向的加速度样悟,默認(rèn)0
@property CGFloat scale;//發(fā)射粒子的縮放系數(shù),默認(rèn)1
@property CGFloat scaleRange;//發(fā)射粒子的縮放系數(shù)范圍颈畸,默認(rèn)0
@property CGFloat scaleSpeed;//發(fā)射粒子的縮放速度乌奇,默認(rèn)0
@property CGFloat spin;//發(fā)射粒子的平均旋轉(zhuǎn)速度,默認(rèn)是0
@property CGFloat spinRange;//發(fā)射粒子的平均旋轉(zhuǎn)速度范圍眯娱,默認(rèn)是0
@property(nullable) CGColorRef color;//發(fā)射粒子的顏色,默認(rèn)白色
@property float redRange;//發(fā)射粒子紅色的范圍,默認(rèn)0
@property float greenRange;//發(fā)射粒子綠色的范圍,默認(rèn)0
@property float blueRange;//發(fā)射粒子藍(lán)色的范圍,默認(rèn)0
@property float alphaRange;//發(fā)射粒子透明度的范圍,默認(rèn)0
@property float redSpeed;//發(fā)射粒子紅色的變化速度,默認(rèn)0
@property float greenSpeed;//發(fā)射粒子綠色的變化速度,默認(rèn)0
@property float blueSpeed;//發(fā)射粒子藍(lán)色的變化速度,默認(rèn)0
@property float alphaSpeed;//發(fā)射粒子透明度的變化速度,默認(rèn)0
@property(nullable, strong) id contents;//發(fā)射的渲染粒子的內(nèi)容礁苗,可以設(shè)置為一個(gè)CGImage的對象
@property CGRect contentsRect;//發(fā)射的渲染粒子內(nèi)容的渲染范圍
@property CGFloat contentsScale;//內(nèi)容的縮放系數(shù)
//下面三個(gè)是拉伸過濾,沒使用過徙缴,具體的話可以看看這篇文章:http://www.reibang.com/p/ae216733eacc
@property(copy) NSString *minificationFilter;
@property(copy) NSString *magnificationFilter;
@property float minificationFilterBias;
@property(nullable, copy) NSArray<CAEmitterCell *> *emitterCells;// 粒子里面的包含的粒子
@property(nullable, copy) NSDictionary *style; //不知道干什么用的
基本上就是這些试伙,更多的效果,需要我們自己去探索于样,了解了他們的一些參數(shù)就可以做出一些效果來了疏叨,最后再奉上自己的demo
希望大家能提出寶貴的意見,可以給我留言穿剖,也可以發(fā)郵件到我的郵箱:namezyqyx@163.com
謝謝大家蚤蔓,如果你有更好的想法或文章請告知,不勝感激糊余。