渐变图层和插值曲线
2016-03-10 23:37:19
渐变图层通常与插值贝塞尔曲线混合使用来绘制各种变化曲线
#import "GradeColorView.h"
#import "DataGetY.h"
///定义对应的颜色
#define kSetAlColor(rd,ge,be,al) ([UIColor colorWithRed:rd<=1?rd:rd/255.0 green:ge<=1?ge:ge/255.0 blue:be<=1?be:be/255.0 alpha:al])
//获取颜色R G B
#define kGetColorRed(color) ([[[CIColor alloc]initWithColor:color] red])
#define kGetColorGreen(color) ([[[CIColor alloc]initWithColor:color] green])
#define kGetColorBlue(color) ([[[CIColor alloc]initWithColor:color] blue])
@interface GradeColorView ()
@property (nonatomic, strong)CAGradientLayer *gradientLayer;////渐变色层
@property (nonatomic, strong)NSArray *pointsArray;
@property (nonatomic, strong)UIView *targetPoint;
@end
@implementation GradeColorView
- (instancetype)initWithFrame:(CGRect)frame WithLineColor:(UIColor *)color
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.lineColor = color;
self.allPoints = [NSMutableArray array];
}
return self;
}
////传入数据 数组
- (void)updateUIWithPointArray:(NSArray *)pointsArray
{
self.pointsArray = pointsArray;
////创建BezierPath
UIBezierPath *path = [UIBezierPath bezierPath];
[self makeDownPointWithInsertNum:19 andPointsArray:self.pointsArray Withpath:path];
path.lineWidth = 0;
[path stroke];
///self.gradientLayer为渐变色层
CAShapeLayer *layer = [CAShapeLayer layer];////创建一个Layer层
layer.path = [path CGPath];
layer.lineCap = kCALineCapRound;
self.gradientLayer.mask = layer;/////layer的背景色选中区域
[self.layer addSublayer:self.gradientLayer];
[self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect
{
[super drawRect:rect];
UIBezierPath *path = [UIBezierPath bezierPath];
[self makeDownPointWithInsertNum:19 andPointsArray:self.pointsArray Withpath:path];
[path closePath];
[self.lineColor setStroke];
[path stroke];
}
2.对数据进行插值处理 处理方式如下:参数1:num 两点间的插值数,参数2:pointsArray 要处理的点数组 参数3 path 要处理的贝塞尔曲线
- (void)makeDownPointWithInsertNum:(NSInteger)num andPointsArray:(NSArray *)pointsArray Withpath:(UIBezierPath *)path
{
/*
插值法 使用说明 p1 和 p2 之间插值 要计算 p0 和 p3
其中 p0 是 p1 前面的一个点(如果p1已经是数组里第一个点了,那p0就是p1点左下方一点,计算如例)
p3 是p2 后面的一个点(如果p2已经是最后一个点了,那p3就是p2正右上方的点)
|
|
| .p2
|
|
| .p3
| .p1
|
|.p0
|
|____________________________________
*/
for (int i = 0; i < pointsArray.count-1; i ++) {
CGPoint p1 = CGPointFromString(pointsArray[i]);
CGPoint p0;
if (i == 0) {
p0 = CGPointMake(p1.x-2, p1.y-2);
[path moveToPoint:p1];
[self.allPoints addObject:NSStringFromCGPoint(p1)];/////第一个数据需要加里面,因为没有
}else{
[path addLineToPoint:p1];
p0 = CGPointFromString(pointsArray[i-1]);
}
CGPoint p2 = CGPointFromString(pointsArray[i + 1]);
CGPoint p3 ;
if (i == pointsArray.count - 2) {
p3 = CGPointMake(p1.x+2, p1.y+2);
}else{
p3 = CGPointFromString(pointsArray[i + 2]);
}
for (int i = 1; i <= num; i++) {
float t = i * (1.0f / num);
float tt = t * t;
float ttt = tt * t;
CGFloat pointx_x = (float) (0.5 * (2 * p1.x + (p2.x - p0.x) * t + (2 * p0.x - 5 * p1.x + 4 * p2.x - p3.x) * tt + (3 * p1.x - p0.x - 3 * p2.x + p3.x)
* ttt));
CGFloat pointx_y = (float) (0.5 * (2 * p1.y + (p2.y - p0.y) * t + (2 * p0.y - 5 * p1.y + 4 * p2.y - p3.y) * tt + (3 * p1.y - p0.y - 3 * p2.y + p3.y)
* ttt));
[path addLineToPoint:CGPointMake(pointx_x, pointx_y)];
[self.allPoints addObject:NSStringFromCGPoint(CGPointMake(pointx_x, pointx_y))];
}
}
}
3.下面的为属性gradientLayer的getter方法,
_gradientLayer.colors = @[
(__bridge id)kSetAlColor(R, G, B, Alpha).CGColor,(__bridge id)kSetAlColor(R, G, B, Alpha).CGColor,(__bridge id)kSetAlColor(R, G, B, Alpha).CGColor];///其中渐变层的颜色种类,alpha表示所占的百分比
#pragma mark -- getter/setter 专门负责添加渐变色
- (CAGradientLayer *)gradientLayer
{
if (!_gradientLayer) {
_gradientLayer = [CAGradientLayer layer];
_gradientLayer.frame = self.bounds;
_gradientLayer.colors = @[
(__bridge id)kSetAlColor(kGetColorRed(_lineColor), kGetColorGreen(_lineColor), kGetColorBlue(_lineColor), 0.8).CGColor,
(__bridge id)kSetAlColor(kGetColorRed(_lineColor), kGetColorGreen(_lineColor), kGetColorBlue(_lineColor), 0.1).CGColor];
_gradientLayer.startPoint = CGPointMake(0, 0);///表示开始的方位(左 ,上)
_gradientLayer.endPoint = CGPointMake(0, 1);////结束方位(右,下)
}
return _gradientLayer;
}
@end
4.最后是封装的曲线类的使用
- (void)viewDidLoad {
[super viewDidLoad];
GradeColorView *colorView = [[GradeColorView allo]initWithFrame:
CGRectMake(80, 120, 250, 250) WithLineColor:[UIColor orangeColor]];
[colorView updateUIWithPointArray:@[
NSStringFromCGPoint(CGPointMake(0,250)),
NSStringFromCGPoint(CGPointMake(20, 160)),
NSStringFromCGPoint(CGPointMake(40, 100)),
NSStringFromCGPoint(CGPointMake(60, 20)),
NSStringFromCGPoint(CGPointMake(80, 90)),
NSStringFromCGPoint(CGPointMake(100, 120)),
NSStringFromCGPoint(CGPointMake(120, 80)),
NSStringFromCGPoint(CGPointMake(140, 140)),
NSStringFromCGPoint(CGPointMake(160, 190)),
NSStringFromCGPoint(CGPointMake(250, 250))]];
[self.view addSubview:colorView];
}
下面是插值曲线的效果: