layer介绍

一、CAEmitterLayer

CAEmitterLayer用来实现基于Core Animation的粒子发生器系统。每个粒子都是一个CAEmitterCell的实例。粒子绘制在背景色与border之上。

在属性中,可以指定Layer中的CAEmitterCell数组,每个cell定义了自己的一组属性,如速度、粒子发生率、旋转、缩放或者内容等。每个粒子也都有一个emitterCells属性,可以做为一个粒子发生器来运作。Layer还可以设置发生器位置、发生器形状、发射单元的位置等等。
下面是一段例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
self.view.backgroundColor = [UIColor colorWithRed:12/255.0f green:105/255.0f blue:244/255.0f alpha:1.0];
//在实际应用中,我们一般会将其放到可视视图之外的地方,以便更好的模拟效果,不过这里为了测试属性,将其放在可视范围内
CGRect rect = CGRectMake(0, 100, self.view.bounds.size.width, 50);
//创建发射器
CAEmitterLayer *emitterLayer = [CAEmitterLayer layer];
emitterLayer.frame = rect;
[self.view.layer addSublayer:emitterLayer];
//设置发射器类型
emitterLayer.emitterShape = kCAEmitterLayerCuboid;
emitterLayer.emitterPosition = CGPointMake(rect.size.width*0.5, rect.size.height*0.5);
emitterLayer.emitterSize = rect.size;
CAEmitterCell *emitterCell = [CAEmitterCell emitterCell];
//设置粒子展现内容
emitterCell.contents = (__bridge id _Nullable)([UIImage imageNamed:@"paopao"].CGImage);
//设置粒子创建速率,也就是每秒产生的个数
emitterCell.birthRate = 100;
//设置粒子的生命周期,也就是在屏幕上存在的时间
emitterCell.lifetime = 3.5;
//设置粒子声明周期范围
emitterCell.lifetimeRange = 1.0;
//设置y轴上的加速度
emitterCell.yAcceleration = 70.0f;
//设置x轴上的加速度
emitterCell.xAcceleration = 10.0f;
//设置粒子的初始速度
emitterCell.velocity = 20;
//设置粒子的初始角度 如果不设置这个值,我们发现粒子都是水平发射的
emitterCell.emissionLongitude = -M_PI_2;
//设置粒子的初始速度范围 在此例子中范围是 -180~220
emitterCell.velocityRange = 200.0f;
//设置粒子的初始角度范围 此例子的范围为 M_PI~0
emitterCell.emissionRange = M_PI_2;
//设置粒子的颜色
// emitterCell.color = [UIColor colorWithRed:0.9 green:1.0 blue:1.0 alpha:1.0].CGColor;
// //我们也可以设置随机颜色,并且限定范围。因为RGB的值最大为1.0,那Red来说,范围并不会变为0.6~1.3,而是0.6~1.0。相似的,如果是负值,则最小为0
// emitterCell.redRange = 0.3;
// emitterCell.greenRange = 0.3;
// emitterCell.blueRange = 0.3;
//设置粒子的大小及其大小范围
emitterCell.scale = 0.8;
emitterCell.scaleRange = 0.8;
//设置让粒子随着时间推移每秒减小15%,如果设置为正值则每秒增加
emitterCell.scaleSpeed = -0.15;
//设置粒子透明度的变化范围
emitterCell.alphaRange = 0.75;
//设置粒子变化速度
emitterCell.alphaSpeed = -0.15;
//将粒子赋给发射器
emitterLayer.emitterCells = @[emitterCell];

CAEmitterLayer通过emitterPosition指定了emitter的位置,在view的中间偏下的地方,并且形状为默认的一个点。renderMode定义了粒子的渲染方式,在这里让所有的粒子出现叠加增强的效果。birthRate让粒子每秒产生四个。

CAEmitterCell指定contents来定义了粒子的内容,emissionLongitude和emissionLatitude指定了经纬度,经度角代表了x-y轴平面上与x轴之间的夹角,纬度角代表了x-z轴平面上与x轴之间的夹角。emissionRange设置了一个范围,围绕着y轴负方向,建立了一个圆锥形,粒子从这个圆锥形的范围内打出。lifetime设置了粒子的存活时长,在1.6秒之后,粒子消失。birthRate定义每秒生成100个,与CAEmitterLayer的birtuRate相乘,即最终的粒子数量400个每秒。velcity指定了初速度,velcityRange设置初速度在300到500之间浮动,yAcceleration指定了沿y轴250的加速度,用于给粒子减速。color设置了粒子的颜色,并设置了每个色值的浮动范围,用于生成所有颜色的烟火。最后设置了名称,以后可以再次引用它。效果如下:

CAEmitterLayer.gif

二、CAGradientLayer

CAGradientLayer用来绘制渐变色,指定几个颜色值、渐变结束位置,就能在layer中绘制出渐变效果。下面是一段例子:

