iOS动画之粒子效果

04.粒子动画

1.效果:

随机绘制一条路径,点击开始按钮,粒子动画
这里写图片描述

2.实现思路

1.搞个画板绘制路径,自定义view

2.给自定义view添加pan手势,和创建复制图层和圆形图层,只需要设置一次,在awakeFromNib方法中设置。

    // 添加pan手势
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];

    [self addGestureRecognizer:pan];

    // 创建复制图层
    CAReplicatorLayer *repLayer = [CAReplicatorLayer layer];

    repLayer.frame = self.bounds;

    [self.layer addSublayer:repLayer];


    // 创建粒子图层
    CALayer *layer = [CALayer layer];

    layer.cornerRadius = 5;

    layer.frame = CGRectMake(-100, 10, 10, 10);

    layer.backgroundColor = [UIColor whiteColor].CGColor;

    [repLayer addSublayer:layer];

    _dotLayer = layer;

3.因为核心动画只能设置一个路径,因此只能创建一个路径,懒加载路径。

- (UIBezierPath *)path
{
    if (_path == nil) {
        _path = [UIBezierPath bezierPath];
    }

    return _path;
}

4.在一开始拖动的时候,保存路径起点,设置路径起点,拖动的时候每次添加线到某个点。


    CGPoint curP = [pan locationInView:self];
    if (pan.state == UIGestureRecognizerStateBegan) {

        _startP = curP;

        [self.path moveToPoint:_startP];

    }

    [self.path addLineToPoint:curP];


    [self setNeedsDisplay];

5.路径绘制好了,点击开始按钮的时候,添加动画到图层

CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];

    anim.keyPath = @"position";
    anim.duration = 4;
    anim.path = self.path.CGPath;

    anim.repeatCount = MAXFLOAT;

    [_dotLayer addAnimation:anim forKey:@"anim"];
    anim.delegate = self;

6.复制图层

    repLayer.instanceCount = 20;
    repLayer.instanceDelay = 4 / 20.0;

    // 设置子层颜色
    repLayer.instanceColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:1].CGColor;

    // 设置子层颜色绿色通道偏移量
    repLayer.instanceGreenOffset = -0.03;

7.重绘
清空路径,重新绘制,移除图层动画。

    _path = nil;
    [_dotLayer removeAnimationForKey:@"anim"];
    [self setNeedsDisplay];

3.全部代码


#import "DrawView.h"


@interface DrawView ()

@property (nonatomic, strong) UIBezierPath *path;

@property (nonatomic, assign) CGPoint startP;

@property (nonatomic, strong)  CALayer *dotLayer;
@property (nonatomic, strong)  CAReplicatorLayer *repLayer;
@property (nonatomic, strong)  CAKeyframeAnimation *anim;

@end

@implementation DrawView
- (UIBezierPath *)path
{
    if (_path == nil) {
        _path = [UIBezierPath bezierPath];
    }
    return _path;
}

- (CAReplicatorLayer *)repLayer
{
    if (_repLayer == nil) {
        _repLayer = [CAReplicatorLayer layer];
        _repLayer.instanceCount = 20;
        _repLayer.instanceDelay = 4 / 20.0;
        _repLayer.frame = self.bounds;
        // 设置子层颜色
        _repLayer.instanceColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:1].CGColor;
        // 设置子层颜色绿色通道偏移量
        _repLayer.instanceGreenOffset = -0.03;

    }
    return _repLayer;
}

- (CALayer *)dotLayer
{
    if (_dotLayer == nil) {
        // 创建粒子图层
        _dotLayer = [CALayer layer];
        _dotLayer.cornerRadius = 5;
        _dotLayer.frame = CGRectMake(-100, 10, 10, 10);
        _dotLayer.backgroundColor = [UIColor whiteColor].CGColor;
    }
    return _dotLayer;
}
- (CAKeyframeAnimation *)anim
{
    if (_anim == nil) {
        _anim = [CAKeyframeAnimation animation];

        _anim.keyPath = @"position";
        _anim.duration = 4;

        _anim.repeatCount = MAXFLOAT;
        _anim.delegate = self;
    }
    return  _anim;
}

- (void)awakeFromNib
{
    // 添加pan手势
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];

    [self addGestureRecognizer:pan];

    // 创建复制图层
    [self.layer addSublayer:self.repLayer];
    [self.repLayer addSublayer:self.dotLayer];}

- (void)reDraw
{
    self.path = nil;
    [self.dotLayer removeAnimationForKey:@"anim"];
    [self setNeedsDisplay];
}

- (void)startAnim
{
    self.anim.path = self.path.CGPath;
    [self.dotLayer addAnimation:self.anim forKey:@"anim"];
}

- (void)pan:(UIPanGestureRecognizer *)pan
{
    CGPoint curP = [pan locationInView:self];
    if (pan.state == UIGestureRecognizerStateBegan) {
        _startP = curP;
        [self.path moveToPoint:_startP];
    }

    [self.path addLineToPoint:curP];
    [self setNeedsDisplay];
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
    [self.path stroke];
}


@end

4.Demo

https://github.com/Esdeath/ParticleEffects

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值