CoreAnimation的粒子效果
2020-08-12 本文已影响0人
王俏
粒子效果
效果1
粒子效果1.gif代码实现
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) CAEmitterLayer * colorBallLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor blackColor];
[self setupEmitter];
}
- (void)setupEmitter{
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, self.view.bounds.size.width, 50)];
[self.view addSubview:label];
label.textColor = [UIColor whiteColor];
label.text = @"轻点或拖动来改变发射源位置";
label.textAlignment = NSTextAlignmentCenter;
/*
emitterShape: 形状:
1. 点;kCAEmitterLayerPoint .
2. 线;kCAEmitterLayerLine
3. 矩形框: kCAEmitterLayerRectangle
4. 立体矩形框: kCAEmitterLayerCuboid
5. 圆形: kCAEmitterLayerCircle
6. 立体圆形: kCAEmitterLayerSphere
emitterMode:
kCAEmitterLayerPoints
kCAEmitterLayerOutline
kCAEmitterLayerSurface
kCAEmitterLayerVolume
*/
//1. 设置CAEmitterLayer
CAEmitterLayer *colorBallLayer = [CAEmitterLayer layer];
[self.view.layer addSublayer:colorBallLayer];
self.colorBallLayer = colorBallLayer;
colorBallLayer.emitterSize = self.view.frame.size;
colorBallLayer.emitterShape = kCAEmitterLayerPoint;
colorBallLayer.emitterMode = kCAEmitterLayerPoints;
colorBallLayer.emitterPosition = CGPointMake(self.view.layer.bounds.size.width, 0.0f);
//2.配置CAEmitterCell
CAEmitterCell *colorBarCell = [CAEmitterCell emitterCell];
colorBarCell.name = @"colorBarCell";
colorBarCell.birthRate = 20.0f;
colorBarCell.lifetime = 10.0f;
colorBarCell.velocity = 40.0f;
colorBarCell.velocityRange = 100.0f;
colorBarCell.yAcceleration = 15.0f;
colorBarCell.emissionLatitude = M_PI;
colorBarCell.emissionRange = M_PI_4;
colorBarCell.scale = 0.2;
colorBarCell.scaleRange = 0.1;
colorBarCell.scaleSpeed = 0.02;
colorBarCell.contents = (id)[[UIImage imageNamed:@"circle_white"]CGImage];
colorBarCell.color = [[UIColor colorWithRed:0.5 green:0.0f blue:0.5f alpha:1.0f]CGColor];
colorBarCell.redRange = 1.0f;
colorBarCell.greenRange = 1.0f;
colorBarCell.alphaRange = 0.8f;
colorBarCell.blueSpeed = 1.0f;
colorBarCell.alphaSpeed = -0.1f;
colorBallLayer.emitterCells = @[colorBarCell];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
CGPoint point = [self locationFromTouchEvent:event];
[self setBallInPsition:point];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
CGPoint point = [self locationFromTouchEvent:event];
[self setBallInPsition:point];
}
/**
* 获取手指所在点
*/
- (CGPoint)locationFromTouchEvent:(UIEvent *)event{
UITouch * touch = [[event allTouches] anyObject];
return [touch locationInView:self.view];
}
/**
* 移动发射源到某个点上
*/
- (void)setBallInPsition:(CGPoint)position{
//基础动画
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"emitterCells.colorBallCell.scale"];
//fromeValue
anim.fromValue = @0.2f;
//toValue
anim.toValue = @0.5f;
//duration
anim.duration = 1.f;
//线性变换
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
//用事务包装隐式动画
[CATransaction begin];
//设置是否禁止由该事务组内的属性更改而触发的操作
[CATransaction setDisableActions:YES];
//为colorBallLayer 添加动画
[self.colorBallLayer addAnimation:anim forKey:nil];
//为colorBallLayert指定位置添加动画效果
[self.colorBallLayer setValue:[NSValue valueWithCGPoint:position] forKey:@"emitterPosition"];
//提交动画
[CATransaction commit];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
效果2
粒子效果2.gif代码实现
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) CAEmitterLayer * rainLayer;
@property (nonatomic, weak) UIImageView * imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self setupUI];
[self setupEmitter];
}
- (void)setupUI{
// 背景图片
UIImageView * imageView = [[UIImageView alloc]initWithFrame:self.view.frame];
[self.view addSubview:imageView];
self.imageView = imageView;
imageView.image = [UIImage imageNamed:@"rain"];
// 下雨按钮
UIButton * startBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:startBtn];
startBtn.frame = CGRectMake(20, self.view.bounds.size.height - 60, 80, 40);
startBtn.backgroundColor = [UIColor whiteColor];
[startBtn setTitle:@"雨停了" forState:UIControlStateNormal];
[startBtn setTitle:@"下雨" forState:UIControlStateSelected];
[startBtn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
[startBtn setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
[startBtn addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
// 雨量按钮
UIButton * rainBIgBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:rainBIgBtn];
rainBIgBtn.tag = 100;
rainBIgBtn.frame = CGRectMake(140, self.view.bounds.size.height - 60, 80, 40);
rainBIgBtn.backgroundColor = [UIColor whiteColor];
[rainBIgBtn setTitle:@"下大点" forState:UIControlStateNormal];
[rainBIgBtn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
[rainBIgBtn addTarget:self action:@selector(rainButtonClick:) forControlEvents:UIControlEventTouchUpInside];
UIButton * rainSmallBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:rainSmallBtn];
rainSmallBtn.tag = 200;
rainSmallBtn.frame = CGRectMake(240, self.view.bounds.size.height - 60, 80, 40);
rainSmallBtn.backgroundColor = [UIColor whiteColor];
[rainSmallBtn setTitle:@"太大了" forState:UIControlStateNormal];
[rainSmallBtn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
[rainSmallBtn addTarget:self action:@selector(rainButtonClick:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)buttonClick:(UIButton *)sender{
if (!sender.selected) {
sender.selected = !sender.selected;
NSLog(@"雨停了");
// 停止下雨
[self.rainLayer setValue:@0.f forKeyPath:@"birthRate"];
}else{
sender.selected = !sender.selected;
NSLog(@"开始下雨了");
// 开始下雨
[self.rainLayer setValue:@1.f forKeyPath:@"birthRate"];
}
}
- (void)rainButtonClick:(UIButton *)sender{
NSInteger rate = 1;
CGFloat scale = 0.05;
if (sender.tag == 100) {
NSLog(@"下大了");
if (self.rainLayer.birthRate < 30) {
[self.rainLayer setValue:@(self.rainLayer.birthRate + rate) forKeyPath:@"birthRate"];
[self.rainLayer setValue:@(self.rainLayer.scale + scale) forKeyPath:@"scale"];
}
}else if (sender.tag == 200){
NSLog(@"变小了");
if (self.rainLayer.birthRate > 1) {
[self.rainLayer setValue:@(self.rainLayer.birthRate - rate) forKeyPath:@"birthRate"];
[self.rainLayer setValue:@(self.rainLayer.scale - scale) forKeyPath:@"scale"];
}
}
}
- (void)setupEmitter{
// 1. 设置CAEmitterLayer
CAEmitterLayer * rainLayer = [CAEmitterLayer layer];
// 2.在背景图上添加粒子图层
[self.imageView.layer addSublayer:rainLayer];
self.rainLayer = rainLayer;
//3.发射形状--线性
rainLayer.emitterShape = kCAEmitterLayerLine;
//发射模式
rainLayer.emitterMode = kCAEmitterLayerSurface;
//发射源大小
rainLayer.emitterSize = self.view.frame.size;
//发射源位置 y最好不要设置为0 最好<0
rainLayer.emitterPosition = CGPointMake(self.view.bounds.size.width * 0.5, -10);
// 2. 配置cell
CAEmitterCell * snowCell = [CAEmitterCell emitterCell];
//粒子内容
snowCell.contents = (id)[[UIImage imageNamed:@"rain_white"] CGImage];
//每秒产生的粒子数量的系数
snowCell.birthRate = 25.f;
//粒子的生命周期
snowCell.lifetime = 20.f;
//speed粒子速度.图层的速率。用于将父时间缩放为本地时间,例如,如果速率是2,则本地时间的进度是父时间的两倍。默认值为1。
snowCell.speed = 10.f;
//粒子速度系数, 默认1.0
snowCell.velocity = 10.f;
//每个发射物体的初始平均范围,默认等于0
snowCell.velocityRange = 10.f;
//粒子在y方向的加速的
snowCell.yAcceleration = 1000.f;
//粒子缩放比例: scale
snowCell.scale = 0.1;
//粒子缩放比例范围:scaleRange
snowCell.scaleRange = 0.f;
// 3.添加到图层上
rainLayer.emitterCells = @[snowCell];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
效果3
粒子效果3.gif#import <UIKit/UIKit.h>
@interface CCLikeButton : UIButton
@end
#import "CCLikeButton.h"
@interface CCLikeButton()
@property(nonatomic,strong)CAEmitterLayer *explosionLayer;
@end
@implementation CCLikeButton
- (void)awakeFromNib{
[super awakeFromNib];
//设置粒子效果
[self setupExplosion];
}
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self setupExplosion];
}
return self;
}
//设置粒子
- (void)setupExplosion{
// 1. 粒子
CAEmitterCell * explosionCell = [CAEmitterCell emitterCell];
explosionCell.name = @"explosionCell";
//透明值变化速度
explosionCell.alphaSpeed = -1.f;
//alphaRange透明值范围
explosionCell.alphaRange = 0.10;
//生命周期
explosionCell.lifetime = 1;
//生命周期range
explosionCell.lifetimeRange = 0.1;
//粒子速度
explosionCell.velocity = 40.f;
//粒子速度范围
explosionCell.velocityRange = 10.f;
//缩放比例
explosionCell.scale = 0.08;
//缩放比例range
explosionCell.scaleRange = 0.02;
//粒子图片
explosionCell.contents = (id)[[UIImage imageNamed:@"spark_red"] CGImage];
// 2.发射源
CAEmitterLayer * explosionLayer = [CAEmitterLayer layer];
[self.layer addSublayer:explosionLayer];
self.explosionLayer = explosionLayer;
//发射院尺寸大小
self.explosionLayer.emitterSize = CGSizeMake(self.bounds.size.width + 40, self.bounds.size.height + 40);
//emitterShape表示粒子从什么形状发射出来,圆形形状
explosionLayer.emitterShape = kCAEmitterLayerCircle;
//emitterMode发射模型,轮廓模式,从形状的边界上发射粒子
explosionLayer.emitterMode = kCAEmitterLayerOutline;
//renderMode:渲染模式
explosionLayer.renderMode = kCAEmitterLayerOldestFirst;
//粒子cell 数组
explosionLayer.emitterCells = @[explosionCell];
}
-(void)layoutSubviews{
// 发射源位置
self.explosionLayer.position = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
[super layoutSubviews];
}
/**
* 选中状态 实现缩放
*/
- (void)setSelected:(BOOL)selected{
[super setSelected:selected];
// 通过关键帧动画实现缩放
CAKeyframeAnimation * animation = [CAKeyframeAnimation animation];
// 设置动画路径
animation.keyPath = @"transform.scale";
if (selected) {
// 从没有点击到点击状态 会有爆炸的动画效果
animation.values = @[@1.5,@2.0, @0.8, @1.0];
animation.duration = 0.5;
//计算关键帧方式:
animation.calculationMode = kCAAnimationCubic;
//为图层添加动画
[self.layer addAnimation:animation forKey:nil];
// 让放大动画先执行完毕 再执行爆炸动画
[self performSelector:@selector(startAnimation) withObject:nil afterDelay:0.25];
}else{
// 从点击状态normal状态 无动画效果 如果点赞之后马上取消 那么也立马停止动画
[self stopAnimation];
}
}
// 没有高亮状态
- (void)setHighlighted:(BOOL)highlighted{
[super setHighlighted:highlighted];
}
/**
* 开始动画
*/
- (void)startAnimation{
// 用KVC设置颗粒个数
[self.explosionLayer setValue:@1000 forKeyPath:@"emitterCells.explosionCell.birthRate"];
// 开始动画
self.explosionLayer.beginTime = CACurrentMediaTime();
// 延迟停止动画
[self performSelector:@selector(stopAnimation) withObject:nil afterDelay:0.15];
}
/**
* 动画结束
*/
- (void)stopAnimation{
// 用KVC设置颗粒个数
[self.explosionLayer setValue:@0 forKeyPath:@"emitterCells.explosionCell.birthRate"];
//移除动画
[self.explosionLayer removeAllAnimations];
}
- (void)drawRect:(CGRect)rect {
}
@end
效果4
粒子效果4.gif代码实现
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) CAEmitterLayer * rainLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//PS.图片随便找的.想要更好看的.可以自己配图.
//㊗️.大家端午安康--CC.
//粽子雨
//[self rainZongzi];
//红包雨
//[self hongBaoRain];
//金币雨
//[self jingbiRain];
//综合效果
[self allRain];
}
-(void)rainZongzi
{
//1. 设置CAEmitterLayer
CAEmitterLayer * rainLayer = [CAEmitterLayer layer];
//2.在背景图上添加粒子图层
[self.view.layer addSublayer:rainLayer];
self.rainLayer = rainLayer;
//3.发射形状--线性
rainLayer.emitterShape = kCAEmitterLayerLine;
rainLayer.emitterMode = kCAEmitterLayerSurface;
rainLayer.emitterSize = self.view.frame.size;
rainLayer.emitterPosition = CGPointMake(self.view.bounds.size.width * 0.5, -10);
//2. 配置cell
CAEmitterCell * snowCell = [CAEmitterCell emitterCell];
snowCell.contents = (id)[[UIImage imageNamed:@"zongzi2.jpg"] CGImage];
snowCell.birthRate = 1.0;
snowCell.lifetime = 30;
snowCell.speed = 2;
snowCell.velocity = 10.f;
snowCell.velocityRange = 10.f;
snowCell.yAcceleration = 60;
snowCell.scale = 0.05;
snowCell.scaleRange = 0.f;
// 3.添加到图层上
rainLayer.emitterCells = @[snowCell];
}
-(void)hongBaoRain
{
//1. 设置CAEmitterLayer
CAEmitterLayer * rainLayer = [CAEmitterLayer layer];
//2.在背景图上添加粒子图层
[self.view.layer addSublayer:rainLayer];
self.rainLayer = rainLayer;
//3.发射形状--线性
rainLayer.emitterShape = kCAEmitterLayerLine;
rainLayer.emitterMode = kCAEmitterLayerSurface;
rainLayer.emitterSize = self.view.frame.size;
rainLayer.emitterPosition = CGPointMake(self.view.bounds.size.width * 0.5, -10);
//2. 配置cell
CAEmitterCell * snowCell = [CAEmitterCell emitterCell];
snowCell.contents = (id)[[UIImage imageNamed:@"hongbao.png"] CGImage];
snowCell.birthRate = 1.0;
snowCell.lifetime = 30;
snowCell.speed = 2;
snowCell.velocity = 10.f;
snowCell.velocityRange = 10.f;
snowCell.yAcceleration = 60;
snowCell.scale = 0.05;
snowCell.scaleRange = 0.f;
// 3.添加到图层上
rainLayer.emitterCells = @[snowCell];
}
-(void)jingbiRain
{
//1. 设置CAEmitterLayer
CAEmitterLayer * rainLayer = [CAEmitterLayer layer];
//2.在背景图上添加粒子图层
[self.view.layer addSublayer:rainLayer];
self.rainLayer = rainLayer;
//3.发射形状--线性
rainLayer.emitterShape = kCAEmitterLayerLine;
rainLayer.emitterMode = kCAEmitterLayerSurface;
rainLayer.emitterSize = self.view.frame.size;
rainLayer.emitterPosition = CGPointMake(self.view.bounds.size.width * 0.5, -10);
//2. 配置cell
CAEmitterCell * snowCell = [CAEmitterCell emitterCell];
snowCell.contents = (id)[[UIImage imageNamed:@"jinbi.png"] CGImage];
snowCell.birthRate = 1.0;
snowCell.lifetime = 30;
snowCell.speed = 2;
snowCell.velocity = 10.f;
snowCell.velocityRange = 10.f;
snowCell.yAcceleration = 60;
snowCell.scale = 0.1;
snowCell.scaleRange = 0.f;
// 3.添加到图层上
rainLayer.emitterCells = @[snowCell];
}
-(void)allRain
{
//1. 设置CAEmitterLayer
CAEmitterLayer * rainLayer = [CAEmitterLayer layer];
//2.在背景图上添加粒子图层
[self.view.layer addSublayer:rainLayer];
self.rainLayer = rainLayer;
//3.发射形状--线性
rainLayer.emitterShape = kCAEmitterLayerLine;
rainLayer.emitterMode = kCAEmitterLayerSurface;
rainLayer.emitterSize = self.view.frame.size;
rainLayer.emitterPosition = CGPointMake(self.view.bounds.size.width * 0.5, -10);
//2. 配置cell
CAEmitterCell * snowCell = [CAEmitterCell emitterCell];
snowCell.contents = (id)[[UIImage imageNamed:@"jinbi.png"] CGImage];
snowCell.birthRate = 1.0;
snowCell.lifetime = 30;
snowCell.speed = 2;
snowCell.velocity = 10.f;
snowCell.velocityRange = 10.f;
snowCell.yAcceleration = 60;
snowCell.scale = 0.1;
snowCell.scaleRange = 0.f;
CAEmitterCell * hongbaoCell = [CAEmitterCell emitterCell];
hongbaoCell.contents = (id)[[UIImage imageNamed:@"hongbao.png"] CGImage];
hongbaoCell.birthRate = 1.0;
hongbaoCell.lifetime = 30;
hongbaoCell.speed = 2;
hongbaoCell.velocity = 10.f;
hongbaoCell.velocityRange = 10.f;
hongbaoCell.yAcceleration = 60;
hongbaoCell.scale = 0.05;
hongbaoCell.scaleRange = 0.f;
CAEmitterCell * zongziCell = [CAEmitterCell emitterCell];
zongziCell.contents = (id)[[UIImage imageNamed:@"zongzi2.jpg"] CGImage];
zongziCell.birthRate = 1.0;
zongziCell.lifetime = 30;
zongziCell.speed = 2;
zongziCell.velocity = 10.f;
zongziCell.velocityRange = 10.f;
zongziCell.yAcceleration = 60;
zongziCell.scale = 0.05;
zongziCell.scaleRange = 0.f;
// 3.添加到图层上
rainLayer.emitterCells = @[snowCell,hongbaoCell,zongziCell];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end