CAShapeLayer的path动画

时间:2023-03-10 07:26:29
CAShapeLayer的path动画

CAShapeLayer的path动画

CAShapeLayer的path动画

效果

CAShapeLayer的path动画

CAShapeLayer的path动画

源码

https://github.com/YouXianMing/Animations

//
// CAShapeLayerPathController.m
// Animations
//
// Created by YouXianMing on 15/11/17.
// Copyright © 2015年 YouXianMing. All rights reserved.
// #import "CAShapeLayerPathController.h"
#import "PathView.h"
#import "UIView+SetRect.h"
#import "GCD.h" @interface CAShapeLayerPathController () @property (nonatomic, strong) PathView *pathView;
@property (nonatomic, strong) GCDTimer *timer; @property (nonatomic, strong) CAShapeLayer *lineShapeLayer;
@property (nonatomic, strong) CAShapeLayer *fillShapeLayer; @property (nonatomic) CGPoint A; @property (nonatomic, strong) CALayer *pointA; @end @implementation CAShapeLayerPathController - (void)viewDidLoad { [super viewDidLoad];
} - (void)setup { [super setup]; // background view
self.pathView = [[PathView alloc] initWithFrame:CGRectMake(, , , )];
self.pathView.center = self.view.center;
self.pathView.gap = .f;
[self.pathView setNeedsDisplay];
[self.view addSubview:self.pathView];
UIBezierPath *path = [self randomPath]; // point A
self.pointA = [CALayer layer];
self.pointA.frame = CGRectMake(, , , );
self.pointA.cornerRadius = .f;
self.pointA.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5f].CGColor;
self.pointA.position = CGPointMake(self.A.x + , self.A.y + );
[self.pathView.layer addSublayer:self.pointA]; // shape
self.fillShapeLayer = [CAShapeLayer layer];
self.fillShapeLayer.path = path.CGPath;
self.fillShapeLayer.strokeColor = [UIColor clearColor].CGColor;
self.fillShapeLayer.fillColor = [UIColor cyanColor].CGColor;
self.fillShapeLayer.lineWidth = .f;
self.fillShapeLayer.frame = CGRectMake(self.pathView.gap,
self.pathView.gap,
self.pathView.width - * self.pathView.gap,
self.pathView.width - * self.pathView.gap);
[self.pathView.layer addSublayer:self.fillShapeLayer]; // line
self.lineShapeLayer = [CAShapeLayer layer];
self.lineShapeLayer.path = path.CGPath;
self.lineShapeLayer.strokeColor = [UIColor redColor].CGColor;
self.lineShapeLayer.fillColor = [UIColor clearColor].CGColor;
self.lineShapeLayer.lineWidth = 0.5f;
self.lineShapeLayer.lineDashPattern = @[@(), @()];
self.lineShapeLayer.frame = CGRectMake(self.pathView.gap,
self.pathView.gap,
self.pathView.width - * self.pathView.gap,
self.pathView.width - * self.pathView.gap);
[self.pathView.layer addSublayer:self.lineShapeLayer]; // timer
self.timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
[self.timer event:^{ // path animation.
UIBezierPath *newPath = [self randomPath];
CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
basicAnimation.duration = 0.5;
basicAnimation.fromValue = (__bridge id)(self.lineShapeLayer.path);
basicAnimation.toValue = (__bridge id)newPath.CGPath;
self.lineShapeLayer.path = newPath.CGPath;
self.fillShapeLayer.path = newPath.CGPath;
[self.lineShapeLayer addAnimation:basicAnimation forKey:@"lineShapeLayerPath"];
[self.fillShapeLayer addAnimation:basicAnimation forKey:@"fillShapeLayerPath"]; // fillColor animation.
UIColor *newColor = [self randomColor];
CABasicAnimation *colorAnimation = [CABasicAnimation animationWithKeyPath:@"fillColor"];
colorAnimation.duration = 0.5;
colorAnimation.fromValue = (__bridge id _Nullable)(self.fillShapeLayer.fillColor);
colorAnimation.toValue = (__bridge id)newColor.CGColor;
self.fillShapeLayer.fillColor = newColor.CGColor;
[self.fillShapeLayer addAnimation:colorAnimation forKey:@"fillShapeLayerColor"]; // path animation.
CGPoint newPoint = CGPointMake(self.A.x + , self.A.y + );
CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
positionAnimation.duration = 0.5f;
positionAnimation.fromValue = [NSValue valueWithCGPoint:self.pointA.position];
positionAnimation.toValue = [NSValue valueWithCGPoint:newPoint];
self.pointA.position = newPoint;
[self.pointA addAnimation:positionAnimation forKey:@"positionAnimation"]; } timeIntervalWithSecs:.f];
[self.timer start];
} - (UIBezierPath *)randomPath { CGPoint pointA = [self randomPointA];
CGPoint pointB = [self randomPointB];
CGPoint pointC = [self randomPointC];
CGPoint pointD = [self randomPointD]; self.A = pointA; UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint:pointA];
[bezierPath addLineToPoint:pointB];
[bezierPath addLineToPoint:pointC];
[bezierPath addLineToPoint:pointD];
[bezierPath closePath]; return bezierPath;
} - (CGPoint)randomPointA { return CGPointMake(arc4random() % (int)(self.pathView.width - * self.pathView.gap), );
} - (CGPoint)randomPointB { return CGPointMake(self.pathView.width - * self.pathView.gap, arc4random() % (int)(self.pathView.width - * self.pathView.gap));
} - (CGPoint)randomPointC { return CGPointMake(arc4random() % (int)(self.pathView.width - * self.pathView.gap), self.pathView.width - * self.pathView.gap);
} - (CGPoint)randomPointD { return CGPointMake(, arc4random() % (int)(self.pathView.width - * self.pathView.gap));
} - (UIColor *)randomColor { return [UIColor colorWithRed:arc4random() % / .f
green:arc4random() % / .f
blue:arc4random() % / .f
alpha:0.5f];
} @end

细节

CAShapeLayer的path动画

注意keyPath参数。