最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

iOS CAEmitterLayer實(shí)現(xiàn)粒子發(fā)射動(dòng)畫效果

 更新時(shí)間:2017年06月09日 17:08:52   作者:Silence_cnblogs  
這篇文章主要為大家詳細(xì)介紹了iOS CAEmitterLayer 實(shí)現(xiàn)粒子發(fā)射動(dòng)畫效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

iOS實(shí)現(xiàn)粒子發(fā)射動(dòng)畫效果圖

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

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

下雨動(dòng)畫效果

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

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

private var rainLayer: CAEmitterLayer!

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

點(diǎn)擊按鈕開始或停止動(dòng)畫。用 CABasicAnimation 使粒子生成速率的倍數(shù)漸變,達(dá)到雨逐漸變大或變小的效果

@IBAction func rainButtonClicked(_ sender: UIButton) {
  // 連續(xù)調(diào)用此方法會(huì)影響雨變大或變小的連貫性,所以禁止連續(xù)點(diǎn)擊按鈕
  sender.isUserInteractionEnabled = false
  // 粒子生成速率漸變動(dòng)畫
  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
  }
  // 加入動(dòng)畫
  rainLayer.add(birthRateAnimation, forKey: "birthRate")
  // 動(dòng)畫時(shí)長(zhǎng)過后恢復(fù)按鈕可點(diǎn)擊狀態(tài)
  DispatchQueue.main.asyncAfter(deadline: .now() + birthRateAnimation.duration) { [weak self] in
    guard self != nil else { return }
    sender.isUserInteractionEnabled = true
  }
}

發(fā)射一圈粒子動(dòng)畫效果

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

private var centerHeartLayer: CAEmitterLayer!

private func setupCenterHeartLayer() {
  centerHeartLayer = CAEmitterLayer()
  // 發(fā)射器形狀為圓形,默認(rèn)向四周發(fā)射粒子
  centerHeartLayer.emitterShape = kCAEmitterLayerCircle
  centerHeartLayer.emitterMode = kCAEmitterLayerOutline
  centerHeartLayer.renderMode = kCAEmitterLayerOldestFirst
  // 發(fā)射器位置
  // 對(duì)于圓形發(fā)射器
  // 圓心位于(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
  // 粒子縮放倍數(shù)每秒減小0.02,粒子逐漸縮小
  cell.scaleSpeed = -0.02
  // 粒子透明度每秒減小1,粒子逐漸變透明
  cell.alphaSpeed = -1
  cell.velocity = 30
  
  centerHeartLayer.emitterCells = [cell]
  view.layer.addSublayer(centerHeartLayer)
}

點(diǎn)擊按鈕開始動(dòng)畫

@IBAction func centerHeartButtonClicked(_ sender: UIButton) {
  sender.isUserInteractionEnabled = false
  // 設(shè)置動(dòng)畫開始時(shí)間,否則會(huì)有太多粒子
  centerHeartLayer.beginTime = CACurrentMediaTime()
  // 開始生成粒子
  centerHeartLayer.birthRate = 1
  // 一段時(shí)間后停止生成粒子
  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
  }
}

向上發(fā)射一個(gè)粒子動(dòng)畫效果

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

private var leftHeartLayer: CAEmitterLayer!

private func setupLeftHeartLayer() {
  leftHeartLayer = CAEmitterLayer()
  // 點(diǎn)狀發(fā)射器,默認(rèn)發(fā)射方向向右
  // 這句可以省略,點(diǎn)狀是默認(rèn)值
  leftHeartLayer.emitterShape = kCAEmitterLayerPoint
  // 從發(fā)射器中的一點(diǎn)發(fā)射粒子
  // 這句可以省略,是默認(rèn)值
  leftHeartLayer.emitterMode = kCAEmitterLayerVolume
  leftHeartLayer.renderMode = kCAEmitterLayerOldestFirst
  // 發(fā)射器位置
  // 對(duì)于點(diǎn)狀發(fā)射器,發(fā)射點(diǎn)在(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秒發(fā)射1個(gè)粒子
  cell.birthRate = 1
  cell.alphaSpeed = -1
  cell.velocity = 50
  cell.emissionLongitude = -CGFloat.pi / 2
  
  leftHeartLayer.emitterCells = [cell]
  view.layer.addSublayer(leftHeartLayer)
}

點(diǎn)擊按鈕開始動(dòng)畫

@IBAction func leftHeartButtonClicked(_ sender: UIButton) {
  sender.isUserInteractionEnabled = false
  // 從上1秒開始動(dòng)畫,使按鈕點(diǎn)擊后立即發(fā)射粒子
  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
  }
}

向上發(fā)射幾個(gè)粒子動(dòng)畫效果

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

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
  // 粒子發(fā)射角度的變化范圍
  cell.emissionRange = CGFloat.pi / 4
  
  rightHeartLayer.emitterCells = [cell]
  view.layer.addSublayer(rightHeartLayer)
}

點(diǎn)擊按鈕開始動(dòng)畫

@IBAction func rightHeartButtonClicked(_ sender: UIButton) {
  sender.isUserInteractionEnabled = false
  // 1秒發(fā)射5個(gè)粒子,0.2秒發(fā)射1個(gè)粒子,從上0.2秒開始動(dòng)畫,使按鈕點(diǎn)擊后立即發(fā)射粒子
  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
  }
}

