Particle effect in iOS Animation
04. Particle Animation 1. effect:
Randomly draw a path, click the start button, particle Animation
2. Implementation ideas
1. Create a canvas to draw a path and customize the view.
2. Add a pan gesture to the custom view and create a copy layer and a Circle Layer. You only need to set it once and set it in the awakeFromNib method.
// Add the pan gesture UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget: self action: @ selector (pan :)]; [self addGestureRecognizer: pan]; // create a copy layer: CAReplicatorLayer * repLayer = [CAReplicatorLayer layer]; repLayer. frame = self. bounds; [self. layer addSublayer: repLayer]; // create a particle layer 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. Because only one path can be set for the core animation, only one path can be created.
- (UIBezierPath *)path{ if (_path == nil) { _path = [UIBezierPath bezierPath]; } return _path;}
4. When dragging at the beginning, save the path start point, set the path start point, and add the line to a certain point each time when dragging.
CGPoint curP = [pan locationInView:self]; if (pan.state == UIGestureRecognizerStateBegan) { _startP = curP; [self.path moveToPoint:_startP]; } [self.path addLineToPoint:curP]; [self setNeedsDisplay];
5. The path has been drawn. When you click the start button, add the animation to the layer.
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. Copy Layers
RepLayer. instanceCount = 20; repLayer. instanceDelay = 4/20.0; // sets the child layer color repLayer. instanceColor = [UIColor colorWithRed: 0 green: 1 blue: 0 alpha: 1]. CGColor; // set the child layer color green channel offset repLayer. instanceGreenOffset =-0.03;
7. redraw
Clear Path, redraw, and remove layer animation.
_path = nil; [_dotLayer removeAnimationForKey:@anim]; [self setNeedsDisplay];
3. All code
# 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]; _ repLayer. instanceCount = 20; _ repLayer. instanceDelay = 4/20.0; _ repLayer. frame = self. bounds; // sets the child layer color _ repLayer. instanceColor = [UIColor colorWithRed: 0 green: 1 blue: 0 alpha: 1]. CGColor; // set the child layer color green channel offset _ repLayer. instanceGreenOffset =-0.03;} return _ repLayer;}-(CALayer *) dotLayer {if (_ dotLayer = nil) {// create particle layer _ 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 {// Add pan gesture UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget: self action: @ selector (pan :)]; [self addGestureRecognizer: pan]; // create a copy layer [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