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