關於CAEmitterLayer和CAEmitterCell結合使用
今天我們來看下CAEmitterLayer(粒子發生器)在開發中的使用
一、CAEmitterLayer 粒子發生器
1、CAEmitterLayer是CALayer的一個子類,和CAEmitterCell一起使用可以創造出多樣的動畫效果。
2、CAEmitterLayer主要用於實現基於Core Animation的粒子發生器系統。
3、在粒子系統中,CAEmitterLayer負責發射粒子(當然粒子也可以發射粒子),而這些所謂的粒子,就是CAEmitterCell,我們可以將CAEmitterLayer比作是CAEmitterCell的容器,它會按照你的設定來以不同的樣式不斷產生粒子,也就是CAEmitterCell。
4、CAEmitterLayer決定了粒子從什麼樣的幾何特性上發射出來,這個幾何特性包括了位置,形狀,大小。另外還有一些渲染相關的特性。另外的一些屬性是CAEmitterLayer和CAEmiiterCell都有的,CAEmitterLayer的這些屬性會作為CAEmitterCell相同屬性的係數。
例如當CAEmitterCell的lifetime(生命週期)為2,其所屬CAEmitterLayer的lifetime為3時,在其它引數選擇預設值的情況下,這個CAEmitterCell的生命週期就是2*3=6秒,6秒後,CAEmitterCell就會從粒子系統中被移除。
5、CAEmitterCell則決定了粒子自身的一些特徵,例如速度,加速度,發射的範圍,顏色等等。這些屬性大多是以“中間值”配合一個範圍值的方式來表示的。
例如velocity和velocityRange。表示CAEmitterCell的初始速度為velocity ± velocityRange。
二、CAEmitterLayer的屬性
CAEmitterLayer類提供了一個粒子發射器系統為核心的動畫。這些粒子是由CAEmitterCell組成的例項,它相當於一個管理者,來管理 CAEmitterCell的發射的一些細節,比如發射的位置,發射形狀等等。
/*
@interface CAEmitterLayer : CALayer
--粒子的陣列 把設定好的粒子放入陣列設定到layer上
@property(nullable, copy) NSArray*emitterCells;
--粒子產生係數,預設1.0;每個cell的產生率乘以這個粒子產生係數,得出每一秒粒子的建立個數。 即:cell.birthRate 乘以 layer.birthRate =每秒粒子產生個數
@property float birthRate;
--粒子的生命週期係數,預設1.0 即:(cell.lifetime 乘以 layer.lifetime)等於粒子的生命週期
@property float lifetime;
--發射源中心點的位置 預設(0,0)
@property CGPoint emitterPosition;
--z軸上的位置
@property CGFloat emitterZPosition;
--是發射源的大小 並不是layer的大小
@property CGSize emitterSize;
--
@property CGFloat emitterDepth;
--發射源的形狀 有圓形 方形 線型等 粒子從什麼形狀發射出來,它並不是表示粒子自己的形狀。
kCAEmitterLayerPoints 點模式,發射器是以點的形勢發射粒子。
kCAEmitterLayerOutline 輪廓,即邊上 整個邊框都是發射點,即邊框進行發射
kCAEmitterLayerSurface 區域進行拋灑
kCAEmitterLayerVolume 容積,即3D圖形的體積內
@property(copy) NSString *emitterShape;
--發散形式
kCAEmitterLayerPoint 點形狀,發射源的形狀就是一個點,
kCAEmitterLayerLine 線形狀,發射源的形狀是一條線,位置在rect的橫向的位於垂直方向中間那條
kCAEmitterLayerRectangle 矩形狀,發射源是一個矩形,
kCAEmitterLayerCuboid 立體矩形形狀,發射源是一個立體矩形,這裡要生效的話需要設定z方向的資料,如果不設定就同矩形狀
kCAEmitterLayerCircle 圓形形狀,發射源是一個圓形,形狀為矩形包裹的那個圓,二維的
kCAEmitterLayerSphere 立體圓形,三維的圓形,同樣需要設定z方向資料,不設定則通二維一樣
@property(copy) NSString *emitterMode;
--描繪模式
kCAEmitterLayerUnordered 粒子是無序出現的,多個發射源將混合
kCAEmitterLayerOldestFirst 宣告久的粒子會被渲染在最上層
kCAEmitterLayerOldestLast 年輕的粒子會被渲染在最上層
kCAEmitterLayerBackToFront 粒子的渲染按照Z軸的前後順序進行
kCAEmitterLayerAdditive 進行粒子混合
@property(copy) NSString *renderMode;
--是否展示在z軸上的效果 把圖層進行3d變形如沿y軸旋轉90度 會有很明顯的立體效果
@property BOOL preservesDepth;
--粒子速度係數, 預設1.0 發射速度 和cell的速度屬性一起決定了粒子的速度 猜測粒子的速度是兩者的乘積
而且和cell的速度屬性不同 這個屬性可以為負 (cell.velocity 乘以 layer.velocity)等於粒子的速度
為負的時候發散方向是向反方向的 為正時是向指定方向的
@property float velocity;
--粒子的縮放比例係數, 預設1.0 縮放大小 和速度相同 粒子的scale值是兩者相乘 cell.scale 乘以 layer.scale)等於粒子的縮放比例
@property float scale;
-- 自旋轉速度係數, 預設1.0 cell.spin 乘以 layer.spin)等於粒子的自旋轉速度
@property float spin;
-- 隨機數設定種子
@property unsigned int seed;
*/
三、CAEmitterCell部分屬性
CAEmitterCell是粒子發射系統裡的粒子,用CAEmitterCell來定義你所需要的粒子的樣式,圖片,顏色,方向,運動,縮放比例和生命週期等等。
/*
@interface CAEmitterCell : NSObject
--粒子的建立
+ (instancetype)emitterCell;
--根據鍵獲得值
+ (nullable id)defaultValueForKey:(NSString *)key
--是否歸檔鍵值
- (BOOL)shouldArchiveValueForKey:(NSString *)key;
--粒子的名字,預設nil.
@property(nullable, copy) NSString *name;
--是否允許被繪製出來
@property(getter=isEnabled) BOOL enabled;
--生成速率預設0
@property float birthRate;
--生存週期以秒為單位。兩者預設0
@property float lifetime;
--生存週期的絕對值的偏移量的最大值
@property float lifetimeRange;
--z軸方向上的發射角度緯度,緯度角代表了x-z軸平面上與x軸之間的夾角,兩者預設0
@property CGFloat emissionLatitude;
--在xy平面上的發射角度經度,經度角代表了x-y軸平面上與x軸之間的夾角
@property CGFloat emissionLongitude;
--周圍發射角度,預設0
@property CGFloat emissionRange;
--放射速度兩者預設0
@property CGFloat velocity;
--速度偏移量
@property CGFloat velocityRange;
--在三個座標軸上的速度增量可以做出類似重力風吹的效果預設0
@property CGFloat xAcceleration;
@property CGFloat yAcceleration;
@property CGFloat zAcceleration;
--縮放數值
@property CGFloat scale;
--縮放數值的偏移量
@property CGFloat scaleRange;
--縮放速度不清楚怎麼設定可能和velocity屬性有關係
@property CGFloat scaleSpeed;
--旋轉
@property CGFloat spin;
--旋轉的偏移量
@property CGFloat spinRange;
--設定cell的顏色content的顏色會影響實際顏色預設白色
@property(nullable) CGColorRef color;
--設定三原色和透明度的值偏移值0-1
@property float redRange;
@property float greenRange;
@property float blueRange;
@property float alphaRange;
--變色速率
@property float redSpeed;
@property float greenSpeed;
@property float blueSpeed;
@property float alphaSpeed;
--cell的內容一般是UIImage
@property(nullable, strong) id contents;
--內容範圍預設(0,0,1,1)
@property CGRect contentsRect;
--內容縮放
@property CGFloat contentsScale;
--渲染'內容'影象時使用的濾波器引數。
@property(copy) NSString *minificationFilter;
@property(copy) NSString *magnificationFilter;
@property float minificationFilterBias;
---粒子發射的粒子
@property(nullable, copy) NSArray *emitterCells;
@property(nullable, copy) NSDictionary *style;
*/
總結,我們可以emitterShape和emitterMode組合多種需要的效果圖。
四、相關例項
1、仿造微信掉落表情效果圖:
程式碼:
- (void)snowAnimation
{
CAEmitterLayer *snowEmitter = [CAEmitterLayer layer];
//降落區域的方位
snowEmitter.frame = self.view.bounds;
//新增到父檢視Layer上
[self.view.layer addSublayer:snowEmitter];
//指定發射源的位置
snowEmitter.emitterPosition = CGPointMake(self.view.bounds.size.width / 2.0, -10);
//指定發射源的大小
snowEmitter.emitterSize = CGSizeMake(self.view.bounds.size.width, 0.0);
//指定發射源的形狀和模式 層級
snowEmitter.emitterShape = kCAEmitterLayerLine;
snowEmitter.emitterMode = kCAEmitterLayerOutline;
snowEmitter.renderMode = kCAEmitterLayerOldestFirst;
//建立CAEmitterCell
CAEmitterCell *snowflake = [CAEmitterCell emitterCell];
//每秒多少個
snowflake.birthRate = 10.0;
//存活時間
snowflake.lifetime = 50.0;
//初速度,因為動畫屬於落體效果,所以我們只需要設定它在y方向上的加速度就行了。
snowflake.velocity = 10;
//初速度範圍
snowflake.velocityRange = 5;
//y軸方向的加速度
snowflake.yAcceleration = 30;
//以錐形分佈開的發射角度。角度用弧度制。粒子均勻分佈在這個錐形範圍內。
snowflake.emissionRange = 5;
//設定降落的圖片
snowflake.contents = (id) [[UIImage imageNamed:@"love"] CGImage];
//圖片縮放比例
snowflake.scale = 0.5;
//開始動畫
snowEmitter.emitterCells = [NSArray arrayWithObject:snowflake];
}
2、煙花效果圖
程式碼:
- (void)fireWorkAnimation{
_emitterLayer = [CAEmitterLayer layer];
//發射源
_emitterLayer.emitterPosition = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height - 50);
//發射源尺寸大小
_emitterLayer.emitterSize = CGSizeMake(50, 0);
//發射源模式
_emitterLayer.emitterMode = kCAEmitterLayerOutline;
//發射源形狀
_emitterLayer.emitterShape = kCAEmitterLayerLine;
//渲染模式
_emitterLayer.renderMode = kCAEmitterLayerAdditive;
//發射方向
_emitterLayer.velocity = 1;
//產生粒子數量
_emitterLayer.seed = (arc4random() % 100 ) + 1;
CAEmitterCell *cell = [CAEmitterCell emitterCell];
//產生的速lv
cell.birthRate = 1.0;
//發射角度
cell.emissionRange = 0.11 * M_PI;
//速度
cell.velocity = 300;
//範圍
cell.velocityRange = 150;
//y 加速度
cell.yAcceleration = 75;
//存活時間
cell.lifetime = 2.04;
//cell 內容
cell.contents = (__bridge id _Nullable)([UIImage imageNamed:@"FFRing"].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:@"FFTspark"] 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.emitterLayer.emitterCells = [NSArray arrayWithObject:cell];
cell.emitterCells = [NSArray arrayWithObjects:burst, nil];
burst.emitterCells = [NSArray arrayWithObject:spark];
[self.view.layer addSublayer:self.emitterLayer];
}
demo: Github
相關文章
- 關於github的全方位使用和與個人小組專案結合Github
- 關於Unity 如何與Blazor Server結合UnityBlazorServer
- CAEmitterLayer粒子發射器MIT
- LlamaIndex RAG 和ReAct結合使用AIIndexReact
- `GitHub page` 和 `gitbook` 結合使用Github
- intervention/image和oss結合使用
- 關於SpringBoot結合mybatis後遇到的坑Spring BootMyBatis
- Celery #4 結合Flask和apscheduler使用Flask
- 關於Android Studio使用Git的總結AndroidGit
- sed命令和find命令的結合的使用
- 關於while(cin)回車結束 和 while(cin)與cin.get()結合時發現的問題While
- 關於Mysql使用的一些總結MySql
- 關於Vue中插槽的理解和總結Vue
- 關於Apache Tika的學習和使用Apache
- 關於DDD和COLA的一些總結和思考
- Go和JavaScript結合使用:抓取網頁中的影像連結GoJavaScript網頁
- go-kit結合gRpc的使用和學習GoRPC
- 關於筆試和麵試的反思總結筆試
- BFS和Dijkstra結合
- 優思學院|Python和六西格瑪管理有什麼關係?如何結合使用?Python
- 關於《以撒的結合》的探討:純善與極惡
- 關於 isset 和邏輯運算子的使用
- mongodb關於使用者許可權的總結MongoDB
- Sqlserver關於TDE透明資料加密的使用總結SQLServer加密
- 關於JS的物件導向的思考和總結JS物件
- 4_關於類的主動使用和被動使用
- Protobuf的使用,結合ideaIdea
- Room是怎樣和LiveData結合使用的?(原始碼分析)OOMLiveData原始碼
- Android RxJava系列三: 與Retrofit2結合使用和封AndroidRxJava
- 關於numpy的索引、合併、分割索引
- 關於培訓結構
- 關於微機結構
- 關於Servlet小總結Servlet
- 關於資料結構資料結構
- 關於近期的總結
- Sqlserver 關於臨時表和表變數的總結SQLServer變數
- 與阿里面試官大戰三回合,關於Redis怎麼使用?全總結在這份PDF了阿里面試Redis
- CDB和PDB關於使用者建立和使用者許可權區別
- 關於Ajax和websocket的區別以及使用場景!Web