CAEmitterLayer粒子效果

一、CAEmitterLayer&CAEmitterCells

在 UIKit 中,粒子系统由两部分组成:
1、一个或多个 CAEmitterCells :发射器电池可以看作是单个粒子的原型(例如,一个单一的粉扑在一团烟雾)。当散发出一个粒子,UIKit根据这个发射粒子和定义的基础上创建一个随机粒子。此原型包括一些属性来控制粒子的图片,颜色,方向,运动,缩放比例和生命周期。

2、一个或多个 CAEmitterLayers, 但通常只有一个:这个发射的层主要控制粒子的形状(例如,一个点,矩形或圆形)和发射的位置(例如,在矩形内,或边缘)。这个层具有全局的乘法器,可以施加到系统内的CAEmitterCells。这些给你一个简单的方法覆盖的所有粒子的变化。比如一个人为的例子将改变x雨来模拟风的速度。

二、属性

1、CAEmitterLayer属性

(1)、装着CAEmitterCell对象的数组,被用于把粒子投放到layer上;

@property(nullable, copy) NSArray<CAEmitterCell *> *emitterCells;

(2)、粒子产生系数,默认1.0;

@property float birthRate;

(3)、粒子生命周期;

@property float lifetime;

(4)、发射源发射位置;

@property CGPoint emitterPosition;

(5)、发射源z坐标位置;

@property CGFloat emitterZPosition;

(6)、发射源大小;

@property CGSize emitterSize;

(7)、决定粒子形状的深度联系:emitter shape;

@property CGFloat emitterDepth;

(8)、发射源的形状;

@property(copy) NSString *emitterShape;
/** `emitterShape' values. **/

CA_EXTERN NSString * const kCAEmitterLayerPoint
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerLine
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerRectangle
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerCuboid
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerCircle
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerSphere
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);

(9)、发射模式;

@property(copy) NSString *emitterMode;
/** `emitterMode' values. **/

CA_EXTERN NSString * const kCAEmitterLayerPoints
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerOutline
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerSurface
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerVolume
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);

(10)、渲染模式;

@property(copy) NSString *renderMode;
/** `renderMode' values. **/

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);

(11)、粒子速度;

@property float velocity;

(12)、粒子的缩放比例;

@property float scale;

(13)、自旋转速度;

@property float spin;

(14)、用于初始化随机数产生的种子;

@property unsigned int seed;

(15)、是否启动三维效果

@property BOOL preservesDepth;

2、CAEmitterCell属性

(1)、粒子的名字;

@property(nullable, copy) NSString *name;

(2)、粒子是否被渲染;

@property(getter=isEnabled) BOOL enabled;

(3)、粒子参数的速度乘数因子;每秒发射的粒子数量;

@property float birthRate;

(4)、粒子的生命周期;

@property float lifetime;

(5)、生命周期范围差;
lifetime= lifetime(+/-) lifetimeRange

@property float lifetimeRange;

(6)、发射的z轴方向的角度;

@property CGFloat emissionLatitude;

(7)、x-y平面的发射方向;

@property CGFloat emissionLongitude;

(8)、周围发射角度;

@property CGFloat emissionRange;

(9)、粒子的速度;

@property CGFloat velocity;

(10)、粒子的速度范围差;

@property CGFloat velocityRange;

(11)、粒子x/y/z方向的加速度分量

@property CGFloat xAcceleration;
@property CGFloat yAcceleration;
@property CGFloat zAcceleration;

(12)、缩放比例;

@property CGFloat scale;

(13)、缩放比例范围差;

@property CGFloat scaleRange;

(14)、缩放比例速度;

@property CGFloat scaleSpeed;

(15)、粒子旋转角度;

@property CGFloat spin;

(16)、粒子旋转角度范围差;

@property CGFloat spinRange;

(17)、粒子的颜色

@property(nullable) CGColorRef color;

(18)、一个粒子的颜色red/green/blue/alpha能改变的范围;

@property float redRange;
@property float greenRange;
@property float blueRange;
@property float alphaRange;

(19)、粒子red/green/blue/alpha在生命周期内的改变速度;

@property float redSpeed;
@property float greenSpeed;
@property float blueSpeed;
@property float alphaSpeed;

(20)、是个CGImageRef的对象,既粒子要展现的图片;

@property(nullable, strong) id contents;

(21)、应该画在contents里的子rectangle;

@property CGRect contentsRect;

(22)、减小自己的大小

@property(copy) NSString *minificationFilter;

三、直播粒子动画

1、CAEmitterLayer实现

#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) CAEmitterLayer *emitterLayer;
@property (nonatomic ,weak)UIView *backView;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    UIView *backView = [[UIView alloc]initWithFrame:CGRectMake((CGRectGetWidth(self.view.frame) - 100)/2, 0, 100, CGRectGetHeight(self.view.frame))];
    backView.layer.masksToBounds = YES;
    [self.view addSubview:backView];
    self.backView = backView;
    
    [self.backView.layer addSublayer:self.emitterLayer];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"1111");
}

