使用CAReplicatorLayer [2]
工具类
// // Math.h // MathEquation // // Created by YouXianMing on 15/11/20. // Copyright © 2015年 YouXianMing. All rights reserved. // #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> struct MATHPoint { CGFloat x; CGFloat y; }; typedef struct MATHPoint MATHPoint; static inline MATHPoint MATHPointMake(CGFloat x, CGFloat y) { MATHPoint p; p.x = x; p.y = y; return p; } @interface Math : NSObject #pragma mark - Radian & degree. /** * Convert radian to degree. * * @param radian Radian. * * @return Degree. */ + (CGFloat)degreeFromRadian:(CGFloat)radian; /** * Convert degree to radian. * * @param degree Degree. * * @return radian. */ + (CGFloat)radianFromDegree:(CGFloat)degree; #pragma mark - Calculate radian. /** * Radian value from math 'tan' function. * * @param sideA Side A * @param sideB Side B * * @return Radian value. */ + (CGFloat)radianValueFromTanSideA:(CGFloat)sideA sideB:(CGFloat)sideB; #pragma mark - Calculate once linear equation (Y = kX + b). @property (nonatomic) CGFloat k; @property (nonatomic) CGFloat b; /** * Calculate constant & slope by two math point for once linear equation. * * @param pointA Point A. * @param pointB Point B. * * @return Math object. */ + (instancetype)mathOnceLinearEquationWithPointA:(MATHPoint)pointA PointB:(MATHPoint)pointB; /** * Get X value when Y equal some number. * * @param yValue Some number. * * @return X number. */ - (CGFloat)xValueWhenYEqual:(CGFloat)yValue; /** * Get Y value when X equal some number. * * @param xValue Some number. * * @return Y number. */ - (CGFloat)yValueWhenXEqual:(CGFloat)xValue; #pragma mark - Reset size. /** * Get the new size with the fixed width. * * @param size Old size. * @param width The fixed width. * * @return New size. */ + (CGSize)resetFromSize:(CGSize)size withFixedWidth:(CGFloat)width; /** * Get the new size with the fixed height. * * @param size Old size. * @param height The fixed width. * * @return New size. */ + (CGSize)resetFromSize:(CGSize)size withFixedHeight:(CGFloat)height; @end
// // Math.m // MathEquation // // Created by YouXianMing on 15/11/20. // Copyright © 2015年 YouXianMing. All rights reserved. // #import "Math.h" @implementation Math + (CGFloat)degreeFromRadian:(CGFloat)radian { return ((radian) * (180.0 / M_PI)); } + (CGFloat)radianFromDegree:(CGFloat)degree { return ((degree) * M_PI / 180.f); } + (CGFloat)radianValueFromTanSideA:(CGFloat)sideA sideB:(CGFloat)sideB { return atan2f(sideA, sideB); } CGFloat calculateSlope(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2) { if (x2 == x1) { return 0; } return (y2 - y1) / (x2 - x1); } CGFloat calculateConstant(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2) { if (x2 == x1) { return 0; } return (y1*(x2 - x1) - x1*(y2 - y1)) / (x2 - x1); } + (instancetype)mathOnceLinearEquationWithPointA:(MATHPoint)pointA PointB:(MATHPoint)pointB { Math *equation = [[[self class] alloc] init]; CGFloat x1 = pointA.x; CGFloat y1 = pointA.y; CGFloat x2 = pointB.x; CGFloat y2 = pointB.y; equation.k = calculateSlope(x1, y1, x2, y2); equation.b = calculateConstant(x1, y1, x2, y2); return equation; } - (CGFloat)xValueWhenYEqual:(CGFloat)yValue { if (_k == 0) { return 0; } return (yValue - _b) / _k; } - (CGFloat)yValueWhenXEqual:(CGFloat)xValue { return _k * xValue + _b; } + (CGSize)resetFromSize:(CGSize)size withFixedWidth:(CGFloat)width { CGFloat newHeight = size.height * (width / size.width); CGSize newSize = CGSizeMake(width, newHeight); return newSize; } + (CGSize)resetFromSize:(CGSize)size withFixedHeight:(CGFloat)height { float newWidth = size.width * (height / size.height); CGSize newSize = CGSizeMake(newWidth, height); return newSize; } @end
进行角度旋转
// // ViewController.m // CAReplicatorLayer // // Created by YouXianMing on 16/1/13. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "ViewController.h" #import "Math.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Create CAReplicatorLayer. CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer]; replicatorLayer.frame = CGRectMake(0, 0, 100, 100); replicatorLayer.borderWidth = 0.5f; replicatorLayer.borderColor = [UIColor blackColor].CGColor; replicatorLayer.position = self.view.center; [self.view.layer addSublayer:replicatorLayer]; // Create Layer. CALayer *layer = [CALayer layer]; layer.frame = CGRectMake(0, 0, 8, 40); layer.backgroundColor = [UIColor redColor].CGColor; [replicatorLayer addSublayer:layer]; replicatorLayer.instanceCount = 3; CATransform3D transform = CATransform3DIdentity; transform = CATransform3DRotate(transform, [Math radianFromDegree:45.f], 0, 0, 1); replicatorLayer.instanceTransform = transform; } @end
进行颜色设置
// // ViewController.m // CAReplicatorLayer // // Created by YouXianMing on 16/1/13. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "ViewController.h" #import "Math.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Create CAReplicatorLayer. CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer]; replicatorLayer.frame = CGRectMake(0, 0, 100, 100); replicatorLayer.borderWidth = 0.5f; replicatorLayer.borderColor = [UIColor blackColor].CGColor; replicatorLayer.position = self.view.center; [self.view.layer addSublayer:replicatorLayer]; // Create Layer. CALayer *layer = [CALayer layer]; layer.frame = CGRectMake(0, 0, 8, 40); layer.backgroundColor = [UIColor whiteColor].CGColor; [replicatorLayer addSublayer:layer]; replicatorLayer.instanceCount = 8; CATransform3D transform = CATransform3DIdentity; transform = CATransform3DRotate(transform, [Math radianFromDegree:45.f], 0, 0, 1); replicatorLayer.instanceTransform = transform; replicatorLayer.instanceBlueOffset = -0.2; replicatorLayer.instanceGreenOffset = -0.1; replicatorLayer.instanceRedOffset = 0.1; } @end
设置第一个对象的颜色
// // ViewController.m // CAReplicatorLayer // // Created by YouXianMing on 16/1/13. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "ViewController.h" #import "Math.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Create CAReplicatorLayer. CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer]; replicatorLayer.frame = CGRectMake(0, 0, 100, 100); replicatorLayer.borderWidth = 0.5f; replicatorLayer.borderColor = [UIColor blackColor].CGColor; replicatorLayer.position = self.view.center; [self.view.layer addSublayer:replicatorLayer]; // Create Layer. CALayer *layer = [CALayer layer]; layer.frame = CGRectMake(0, 0, 8, 40); layer.backgroundColor = [UIColor whiteColor].CGColor; [replicatorLayer addSublayer:layer]; replicatorLayer.instanceCount = 8; CATransform3D transform = CATransform3DIdentity; transform = CATransform3DRotate(transform, [Math radianFromDegree:45.f], 0, 0, 1); replicatorLayer.instanceTransform = transform; replicatorLayer.instanceColor = [[UIColor redColor] colorWithAlphaComponent:0.3f].CGColor; replicatorLayer.instanceBlueOffset = -0.3f; replicatorLayer.instanceGreenOffset = -0.3f; replicatorLayer.instanceRedOffset = -0.3f; } @end
综合使用
// // ViewController.m // CAReplicatorLayer // // Created by YouXianMing on 16/1/13. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "ViewController.h" #import "Math.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Create CAReplicatorLayer. CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer]; replicatorLayer.frame = CGRectMake(0, 0, 100, 100); replicatorLayer.borderWidth = 0.5f; replicatorLayer.borderColor = [UIColor blackColor].CGColor; replicatorLayer.position = self.view.center; [self.view.layer addSublayer:replicatorLayer]; // Create Layer. CALayer *layer = [CALayer layer]; layer.frame = CGRectMake(0, 0, 8, 40); layer.backgroundColor = [UIColor whiteColor].CGColor; [replicatorLayer addSublayer:layer]; { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.y"]; animation.toValue = @(layer.position.y - 25.f); animation.duration = 0.5f; animation.autoreverses = true; animation.repeatCount = CGFLOAT_MAX; [layer addAnimation:animation forKey:nil]; } replicatorLayer.instanceCount = 0; CATransform3D transform = CATransform3DIdentity; transform = CATransform3DRotate(transform, [Math radianFromDegree:45.f], 0, 0, 1); replicatorLayer.instanceTransform = transform; replicatorLayer.instanceColor = [[UIColor redColor] colorWithAlphaComponent:0.3f].CGColor; replicatorLayer.instanceBlueOffset = -0.3f; replicatorLayer.instanceGreenOffset = -0.3f; replicatorLayer.instanceRedOffset = -0.3f; replicatorLayer.instanceDelay = 0.1f; { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"instanceCount"]; animation.fromValue = @(replicatorLayer.instanceCount); animation.toValue = @(9); animation.duration = 0.3f; animation.autoreverses = true; animation.repeatCount = CGFLOAT_MAX; [replicatorLayer addAnimation:animation forKey:nil]; } } @end
// // ViewController.m // CAReplicatorLayer // // Created by YouXianMing on 16/1/13. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; CGFloat width = self.view.frame.size.width; CGFloat height = 100; CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer]; [self.view.layer addSublayer:replicatorLayer]; replicatorLayer.frame = CGRectMake(0, 0, width, height); replicatorLayer.position = self.view.center; replicatorLayer.borderWidth = 0.5f; replicatorLayer.instanceCount = width / 3; replicatorLayer.masksToBounds = YES; replicatorLayer.instanceTransform = CATransform3DMakeTranslation(-3.0, 0.0, 0.0); replicatorLayer.instanceDelay = 0.025f; CALayer *layer = [CALayer layer]; layer.frame = CGRectMake(width - 1, height, 2, 100); layer.backgroundColor = [UIColor redColor].CGColor; [replicatorLayer addSublayer:layer]; CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.y"]; animation.toValue = @(layer.position.y - 60.f); animation.duration = 0.5f; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; animation.autoreverses = true; animation.repeatCount = CGFLOAT_MAX; [layer addAnimation:animation forKey:nil]; } @end
https://github.com/YouXianMing/GCD-Program
// // ViewController.m // CAReplicatorLayer // // Created by YouXianMing on 16/1/13. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "ViewController.h" #import "GCD.h" @interface ViewController () @property (nonatomic, strong) GCDTimer *timer; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; CGFloat width = self.view.frame.size.width; CGFloat height = 100; CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer]; [self.view.layer addSublayer:replicatorLayer]; replicatorLayer.frame = CGRectMake(0, 0, width, height); replicatorLayer.position = self.view.center; replicatorLayer.borderWidth = 0.5f; replicatorLayer.instanceCount = width / 3; replicatorLayer.masksToBounds = YES; replicatorLayer.instanceTransform = CATransform3DMakeTranslation(-3.0, 0.0, 0.0); replicatorLayer.instanceDelay = 0.025f; CALayer *layer = [CALayer layer]; layer.frame = CGRectMake(width - 1, height, 2, 100); layer.backgroundColor = [UIColor redColor].CGColor; [replicatorLayer addSublayer:layer]; self.timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]]; [self.timer event:^{ CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.y"]; animation.toValue = @(layer.position.y - arc4random() % 100); animation.duration = 0.5f; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; animation.autoreverses = true; animation.repeatCount = CGFLOAT_MAX; [layer addAnimation:animation forKey:nil]; } timeIntervalWithSecs:1.f delaySecs:1.f]; [self.timer start]; } @end
// // ViewController.m // CAReplicatorLayer // // Created by YouXianMing on 16/1/13. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "ViewController.h" #import "Math.h" #import "GCD.h" @interface ViewController () @property (nonatomic, strong) GCDTimer *timer; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; CGFloat width = self.view.frame.size.width; CGFloat height = 100; CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer]; [self.view.layer addSublayer:replicatorLayer]; replicatorLayer.frame = CGRectMake(0, 0, width, height); replicatorLayer.position = self.view.center; replicatorLayer.borderWidth = 0.5f; replicatorLayer.instanceCount = width / 3; replicatorLayer.masksToBounds = YES; replicatorLayer.instanceTransform = CATransform3DMakeTranslation(-3.0, 0.0, 0.0); replicatorLayer.instanceDelay = 0.5f; CALayer *layer = [CALayer layer]; layer.frame = CGRectMake(width - 1, height, 2, 100); layer.backgroundColor = [UIColor redColor].CGColor; [replicatorLayer addSublayer:layer]; self.timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]]; [self.timer event:^{ CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.y"]; animation.toValue = @(layer.position.y - arc4random() % 100); animation.duration = 0.5f; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; animation.autoreverses = true; animation.repeatCount = CGFLOAT_MAX; [layer addAnimation:animation forKey:nil]; } timeIntervalWithSecs:1.f delaySecs:1.f]; [self.timer start]; } @end