上篇的下雪动画觉得效果虽然有,但是还是没有粒子效果来的逼真。于是我就用CAEmitterlayer重新写了一下,顺便复习一下粒子效果。
粒子效果(CAEmitterlayer类)可以实现例如火焰,雨雪,烟雾,气球的漂浮缩放等效果。而且因为CAEmitterlayer运用在GPU上,在运行动画时不会消耗cpu。
这里贴一出“iOS Core Animation: Advanced Techniques”给的解释
“CAEmitterLayer 看上去像是许多 CAEmitterCell 的容器,这些 CAEmitterCell 定义了一个例子效果。你将会为不同的例子效果定义一个或多个 CAEmitterCell 作为模版,同时 CAEmitterLayer 负责基于这些模版实例化一个粒子流。一个 CAEmitterCell 类似于一个 CALayer :它有一个 contents 属性可以定义为一个 CGImage ,另外还有一些可设置属性控制着表现和行为”
重写上一个demo。先贴出主要部分:
func snowWeather() {
let snowEmitter = CAEmitterLayer()
snowEmitter.emitterPosition = CGPoint(x: self.view.bounds.size.width / 2.0, y: -30) // 发射源位置
snowEmitter.emitterSize = CGSize(width: self.view.bounds.size.width * 2.0, height: 0.0) // 发射源大小
snowEmitter.emitterShape = kCAEmitterLayerLine // 发射出的形状
snowEmitter.emitterMode = kCAEmitterLayerOutline // 发射模式
let snowflake = CAEmitterCell()
snowflake.birthRate = 1.0 // 每秒生成的粒子数
snowflake.lifetime = 100 // 粒子的生命周期
snowflake.velocity = -10 // 粒子的初始速度,正数为垂直向上,负数为垂直向下
snowflake.velocityRange = 10 // 保证范围,不会出现有反方向动画出现
snowflake.yAcceleration = 2 // xAcceleration,yAcceleration,zAcceleration表示在某个方向加速
snowflake.emissionRange = 0.5 * .pi // 以锥形分布开的发射角度,角度用弧度制,粒子均匀分布在这个锥形范围内
snowflake.spinRange = 0.25 * .pi // 粒子的平均旋转速度,弧度制
snowflake.contents = UIImage(named:"snow")?.cgImage // cell中的内容
snowflake.color = UIColor(red: 0.6, green: 0.658, blue: 0.743, alpha: 1).cgColor // cell渲染颜色
snowEmitter.shadowOpacity = 1.0
snowEmitter.shadowRadius = 0
snowEmitter.shadowOffset = CGSize(width: 0, height: 1.0)
snowEmitter.shadowColor = UIColor.white.cgColor
snowEmitter.emitterCells = [snowflake]
self.view.layer.addSublayer(snowEmitter)
}
解释下各个属性:
发射源大小。除了emitterSize外还有emitterDepth,也就是纵向深度。相当于一个立体的发射源,可以增加层次感。
发射源形状:emitterShape
/** `emitterShape' values. **/
@available(iOS 5.0, *)
public let kCAEmitterLayerPoint: String
@available(iOS 5.0, *)
public let kCAEmitterLayerLine: String
@available(iOS 5.0, *)
public let kCAEmitterLayerRectangle: String
@available(iOS 5.0, *)
public let kCAEmitterLayerCuboid: String
@available(iOS 5.0, *)
public let kCAEmitterLayerCircle: String
@available(iOS 5.0, *)
public let kCAEmitterLayerSphere: String
这我们用的比较多的是kCAEmitterLayerPoint和kCAEmitterLayerLine。一个从一个点中喷射,一个是从一条线中每个点喷射出来。
发射源形状:emitterMode
/** `emitterMode' values. **/
@available(iOS 5.0, *)
public let kCAEmitterLayerPoints: String
@available(iOS 5.0, *)
public let kCAEmitterLayerOutline: String
@available(iOS 5.0, *)
public let kCAEmitterLayerSurface: String
@available(iOS 5.0, *)
public let kCAEmitterLayerVolume: String
这两个结合在一起就能达到你想要扩散的方式。
@property float redRange;
@property float greenRange;
@property float blueRange;
@property float alphaRange;
@property float redSpeed;
@property float greenSpeed;
@property float blueSpeed;
@property float alphaSpeed;”
第一组属性是:指定color的每个通道的范围。第二组是指定改变color每个通道的速率。
渲染模式:renderMode。 下面的属性
CA_EXTERN NSString * const kCAEmitterLayerUnordered
__OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerOldestFirst
__OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerOldestLast
__OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerBackToFront
__OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerAdditive
__OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
剩下的一些属性就写在注释中偷些懒😂。
整个下雪效果就ok了,cpu消耗为了0。效果比上一个demo效果完美很多。
demo地址:https://github.com/rickierYun/CAEmitterLayerDemo