iOS CAEmitterLayer实现粒子发射动画效果

2020-01-20 13:20:30丽君

点击按钮开始动画


@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)
}