亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS CAEmitterLayer實現粒子發射動畫效果

2020-07-26 02:47:48
字體:
來源:轉載
供稿:網友

iOS實現粒子發射動畫效果圖

代碼已上傳 GitHub:https://github.com/Silence-GitHub/CoreAnimationDemo

動畫效果用 CAEmitterLayer 實現。CAEmitterLayer 顯示粒子發射動畫,具體的粒子由 CAEmitterCell 封裝。代碼示例是展示 CAEmitterLayer 如何使用。為了方便,直接在控制器(UIViewController)中設置 CAEmitterLayer。如果在項目中使用,有時在自定義視圖(UIView)中加入 CAEmitterLayer 比較合理,例如自定義點贊按鈕,可以精簡控制器的代碼。

下雨動畫效果

這里的雨勻速下落,雨的密度逐漸變化。

給控制器添加類型為 CAEmitterLayer 的屬性 rainLayer,在 viewDidLoad 方法中對此屬性進行初始化

private var rainLayer: CAEmitterLayer!private func setupRainLayer() {  // 粒子發射圖層  rainLayer = CAEmitterLayer()  // 發射器形狀為線形,默認發射方向向上  rainLayer.emitterShape = kCAEmitterLayerLine  // 從發射器的輪廓發射粒子  rainLayer.emitterMode = kCAEmitterLayerOutline  // 優先渲染舊的粒子  rainLayer.renderMode = kCAEmitterLayerOldestFirst  // 發射位置  // 對于線形發射器,線的兩端點分別為  // (emitterPosition.x - emitterSize.width/2, emitterPosition.y, emitterZPosition)和  // (emitterPosition.x + emitterSize.width/2, emitterPosition.y, emitterZPosition)  rainLayer.emitterPosition = CGPoint(x: view.bounds.midX, y: 0)  // 發射器大小  rainLayer.emitterSize = CGSize(width: view.bounds.width, height: 0)  // 粒子生成速率的倍數,一開始不發射,設置為零  rainLayer.birthRate = 0    // 發射的粒子  let cell = CAEmitterCell()  // 粒子顯示的內容,設置CGImage,顯示圖片  cell.contents = #imageLiteral(resourceName: "Heart_red").cgImage  // 粒子縮放倍數  cell.scale = 0.1  // 粒子壽命,單位是秒  cell.lifetime = 5  // 粒子生成速率,單位是個/秒,實際顯示效果要乘以CAEmitterLayer的birthRate  cell.birthRate = 1000  // 粒子速度  cell.velocity = 500  // 粒子發射角度,正值表示順時針方向  cell.emissionLongitude = CGFloat.pi    // 圖層要發射1種粒子  rainLayer.emitterCells = [cell]  // 添加粒子發射圖層  view.layer.addSublayer(rainLayer)}

點擊按鈕開始或停止動畫。用 CABasicAnimation 使粒子生成速率的倍數漸變,達到雨逐漸變大或變小的效果

@IBAction func rainButtonClicked(_ sender: UIButton) {  // 連續調用此方法會影響雨變大或變小的連貫性,所以禁止連續點擊按鈕  sender.isUserInteractionEnabled = false  // 粒子生成速率漸變動畫  let birthRateAnimation = CABasicAnimation(keyPath: "birthRate")  birthRateAnimation.duration = 3  if rainLayer.birthRate == 0 {    // 雨變大    birthRateAnimation.fromValue = 0    birthRateAnimation.toValue = 1    rainLayer.birthRate = 1  } else {    // 雨變小    birthRateAnimation.fromValue = 1    birthRateAnimation.toValue = 0    rainLayer.birthRate = 0  }  // 加入動畫  rainLayer.add(birthRateAnimation, forKey: "birthRate")  // 動畫時長過后恢復按鈕可點擊狀態  DispatchQueue.main.asyncAfter(deadline: .now() + birthRateAnimation.duration) { [weak self] in    guard self != nil else { return }    sender.isUserInteractionEnabled = true  }}

發射一圈粒子動畫效果

給控制器添加類型為 CAEmitterLayer 的屬性 centerHeartLayer,在 viewDidLoad 方法中對此屬性進行初始化

private var centerHeartLayer: CAEmitterLayer!private func setupCenterHeartLayer() {  centerHeartLayer = CAEmitterLayer()  // 發射器形狀為圓形,默認向四周發射粒子  centerHeartLayer.emitterShape = kCAEmitterLayerCircle  centerHeartLayer.emitterMode = kCAEmitterLayerOutline  centerHeartLayer.renderMode = kCAEmitterLayerOldestFirst  // 發射器位置  // 對于圓形發射器  // 圓心位于(emitterPosition.x, emitterPosition.y, emitterZPosition)  // 半徑為emitterSize.width  centerHeartLayer.emitterPosition = CGPoint(x: view.bounds.midX, y: view.bounds.midY)  centerHeartLayer.emitterSize = centerHeartButton.frame.size  centerHeartLayer.birthRate = 0    let cell = CAEmitterCell()  cell.contents = #imageLiteral(resourceName: "Heart_red").cgImage  cell.lifetime = 1  cell.birthRate = 2000  cell.scale = 0.05  // 粒子縮放倍數每秒減小0.02,粒子逐漸縮小  cell.scaleSpeed = -0.02  // 粒子透明度每秒減小1,粒子逐漸變透明  cell.alphaSpeed = -1  cell.velocity = 30    centerHeartLayer.emitterCells = [cell]  view.layer.addSublayer(centerHeartLayer)}

點擊按鈕開始動畫

@IBAction func centerHeartButtonClicked(_ sender: UIButton) {  sender.isUserInteractionEnabled = false  // 設置動畫開始時間,否則會有太多粒子  centerHeartLayer.beginTime = CACurrentMediaTime()  // 開始生成粒子  centerHeartLayer.birthRate = 1  // 一段時間后停止生成粒子  DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in    guard let strongSelf = self else { return }    strongSelf.centerHeartLayer.birthRate = 0  }  DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in    guard self != nil else { return }    sender.isUserInteractionEnabled = true  }}

向上發射一個粒子動畫效果

給控制器添加類型為 CAEmitterLayer 的屬性 leftHeartLayer,在 viewDidLoad 方法中對此屬性進行初始化

private var leftHeartLayer: CAEmitterLayer!private func setupLeftHeartLayer() {  leftHeartLayer = CAEmitterLayer()  // 點狀發射器,默認發射方向向右  // 這句可以省略,點狀是默認值  leftHeartLayer.emitterShape = kCAEmitterLayerPoint  // 從發射器中的一點發射粒子  // 這句可以省略,是默認值  leftHeartLayer.emitterMode = kCAEmitterLayerVolume  leftHeartLayer.renderMode = kCAEmitterLayerOldestFirst  // 發射器位置  // 對于點狀發射器,發射點在(emitterPosition.x, emitterPosition.y, emitterZPosition)  leftHeartLayer.emitterPosition = CGPoint(x: view.bounds.midX * 0.5, y: view.bounds.midY)  leftHeartLayer.birthRate = 0    let cell = CAEmitterCell()  cell.contents = #imageLiteral(resourceName: "Heart_red").cgImage  cell.scale = 0.5  cell.lifetime = 1  // 1秒發射1個粒子  cell.birthRate = 1  cell.alphaSpeed = -1  cell.velocity = 50  cell.emissionLongitude = -CGFloat.pi / 2    leftHeartLayer.emitterCells = [cell]  view.layer.addSublayer(leftHeartLayer)}

點擊按鈕開始動畫

@IBAction func leftHeartButtonClicked(_ sender: UIButton) {  sender.isUserInteractionEnabled = false  // 從上1秒開始動畫,使按鈕點擊后立即發射粒子  leftHeartLayer.beginTime = CACurrentMediaTime() - 1  leftHeartLayer.birthRate = 1  DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in    guard let strongSelf = self else { return }    strongSelf.leftHeartLayer.birthRate = 0  }  DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in    guard self != nil else { return }    sender.isUserInteractionEnabled = true  }}

向上發射幾個粒子動畫效果

給控制器添加類型為 CAEmitterLayer 的屬性 rightHeartLayer,在 viewDidLoad 方法中對此屬性進行初始化

private var rightHeartLayer: CAEmitterLayer!private func setupRightHeartLayer() {  rightHeartLayer = CAEmitterLayer()  rightHeartLayer.renderMode = kCAEmitterLayerOldestFirst  rightHeartLayer.emitterPosition = CGPoint(x: view.bounds.midX * 1.5, y: view.bounds.midY)  rightHeartLayer.birthRate = 0    let cell = CAEmitterCell()  cell.contents = #imageLiteral(resourceName: "Heart_red").cgImage  cell.scale = 0.5  cell.lifetime = 1  cell.birthRate = 5  cell.alphaSpeed = -1  cell.velocity = 50  cell.emissionLongitude = -CGFloat.pi / 2  // 粒子發射角度的變化范圍  cell.emissionRange = CGFloat.pi / 4    rightHeartLayer.emitterCells = [cell]  view.layer.addSublayer(rightHeartLayer)}

點擊按鈕開始動畫

@IBAction func rightHeartButtonClicked(_ sender: UIButton) {  sender.isUserInteractionEnabled = false  // 1秒發射5個粒子,0.2秒發射1個粒子,從上0.2秒開始動畫,使按鈕點擊后立即發射粒子  rightHeartLayer.beginTime = CACurrentMediaTime() - 0.2  rightHeartLayer.birthRate = 1  DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) { [weak self] in    guard let strongSelf = self else { return }    strongSelf.rightHeartLayer.birthRate = 0  }  DispatchQueue.main.asyncAfter(deadline: .now() + 1.6) { [weak self] in    guard self != nil else { return }    sender.isUserInteractionEnabled = true  }}

拋物線粒子動畫效果

實現拋物線動畫需要給粒子加上重力加速度。此外,這里還加入粒子旋轉效果,同時發射兩種粒子。

給控制器添加類型為 CAEmitterLayer 的屬性 gravityLayer,在 viewDidLoad 方法中對此屬性進行初始化

private var gravityLayer: CAEmitterLayer!private func setupGravityLayer() {  gravityLayer = CAEmitterLayer()  gravityLayer.renderMode = kCAEmitterLayerOldestFirst  gravityLayer.emitterPosition = CGPoint(x: 0, y: view.bounds.maxY)  gravityLayer.birthRate = 0    let cell = CAEmitterCell()  cell.contents = #imageLiteral(resourceName: "Heart_red").cgImage  cell.scale = 0.5  cell.lifetime = 10  cell.alphaSpeed = -0.1  cell.birthRate = 10  cell.velocity = 100  // y軸方法的加速度,模擬重力加速度  cell.yAcceleration = 20  cell.emissionLongitude = -CGFloat.pi / 4  cell.emissionRange = CGFloat.pi / 4  // 粒子旋轉角速度,單位是弧度/秒,正值表示順時針旋轉  // 這句可以省略,默認值是零  cell.spin = 0  // 粒子旋轉角速度變化范圍  cell.spinRange = CGFloat.pi * 2    let cell2 = CAEmitterCell()  cell2.contents = #imageLiteral(resourceName: "Heart_blue").cgImage  cell2.scale = 0.3  cell2.lifetime = 20  cell2.alphaSpeed = -0.05  cell2.birthRate = 5  cell2.velocity = 135  cell2.yAcceleration = 20  cell2.emissionLongitude = -CGFloat.pi / 4  cell2.emissionRange = CGFloat.pi / 4  cell2.spin = 0  cell2.spinRange = CGFloat.pi * 2    // 圖層要發射2種粒子  gravityLayer.emitterCells = [cell, cell2]  view.layer.addSublayer(gravityLayer)}

點擊開始或停止動畫

@IBAction func gravityButtonClicked(_ sender: UIButton) {  if gravityLayer.birthRate == 0 {    gravityLayer.beginTime = CACurrentMediaTime()    gravityLayer.birthRate = 1  } else {    gravityLayer.birthRate = 0  }}

以上是動畫的實現方法,代碼已上傳 GitHub:https://github.com/Silence-GitHub/CoreAnimationDemo

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕无线精品亚洲乱码一区| 欧美激情精品在线| 中文字幕日韩综合av| 久久久免费av| 91嫩草在线视频| 日韩成人免费视频| 77777亚洲午夜久久多人| 国产精品视频导航| 精品高清美女精品国产区| 亚洲成人av在线播放| 国产成人福利夜色影视| 激情成人在线视频| 亚洲精品中文字幕av| 成人福利网站在线观看| 日韩精品中文字幕在线播放| 久久久亚洲国产天美传媒修理工| 国产欧美日韩免费| 91精品视频大全| 国产精品影片在线观看| 久久久久久午夜| 日韩精品在线观看一区| 欧美精品在线免费观看| 午夜精品久久久久久99热| 欧美国产日本在线| 欧美日韩国产一区二区三区| 欧美成人自拍视频| 亚洲老头老太hd| 欧美日韩在线一区| 亚洲а∨天堂久久精品9966| 国产一区二区精品丝袜| 欧美成人四级hd版| 日本久久精品视频| 97久久久免费福利网址| 国产精品久久精品| 成人黄色免费片| 国内免费久久久久久久久久久| 国产欧美一区二区三区久久人妖| 亚洲va国产va天堂va久久| 国产综合色香蕉精品| 久久五月天色综合| 欧美午夜视频一区二区| 91系列在线观看| 国产精品丝袜久久久久久不卡| 欧美中文字幕视频| 国产成人免费av电影| 狠狠躁天天躁日日躁欧美| 亚洲精品中文字幕av| 91久久久久久久| 亚洲欧美变态国产另类| 欧美又大又粗又长| 亚洲福利在线看| 国产精品久久久久久久久久新婚| 欧美在线观看日本一区| 精品亚洲精品福利线在观看| 日韩精品视频在线观看网址| 2019中文字幕免费视频| 永久555www成人免费| 性夜试看影院91社区| 在线观看日韩视频| 中文精品99久久国产香蕉| 欧美亚洲在线观看| 欧美日韩国产成人在线观看| 欧美成人第一页| 日韩电影中文字幕| 韩国19禁主播vip福利视频| 亚洲欧美中文字幕| 欧日韩不卡在线视频| 国外成人性视频| 欧美成人亚洲成人日韩成人| 国产欧美精品一区二区| 亚洲视频欧美视频| 国产精品自产拍高潮在线观看| 国产精品福利小视频| 亚洲成av人影院在线观看| 国产97色在线|日韩| 精品女同一区二区三区在线播放| 精品国产区一区二区三区在线观看| 欧美精品免费看| 欧美日韩国产一区在线| 国产成人极品视频| 色狠狠久久aa北条麻妃| 欧美电影免费观看高清完整| 色偷偷91综合久久噜噜| 中文国产成人精品| 欧美一区二区三区免费观看| 日本亚洲精品在线观看| 777午夜精品福利在线观看| 国产色婷婷国产综合在线理论片a| 97色在线播放视频| 国产精品伦子伦免费视频| 懂色aⅴ精品一区二区三区蜜月| 日韩免费视频在线观看| 久久综合伊人77777蜜臀| 一本色道久久88亚洲综合88| 欧美激情网站在线观看| 久久精品国产一区二区电影| 久久精彩免费视频| 国产日韩换脸av一区在线观看| 欧美午夜美女看片| 亚洲国产成人在线播放| 91精品国产91久久久久久久久| 精品高清一区二区三区| 欧美精品一区二区三区国产精品| 久久久人成影片一区二区三区| 亚洲精品美女视频| 国产精品久久久久久久app| 91福利视频在线观看| 欧美一区深夜视频| 日韩精品日韩在线观看| 亚洲视频电影图片偷拍一区| 国内伊人久久久久久网站视频| 国产精品久久久久久久美男| 色综合久久中文字幕综合网小说| 国产精品久久久999| 国产成人精品久久二区二区91| 2020欧美日韩在线视频| 亚洲最大激情中文字幕| 国产福利精品av综合导导航| 欧美日韩免费看| 97在线观看视频国产| 精品久久久久久久久久ntr影视| 欧美在线视频导航| www.国产精品一二区| 91欧美精品午夜性色福利在线| 国产亚洲成av人片在线观看桃| 97超级碰碰人国产在线观看| 久久99久久久久久久噜噜| 国产精品视频中文字幕91| 精品亚洲va在线va天堂资源站| 影音先锋欧美在线资源| 久久久噜噜噜久噜久久| 国产va免费精品高清在线观看| 欧美最猛性xxxx| 欧美亚洲国产视频| 欧美电影免费观看网站| 欧美精品videos| 热久久美女精品天天吊色| 亚洲第一精品夜夜躁人人躁| 色妞一区二区三区| 日韩av在线播放资源| 亚洲国产精品高清久久久| 日本19禁啪啪免费观看www| 九九热这里只有在线精品视| 夜夜嗨av一区二区三区免费区| 1769国内精品视频在线播放| xxxxx成人.com| 亚洲香蕉成人av网站在线观看| 亚洲伊人久久综合| 国产一区香蕉久久| 在线视频欧美日韩精品| 久热精品视频在线| 日韩专区中文字幕| 成人免费视频xnxx.com| 国产精品一香蕉国产线看观看| 欧美老女人bb| 国产一区二区动漫| 91chinesevideo永久地址| 91国产中文字幕| 亚洲人在线观看| 国产一区二区三区中文| 国产精品久久久久久亚洲影视| 91色视频在线观看| 欧美日韩中文字幕日韩欧美| 亚洲国产欧美一区二区丝袜黑人|