下雪 下雨 等粒子动画效果
CAEmitterLayer用GPU渲染 不占用CPU
极客学院视频地址 http://www.jikexueyuan.com/course/1302_1.html?ss=2
ViewController.h
#import "ViewController.h"
#import "CAEmitterLayerView.h"
#import "SnowView.h"
#import "RainView.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//MARK: 1.用 CAEmitterLayer 产生粒子效果
[self mark1];
//MARK: 2.封装 CAEmitterLayer
CAEmitterLayerView *layerView = [[CAEmitterLayerView alloc]initWithFrame:CGRectZero];
NSLog(@"%@",layerView.layer);
//MARK: 3.封装下雪、下雨的粒子效果控件
// 优化效果 添加alpha图层 模糊边界效果
UIImageView *alphaView1 = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
alphaView1.image = [UIImage imageNamed:@"alpha"];
UIImageView *alphaView2 = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
alphaView2.image = [UIImage imageNamed:@"alpha"];
// 添加下雪效果 (在这里复习一下多态 用父类指针指向子类创建出来的对象)
CAEmitterLayerView *snowView = [[SnowView alloc]initWithFrame:CGRectMake(100, 220, 100, 100)];
snowView.maskView = alphaView1;
[self.view addSubview:snowView];
[snowView show];
// 添加下雨效果
CAEmitterLayerView *rainView = [[RainView alloc]initWithFrame:CGRectMake(220, 220, 100, 100)];
rainView.maskView = alphaView2;
[self.view addSubview:rainView];
[rainView show];
}
- (void)mark1 {
//第一步 创建出Layer
CAEmitterLayer *emitterLayer = [CAEmitterLayer layer];
// 设置基本信息
emitterLayer.borderWidth = 1.f;
// 给定尺寸
emitterLayer.frame = CGRectMake(100, 100, 100, 100);
// 不让粒子超出layer的范围
emitterLayer.masksToBounds = YES;
// 粒子发射点坐标
emitterLayer.emitterPosition = CGPointMake(0, 0);
// 发射模式
emitterLayer.emitterMode = kCAEmitterLayerSurface;
// 发射形状
emitterLayer.emitterShape = kCAEmitterLayerLine;
// 添加layer
[self.view.layer addSublayer:emitterLayer];
//第二步 创建粒子
CAEmitterCell * cell = [CAEmitterCell emitterCell];
// 粒子产生率
cell.birthRate = 1.f;
// 粒子生命周期 设置成120秒
cell.lifetime = 120.f;
// 粒子运动的速度值(10) 以及加减的范围(7~13)
cell.velocity = 10.f;
cell.velocityRange = 3.f;
// y轴加速度
cell.yAcceleration = 2.f;
// 粒子发射范围的角度
cell.emissionRange = 4 * M_1_PI;
// 设置粒子颜色
cell.color = [UIColor blackColor].CGColor;
// 设置粒子图片
cell.contents = (__bridge id)[UIImage imageNamed:@"snow"].CGImage;
//第三步 让CAEmitterLayer和CAEmitterCell产生关联
emitterLayer.emitterCells = @[cell];
}
模拟一个抽象的父类CAEmitterLayerView
CAEmitterLayerView.h
@interface CAEmitterLayerView : UIView
//模拟一个抽象的父类
/*
模仿setter,getter方法 用.语法解决设置有很多参数的问题
*/
- (void)setEmitterLayer:(CAEmitterLayer *)layer;
- (CAEmitterLayer *)emitterLayer;
//显示出当前View
- (void)show;
//隐藏当前View
- (void)hide;
CAEmitterLayerView.m
@interface CAEmitterLayerView () {
CAEmitterLayer * _emitterLayer;
}
@end
@implementation CAEmitterLayerView
//创建layer的过程中把CALayer替换成CAEmitterLayer
+ (Class)layerClass {
return [CAEmitterLayer class];
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_emitterLayer = (CAEmitterLayer *)self.layer;
}
return self;
}
- (void)setEmitterLayer:(CAEmitterLayer *)layer {
_emitterLayer = layer;
}
- (CAEmitterLayer *)emitterLayer {
return _emitterLayer;
}
- (void)show {
//这里可以说是 里氏代换原则 每个继承了CAEmitterLayerView的子类都有show的方法 但是都可以重写 实现不同的功能(只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为)
}
- (void)hide {
}
继承了CAEmitterLayerView的SnowView和RainView
SnowView.m
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initEmitterLayerProperties];
}
return self;
}
- (void)initEmitterLayerProperties {
//初始化一些参数
self.emitterLayer.masksToBounds = YES;
self.emitterLayer.emitterShape = kCAEmitterLayerLine;
self.emitterLayer.emitterMode = kCAEmitterLayerSurface;
self.emitterLayer.emitterSize = self.frame.size;
self.emitterLayer.emitterPosition = CGPointMake(self.bounds.size.width / 2.f, - 20);
}
- (void)show {
//添加 CAEmitterCell
CAEmitterCell *snowflake = [CAEmitterCell emitterCell];
snowflake.birthRate = 1.f;
snowflake.speed = 10.f;
snowflake.velocity = 2.f;
snowflake.velocityRange = 10.f;
snowflake.yAcceleration = 10.f;
snowflake.emissionRange = 0.5 * M_PI;
snowflake.spinRange = 0.25 * M_PI;
snowflake.contents = (__bridge id)([UIImage imageNamed:@"snow"].CGImage);
snowflake.color = [UIColor redColor].CGColor;
snowflake.lifetime = 60.f;
snowflake.scale = 0.5;
snowflake.scaleRange = 0.3;
// 添加动画
self.emitterLayer.emitterCells = @[snowflake];
}
RainView.m
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// 初始化设置
[self setup];
}
return self;
}
- (void)setup {
self.emitterLayer.masksToBounds = YES;
self.emitterLayer.emitterShape = kCAEmitterLayerLine;
self.emitterLayer.emitterMode = kCAEmitterLayerSurface;
self.emitterLayer.emitterSize = self.frame.size;
self.emitterLayer.emitterPosition = CGPointMake(self.bounds.size.width / 2.f, - 20);
}
- (void)show {
// 配置
CAEmitterCell *rainflake = [CAEmitterCell emitterCell];
rainflake.birthRate = 25.f;
rainflake.speed = 10.f;
rainflake.velocity = 10.f;
rainflake.velocityRange = 10.f;
rainflake.yAcceleration = 1000.f;
rainflake.contents = (__bridge id)([UIImage imageNamed:@"rain"].CGImage);
rainflake.color = [UIColor blackColor].CGColor;
rainflake.lifetime = 7.f;
rainflake.scale = 0.2f;
rainflake.scaleRange = 0.f;
// 添加动画
self.emitterLayer.emitterCells = @[rainflake];
}