- (CAEmitterLayer *)emitterLayer{
    if (!_emitterLayer) {
        _emitterLayer = [CAEmitterLayer layer];
        //发射器在xy平面的中心位置
        _emitterLayer.emitterPosition = CGPointMake(CGRectGetWidth(self.backView.frame)/2, CGRectGetHeight(self.backView.frame) - 50);
        //发射器的尺寸大小
        _emitterLayer.emitterSize = CGSizeMake(20, 20);
        //渲染模式
        _emitterLayer.renderMode = kCAEmitterLayerOldestFirst;
        NSMutableArray *array = [NSMutableArray array];
        // 创建粒子
        for (int i = 1; i < 5; i++) {
            // 发射单元
            CAEmitterCell *stepCell = [CAEmitterCell emitterCell];
            // 粒子的创建速率,默认为1/s
            stepCell.birthRate = 1;
            // 粒子存活时间
            stepCell.lifetime = arc4random_uniform(4) + 4;
            // 粒子的生存时间容差
            stepCell.lifetimeRange = 1.5;
            UIImage *image =
            [UIImage imageNamed:[NSString stringWithFormat:@"good%d", i]];
            // 粒子显示的内容
            stepCell.contents = (id)[image CGImage];
            // 粒子的运动速度
            stepCell.velocity = arc4random_uniform(100) + 100;
            // 粒子速度的容差
            stepCell.velocityRange = 80;
            // 粒子在xy平面的发射角度
            stepCell.emissionLongitude = M_PI + M_PI_2;
            // 粒子发射角度的容差
            stepCell.emissionRange = M_PI_2 / 6;
            // 缩放比例
            stepCell.scale = 0.3;
            stepCell.scaleSpeed = 0.3;
            [array addObject:stepCell];
        }
        _emitterLayer.emitterCells = array;
        _emitterLayer.backgroundColor = [UIColor yellowColor].CGColor;
    }
    return _emitterLayer;
}

这里写图片描述

2、UIView实现

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self animateInView:self.view];
}
- (void)animateInView:(UIView *)view{
    //添加心图片
    UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 400, 30, 30)];
    int nameI = arc4random()%4 + 1;
    imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"good%d", nameI]];
    [view addSubview:imageView];
    
    //初始化状态
    imageView.transform = CGAffineTransformMakeScale(0, 0);
    imageView.alpha = 0;
    //在底部 由无到有 又小变大的弹性动画
    [UIView animateWithDuration:0.5
                          delay:0.0
         usingSpringWithDamping:0.6
          initialSpringVelocity:0.8
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         imageView.transform = CGAffineTransformIdentity;
                         imageView.alpha = 0.9;
                     }
                     completion:NULL];
    //放大后向左或向右旋转一定角度动画
    NSInteger i = arc4random_uniform(2);
    NSInteger rotationDirection = 1 - (2*i);
    NSInteger rotationFraction = arc4random_uniform(10);
    
    NSTimeInterval totalAnimationDuration = 3;
    
    [UIView animateWithDuration:totalAnimationDuration
                     animations:^{
                        imageView.transform = CGAffineTransformMakeRotation(rotationDirection*PI/(16 + rotationFraction*0.2));
                     }];
    //S型动画
    CGFloat heartSize = CGRectGetWidth(imageView.bounds);
    CGFloat heartCenterX = imageView.center.x;
    CGFloat viewHeight = CGRectGetHeight(view.bounds);

    UIBezierPath *heartTravelPath = [UIBezierPath bezierPath];
    [heartTravelPath moveToPoint:imageView.center];
    
    //随机结束点
    CGPoint endPoint = CGPointMake(heartCenterX + (rotationDirection)*arc4random_uniform(2*heartSize),viewHeight/6.0 + arc4random_uniform(viewHeight/4.0));

    NSInteger j = arc4random_uniform(2);
    NSInteger travelDirection = 1 - (2 * j); // -1 OR 1

    //绘制S型曲线 随机点
    CGFloat xDelta = (heartSize/2.0 + arc4random_uniform(2 * heartSize))*travelDirection;
    CGFloat yDelta =
    MAX(endPoint.y, MAX(arc4random_uniform(8 * heartSize), heartSize));
    //控制点1 控制点2
    CGPoint controlPoint1 = CGPointMake(heartCenterX + xDelta, yDelta);
    CGPoint controlPoint2 = CGPointMake(heartCenterX - xDelta, yDelta);

    [heartTravelPath addCurveToPoint:endPoint
                       controlPoint1:controlPoint1
                       controlPoint2:controlPoint2];
    CAKeyframeAnimation *keyFrameAnimation =
    [CAKeyframeAnimation animationWithKeyPath:@"position"];
    keyFrameAnimation.path = heartTravelPath.CGPath;
    keyFrameAnimation.timingFunction =
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    keyFrameAnimation.duration = totalAnimationDuration + endPoint.y / viewHeight;
    [imageView.layer addAnimation:keyFrameAnimation forKey:@"positionOnPath"];

    // 动画消失
    [UIView animateWithDuration:totalAnimationDuration
                     animations:^{
                         imageView.alpha = 0.0;
                     }
                     completion:^(BOOL finished) {
                         [imageView removeFromSuperview];
                     }];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值