1
2
3
4
5
6
7
8
9
10
11
CAGradientLayer *layer = [CAGradientLayer layer];
CGRect frame = self.view.frame;
frame.origin = CGPointMake(0, 0);
layer.frame = frame;
layer.opacity = 0.5;
layer.colors = @[(id)[UIColor redColor].CGColor,(id)[UIColor greenColor].CGColor,(id)[UIColor blueColor].CGColor];
layer.locations = @[@0.2,@0.5,@0.8];
layer.startPoint = CGPointMake(0, 0);
layer.endPoint = CGPointMake(1, 1);
[self.view.layer addSublayer:layer];

例子中的layer是直接加载self.view.layer上的,位于emitterLayer上面,设置为半透明,在渐变色下显示出图片内容。colors指定渐变色选取红色、绿色和蓝色三色。locations设置了红色与绿色的渐变区域在20%与50%之间,小于20%的位置为红色,50%位置为绿色,绿色与蓝色的渐变区域在50%与80%之间,大于80%的位置为蓝色。startPoint设置为左上角,endPoint设置为右下角,颜色从左上角逐渐变到右下角。效果如下:

CAGradientLayer.gif

三、CAReplicatorLayer

CAReplicatorLayer创建layer和它的sublayer的多个副本,副本可以设置transform来变形,或者设置颜色、透明度的变化。例子如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 背景 layer
CAReplicatorLayer * repLayer = [CAReplicatorLayer layer];
repLayer.frame = self.view.frame;
repLayer.backgroundColor = [UIColor clearColor].CGColor;
[self.view.layer addSublayer:repLayer];
// 1、单个原点: 原始层
CALayer * dotLayer = [CALayer layer];
dotLayer.frame = CGRectMake(0, 0, 10, 10);
dotLayer.position = CGPointMake(59, 61);
dotLayer.cornerRadius = 5;
dotLayer.borderWidth = 1;
dotLayer.backgroundColor = [UIColor colorWithWhite:0.8 alpha:1].CGColor;
dotLayer.borderColor = [UIColor colorWithWhite:1.0 alpha:1].CGColor;
// Rasterize 光栅栏 效果
dotLayer.shouldRasterize = YES;
// 加在 replicator layer 上的 layer 可以复制
[repLayer addSublayer:dotLayer];
// 2、只是为一个点添加了动画
CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
// 设置动画的路径 为 设置好的 贝塞尔曲线
animation.path = [self creatBezierPath];
animation.repeatCount = INFINITY;
animation.duration = 4;
[dotLayer addAnimation:animation forKey:nil];
// 3、设置延时,拷贝数量
repLayer.instanceDelay = 0.1;
repLayer.instanceCount = 20;
// 4、改变颜色、设置颜色的 偏移
repLayer.instanceColor = [UIColor greenColor].CGColor;
//repLayer.instanceGreenOffset = -0.03;

利用 pinterCode 软件 计算的路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
- (CGPathRef)creatBezierPath {
UIBezierPath* bezierPath = UIBezierPath.bezierPath;
[bezierPath moveToPoint: CGPointMake(59, 61)];
[bezierPath addLineToPoint: CGPointMake(65.21, 66.9)];
[bezierPath addLineToPoint: CGPointMake(73.69, 65.77)];
[bezierPath addLineToPoint: CGPointMake(75.25, 74.19)];
[bezierPath addLineToPoint: CGPointMake(82.78, 78.27)];
[bezierPath addLineToPoint: CGPointMake(79.09, 86)];
[bezierPath addLineToPoint: CGPointMake(82.78, 93.73)];
[bezierPath addLineToPoint: CGPointMake(75.25, 97.81)];
[bezierPath addLineToPoint: CGPointMake(73.69, 106.23)];
[bezierPath addLineToPoint: CGPointMake(65.21, 105.1)];
[bezierPath addLineToPoint: CGPointMake(59, 111)];
[bezierPath addLineToPoint: CGPointMake(52.79, 105.1)];
[bezierPath addLineToPoint: CGPointMake(44.31, 106.23)];
[bezierPath addLineToPoint: CGPointMake(42.75, 97.81)];
[bezierPath addLineToPoint: CGPointMake(35.22, 93.73)];
[bezierPath addLineToPoint: CGPointMake(38.91, 86)];
[bezierPath addLineToPoint: CGPointMake(35.22, 78.27)];
[bezierPath addLineToPoint: CGPointMake(42.75, 74.19)];
[bezierPath addLineToPoint: CGPointMake(44.31, 65.77)];
[bezierPath addLineToPoint: CGPointMake(52.79, 66.9)];
[bezierPath closePath];
// 放大
CGAffineTransform scale = CGAffineTransformMakeScale(3, 3);
// 生成 CGPath 拷贝 (副本)
CGPathRef pathRef = CGPathCreateCopyByTransformingPath(bezierPath.CGPath, &scale);
return pathRef;
}

效果如下:
CAReplicatorLayer.gif