使用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