拋物線粒子動(dòng)畫效果

實(shí)現(xiàn)拋物線動(dòng)畫需要給粒子加上重力加速度。此外,這里還加入粒子旋轉(zhuǎn)效果,同時(shí)發(fā)射兩種粒子。

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

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
  // 粒子旋轉(zhuǎn)角速度,單位是弧度/秒,正值表示順時(shí)針旋轉(zhuǎn)
  // 這句可以省略,默認(rèn)值是零
  cell.spin = 0
  // 粒子旋轉(zhuǎn)角速度變化范圍
  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
  
  // 圖層要發(fā)射2種粒子
  gravityLayer.emitterCells = [cell, cell2]
  view.layer.addSublayer(gravityLayer)
}

點(diǎn)擊開始或停止動(dòng)畫

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

以上是動(dòng)畫的實(shí)現(xiàn)方法,代碼已上傳 GitHub:https://github.com/Silence-GitHub/CoreAnimationDemo

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • IOS內(nèi)存泄漏檢查方法及重寫MLeakFinder

    IOS內(nèi)存泄漏檢查方法及重寫MLeakFinder

    這篇文章主要介紹了IOS內(nèi)存泄漏檢查方法及如何重寫MLeakFinder,幫助ios開發(fā)者維護(hù)自身程序,感興趣的朋友可以了解下
    2021-04-04
  • iOS xib文件中添加ScrollView約束的方法

    iOS xib文件中添加ScrollView約束的方法

    下面小編就為大家分享一篇iOS xib文件中添加ScrollView約束的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • iOS開發(fā)中class和#import的區(qū)別介紹

    iOS開發(fā)中class和#import的區(qū)別介紹

    這篇文章主要介紹了iOS開發(fā)中class和#import的區(qū)別,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2018-02-02
  • iOS基于UITableView實(shí)現(xiàn)多層展開與收起

    iOS基于UITableView實(shí)現(xiàn)多層展開與收起

    這篇文章主要為大家詳細(xì)介紹了iOS基于UITableView實(shí)現(xiàn)多層展開與收起的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • iOS中視頻播放器的簡(jiǎn)單封裝詳解

    iOS中視頻播放器的簡(jiǎn)單封裝詳解

    要實(shí)現(xiàn)封裝視頻播放器,首先需要實(shí)現(xiàn)視頻播放器,然后再去考慮怎樣封裝可以讓以后自己使用起來方便快捷。iOS9之前可以使用MediaPlayer來進(jìn)行視頻的播放,iOS9之后系統(tǒng)推薦使用AVFoundation框架實(shí)現(xiàn)視頻的播放。下面通過本文來看看詳細(xì)的介紹吧。
    2016-10-10
  • 實(shí)例解析iOS中音樂播放器應(yīng)用開發(fā)的基本要點(diǎn)

    實(shí)例解析iOS中音樂播放器應(yīng)用開發(fā)的基本要點(diǎn)

    這篇文章主要介紹了iOS開發(fā)中制作一個(gè)簡(jiǎn)單的音樂播放器的基本要點(diǎn)解析,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下
    2016-01-01
  • IOS實(shí)現(xiàn)郵箱模糊匹配的功能

    IOS實(shí)現(xiàn)郵箱模糊匹配的功能

    在一些App的訂單填寫頁,輸入用戶郵箱有個(gè)提示郵箱后綴的功能,很好用!還可以根據(jù)各個(gè)郵箱類型用戶量來做一個(gè)優(yōu)先級(jí)的匹配哦。這個(gè)功能該如何實(shí)現(xiàn)呢,下面來一起看看。
    2016-08-08
  • 如何實(shí)現(xiàn)IOS_SearchBar搜索欄及關(guān)鍵字高亮

    如何實(shí)現(xiàn)IOS_SearchBar搜索欄及關(guān)鍵字高亮

    本文通過實(shí)例代碼演示如何實(shí)現(xiàn)IOS搜索欄及搜索關(guān)鍵字高亮,效果很棒,小編覺得對(duì)大家的學(xué)習(xí)會(huì)很有幫助,現(xiàn)在分享給大家,有需要的可以參考學(xué)習(xí)。
    2016-08-08
  • IOS自帶Email的兩種方法實(shí)例詳解

    IOS自帶Email的兩種方法實(shí)例詳解

    這篇文章主要介紹了IOS自帶Email的兩種方法實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • ios常見加密解密方法(RSA、DES 、AES、MD5)

    ios常見加密解密方法(RSA、DES 、AES、MD5)

    本篇文章主要介紹了ios常見加密解密方法(RSA、DES 、AES、MD5),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02

最新評(píng)論

博野县| 临清市| 凌云县| 怀远县| 陕西省| 闽清县| 南安市| 清丰县| 中宁县| 宁海县| 肇源县| 南康市| 辽阳市| 雷山县| 诏安县| 岢岚县| 乌鲁木齐县| 莲花县| 伊吾县| 深圳市| 搜索| 广南县| 池州市| 蓝田县| 奉化市| 临沧市| 大安市| 玉林市| 元朗区| 桐乡市| 高要市| 左贡县| 盘锦市| 安福县| 阳春市| 栖霞市| 修文县| 密云县| 浙江省| 丹江口市| 望谟县|