IOS中一个简单的粒子效果实现
1、效果图展示
2、实现思路
1> 首先要实现上面的效果,第一步要处理的就是一个简单的画板,在View上面用鼠标滑动的时候画出线条,这个功能可使用UIBezierPath实现
2> 关于粒子效果的实现,可以创建一个CALayer,然后用CAReplicatorLayer进行复制layer,从而达到粒子效果
3、代码实现
DrawView类的封装与编写
// // DrawView.m // 06-粒子效果 // // Created by xgao on 16/11/24. // Copyright (c) 2016年 xgao. All rights reserved. // #import "DrawView.h" // 复制的实例个数 static int _instansCount = 0; @interface DrawView () @property (nonatomic, strong) UIBezierPath *path; @property (nonatomic, weak) CALayer *dotLayer; @property (nonatomic, weak) CAReplicatorLayer *repL; @end @implementation DrawView #pragma mark - 懒加载点层 - (CALayer *)dotLayer{ if (_dotLayer == nil) { // 创建图层 CALayer *layer = [CALayer layer]; CGFloat wh = 10; layer.frame = CGRectMake(0, -1000, wh, wh); layer.cornerRadius = wh / 2; layer.backgroundColor = [UIColor blueColor].CGColor; // 将layer添加到CAReplicatorLayer中 [_repL addSublayer:layer]; _dotLayer = layer; } return _dotLayer; } - (UIBezierPath *)path{ if (_path == nil) { _path = [UIBezierPath bezierPath]; } return _path; } #pragma mark - 开始点击调用 // 鼠标开始点击 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ // 获取touch对象 UITouch *touch = [touches anyObject]; // 获取当前触摸点 CGPoint curP = [touch locationInView:self]; // 设置起点 [self.path moveToPoint:curP]; } // 鼠标按住移动 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ // 获取touch对象 UITouch *touch = [touches anyObject]; // 获取当前触摸点 CGPoint curP = [touch locationInView:self]; // 添加线到某个点 [_path addLineToPoint:curP]; // 重绘 [self setNeedsDisplay]; _instansCount ++; } - (void)drawRect:(CGRect)rect { // 进行路径线条的绘制 [_path stroke]; } #pragma mark - 开始动画 - (void)startAnim{ // 创建帧动画 CAKeyframeAnimation *anim = [CAKeyframeAnimation animation]; anim.keyPath = @"position"; anim.path = _path.CGPath; anim.duration = 3; anim.repeatCount = MAXFLOAT; [self.dotLayer addAnimation:anim forKey:nil]; // 注意:如果复制的子层有动画,先添加动画,再复制 // 复制子层 _repL.instanceCount = _instansCount; // 延迟图层动画 _repL.instanceDelay = 0.2; } #pragma mark - 加载完xib调用,创建复制层 - (void)awakeFromNib{ // 创建复制层 CAReplicatorLayer *repL = [CAReplicatorLayer layer]; repL.frame = self.bounds; [self.layer addSublayer:repL]; _repL = repL; } #pragma mark - 重绘 - (void)reDraw{ // 清空绘图信息 _path = nil; [self setNeedsDisplay]; // 把图层移除父控件,复制层也会移除。 [_dotLayer removeFromSuperlayer]; _dotLayer = nil; // 清空子层总数 _instansCount = 0; } @end
DrawView的使用
// 点击开始动画 - (IBAction)startAnim:(id)sender { DrawView *view = (DrawView *)self.view; [view startAnim]; } // 重置按钮 - (IBAction)reDraw:(id)sender { DrawView *view = (DrawView *)self.view; [view reDraw]; }