前言:
關于貝塞爾曲線與CAShapeLayer的學習
學習Demo演示:
貝塞爾曲線簡單了解
使用UIBezierPath類可以創(chuàng)建基于矢量的路徑垛叨,這個類在UIKit中坏瘩。此類是Core Graphics框架關于path的一個封裝介牙。使用此類可以定義簡單的形狀银受,如橢圓或者矩形圈膏,或者有多個直線和曲線段組成的形狀塔猾。
Bezier Path 基礎
UIBezierPath對象是CGPathRef數(shù)據(jù)類型的封裝。path如果是基于矢量形狀的稽坤,都用直線和曲線段去創(chuàng)建丈甸。我們使用直線段去創(chuàng)建矩形和多邊形,使用曲線段去創(chuàng)建荒蛲省(arc)睦擂,圓或者其他復雜的曲線形狀。
每一段都包括一個或者多個點杖玲,繪圖命令定義如何去詮釋這些點顿仇。每一個直線段或者曲線段的結束的地方是下一個的開始的地方。
每一個連接的直線或者曲線段的集合成為subpath摆马。一個UIBezierPath對象定義一個完整的路徑包括一個或者多個subpaths臼闻。
-
創(chuàng)建和使用一個path對象的過程是分開的。創(chuàng)建path是第一步囤采,包含一下步驟:
(1)創(chuàng)建一個Bezier path對象述呐。
(2)使用方法moveToPoint:去設置初始線段的起點。
(3)添加line或者curve去定義一個或者多個subpaths蕉毯。
(4)改變UIBezierPath對象跟繪圖相關的屬性乓搬。
例如思犁,我們可以設置stroked path的屬性lineWidth和lineJoinStyle。也可以設置filled path的屬性usesEvenOddFillRule进肯。
當創(chuàng)建path抒倚,我們應該管理path上面的點相對于原點(0,0)坷澡,這樣我們在隨后就可以很容易的移動path了托呕。為了繪制path對象,我們要用到stroke和fill方法频敛。這些方法在current graphic context下渲染path的line和curve段项郊。
CAShapeLayer
- 簡單介紹:
CAShapeLayer繼承自CALayer,因此斟赚,可使用CALayer的所有屬性着降。但是,CAShapeLayer需要和貝塞爾曲線配合使用才有意義拗军。
#CAShapeLayer和drawRect的比較
- 1.drawRect:屬于CoreGraphics框架任洞,占用CPU,性能消耗大
- 2.CAShapeLayer:屬于CoreAnimation框架发侵,通過GPU來渲染圖形交掏,節(jié)省性能。動畫渲染直接提交給手機GPU刃鳄,不消耗內存
溫馨提示:drawRect只是一個方法而已盅弛,是UIView的方法,重寫此方法可以完成我們的繪制圖形功能叔锐。
CAShapeLayer與UIBezierPath的關系
CAShapeLayer與UIBezierPath的關系:
- 1.CAShapeLayer中shape代表形狀的意思挪鹏,所以需要形狀才能生效
- 2.貝塞爾曲線可以創(chuàng)建基于矢量的路徑,而UIBezierPath類是對CGPathRef的封裝
- 3.貝塞爾曲線給CAShapeLayer提供路徑愉烙,CAShapeLayer在提供的路徑中進行渲染讨盒。路徑會閉環(huán),所以繪制出了Shape
- 4.用于CAShapeLayer的貝塞爾曲線作為path步责,其path是一個首尾相接的閉環(huán)的曲線返顺,即使該貝塞爾曲線不是一個閉環(huán)的曲線
代碼示例
CAShapeLayer與UIBezierPath畫圖
1.折線
- (IBAction)折線:(id)sender {
[self clearDisplayView];
// 創(chuàng)建一個路徑對象
UIBezierPath *linePath = [UIBezierPath bezierPath];
// 起點
[linePath moveToPoint:(CGPoint){20,20}];
// 其他點
[linePath addLineToPoint:(CGPoint){160,160}];
[linePath addLineToPoint:(CGPoint){180,50}];
>
// 設置路徑畫布
CAShapeLayer *lineLayer = [CAShapeLayer layer];
lineLayer.bounds = (CGRect){0,0,200,200};
lineLayer.position = _centerPosition;
lineLayer.lineWidth = 2.0;
lineLayer.strokeColor = [UIColor orangeColor].CGColor; // 邊線顏色
>
lineLayer.path = linePath.CGPath;
lineLayer.fillColor = nil; // 默認是black
// 添加到圖層上
[self.displayView.layer addSublayer:lineLayer];
}
2. 三角形
- (IBAction)三角形:(id)sender {
[self clearDisplayView];
>
// 創(chuàng)建一個路徑對象
UIBezierPath *polyonPath = [UIBezierPath bezierPath];
>
// 起點-->相對于所在視圖
[polyonPath moveToPoint:(CGPoint){20,40}];
// 其他點
[polyonPath addLineToPoint:(CGPoint){160,160}];
[polyonPath addLineToPoint:(CGPoint){140,50}];
[polyonPath closePath]; // 關閉路徑 添加一個結尾和起點相同的點
>
CAShapeLayer *polygonLayer = [CAShapeLayer layer];
>
polygonLayer.bounds = (CGRect){0,0,160,160};
polygonLayer.position = _centerPosition;
polygonLayer.lineWidth = 2;
polygonLayer.strokeColor = [UIColor redColor].CGColor; // 邊線的顏色
polygonLayer.path = polyonPath.CGPath;
polygonLayer.fillColor = nil;
>
[self.displayView.layer addSublayer:polygonLayer];
}
3. 多邊形
- (IBAction)多邊形:(id)sender {
[self clearDisplayView];
UIBezierPath *aPath = [UIBezierPath bezierPath];
>
// Set the starting point of the shape.
[aPath moveToPoint:CGPointMake(100, 0.0)];
// Draw the lines
[aPath addLineToPoint:CGPointMake(200.0,40.0)];
[aPath addLineToPoint:(CGPoint){160,140}];
[aPath addLineToPoint:(CGPoint){40,140}];
[aPath addLineToPoint:(CGPoint){0,40}];
[aPath closePath];
>
CAShapeLayer *layer = [CAShapeLayer layer];
layer.bounds = (CGRect){0,0,200,160};
>
layer.position = _centerPosition;
layer.lineWidth = 2.0;
layer.lineCap = kCALineCapRound; // 線條拐角
layer.lineJoin = kCALineCapRound; // 終點處理
layer.strokeColor = [UIColor greenColor].CGColor;
layer.path = aPath.CGPath;
layer.fillColor = nil; // 默認為blackColor
>
[self.displayView.layer addSublayer:layer];
>
}
4. 橢圓和圓
- (IBAction)橢圓:(id)sender {
[self clearDisplayView];
// 創(chuàng)建橢圓一個路徑
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:(CGRect){0,0,260,200}];
>
CAShapeLayer *pathLayer = [CAShapeLayer layer];
>
pathLayer.bounds = (CGRect){0,0,260,200};
pathLayer.position = _centerPosition;
pathLayer.lineWidth = 2.0;
pathLayer.strokeColor = [UIColor grayColor].CGColor;
pathLayer.path = path.CGPath;
pathLayer.fillColor = nil; // 默認為blackColor
[self.displayView.layer addSublayer:pathLayer];
}
圓
- (IBAction)圓:(id)sender {
[self clearDisplayView];
// 創(chuàng)建一個路徑
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:(CGRect){0,0,200,200}];
>
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.bounds = (CGRect){0,0,200,200};
pathLayer.position = _centerPosition;
>
pathLayer.lineWidth = 2.0;
pathLayer.strokeColor = [UIColor orangeColor].CGColor; // 邊緣顏色
pathLayer.path = path.CGPath;
// pathLayer.fillColor = nil;
// [self.displayView.layer addSublayer:pathLayer];
self.displayView.layer.mask = pathLayer; // layer 的 mask屬性,添加蒙版
}
5. 實心矩形
- (IBAction)實心矩形:(id)sender {
[self clearDisplayView];
>
CAShapeLayer *layer = [CAShapeLayer layer];
layer.frame = (CGRect){0,0,100,100};
layer.position = _centerPosition;
layer.backgroundColor = [UIColor lightGrayColor].CGColor;
[self.displayView.layer addSublayer:layer];
}
6. 空心矩形
- (IBAction)空心矩形:(id)sender {
[self clearDisplayView];
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(130, 10, 100, 80)];
>
CAShapeLayer *layer = [CAShapeLayer layer];
//填充顏色
layer.fillColor = [UIColor clearColor].CGColor;
//邊框顏色
layer.strokeColor = [UIColor blackColor].CGColor;
layer.path = path.CGPath;
[self.displayView.layer addSublayer:layer];
}
7. 畫圓角矩形
- (IBAction)圓角矩形:(id)sender {
[self clearDisplayView];
// 創(chuàng)建一個路徑
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:(CGRect){0,0,200,200} cornerRadius:50];
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.bounds = (CGRect){0,0,200,200};
pathLayer.position = _centerPosition;
pathLayer.lineWidth = 2.0;
pathLayer.strokeColor = [UIColor redColor].CGColor;
// pathLayer.fillColor = [UIColor lightGrayColor].CGColor; // 默認為blackColor
// [polygonView.layer addSublayer:polygonLayer];
pathLayer.path = path.CGPath;
self.displayView.layer.mask = pathLayer; // layer 的 mask屬性勺择,添加蒙版
}
8. 畫單角的圓角矩形的UIBezierPath相關方法
- (IBAction)單圓角矩形:(id)sender {
[self clearDisplayView];
// 創(chuàng)建路徑
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:(CGRect){0,0,200,200} byRoundingCorners:UIRectCornerTopLeft cornerRadii:(CGSize){100,0}];
CAShapeLayer *pathLayer = [CAShapeLayer layer];
>
pathLayer.bounds = (CGRect){0,0,200,200};
pathLayer.position = _centerPosition;
pathLayer.lineWidth = 2.0;
pathLayer.strokeColor = [UIColor grayColor].CGColor;
pathLayer.path = path.CGPath;
pathLayer.fillColor = nil;
[self.displayView.layer addSublayer:pathLayer];
// self.displayView.layer.mask = pathLayer;
}
9. 畫圓弧
- (IBAction)圓弧:(id)sender {
[self clearDisplayView];
// 繪制路徑對象
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:_centerPosition radius:50 startAngle:0 endAngle:M_PI_2 clockwise:YES];
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.lineWidth = 2.0;
pathLayer.strokeColor = [UIColor redColor].CGColor;
pathLayer.fillColor = nil;
pathLayer.path = path.CGPath;
>
[self.displayView.layer addSublayer:pathLayer];
}
10.折線和弧線構成的曲線**
#pragma mark - 折線和弧線構成的曲線
- (IBAction)折線弧線曲:(id)sender {
[self clearDisplayView];
// 創(chuàng)建路徑
UIBezierPath *path = [UIBezierPath bezierPath];
// 折線
[path moveToPoint:(CGPoint){100,100}];
[path addLineToPoint:_centerPosition];
// 添加一條弧線
[path addArcWithCenter:_centerPosition radius:50 startAngle:0 endAngle:M_PI clockwise:YES];
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.lineWidth = 2.0;
pathLayer.strokeColor = [UIColor redColor].CGColor;
pathLayer.fillColor = nil;
pathLayer.path = path.CGPath;
[self.displayView.layer addSublayer:pathLayer];
}
11.二次貝塞爾曲線
- (IBAction)二次貝塞爾曲線:(id)sender {
[self clearDisplayView];
// 綠色二次貝塞爾曲線
UIBezierPath *path1 = [UIBezierPath bezierPath];
[path1 moveToPoint:(CGPoint){0,100}];
[path1 addQuadCurveToPoint:(CGPoint){200,50} controlPoint:(CGPoint){100,200}];
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.position = (CGPoint){100,100};
pathLayer.lineWidth = 2.0;
pathLayer.strokeColor = [UIColor greenColor].CGColor;
pathLayer.fillColor = nil;
pathLayer.path = path1.CGPath;
[self.displayView.layer addSublayer:pathLayer];
>
>
// 紅色二次貝塞爾曲線
UIBezierPath *path2 = [UIBezierPath bezierPath];
[path2 moveToPoint:CGPointMake(0, 100)];
CGPoint end2Point = CGPointMake(100, 50);
[path2 addQuadCurveToPoint:end2Point controlPoint:CGPointMake(100, 200)]; // 二次貝塞爾曲線
CAShapeLayer *path2Layer = [CAShapeLayer layer];
path2Layer.position = (CGPoint){100,100};
path2Layer.lineWidth = 2;
path2Layer.strokeColor = [UIColor redColor].CGColor;
path2Layer.fillColor = nil; // 默認為blackColor
path2Layer.path = path2.CGPath;
[_displayView.layer addSublayer:path2Layer];
}
起點終點相同创南,控制點不同
總結:控制點與起點和終點所在直線偏移距離越大,曲線弧度越大省核。
- (IBAction)二次貝塞爾曲線2:(id)sender {
[self clearDisplayView];
CGPoint startPoint = CGPointMake(0, 100);
CGPoint endPoint = CGPointMake(200, 50);
// 綠色二次貝塞爾曲線
UIBezierPath *path1 = [UIBezierPath bezierPath];
[path1 moveToPoint:startPoint];
[path1 addQuadCurveToPoint:endPoint controlPoint:CGPointMake(100, 200)]; // 二次貝塞爾曲線
CAShapeLayer *path1Layer = [CAShapeLayer layer];
path1Layer.position = (CGPoint){100,100};
path1Layer.lineWidth = 2;
path1Layer.strokeColor = [UIColor greenColor].CGColor;
path1Layer.fillColor = nil; // 默認為blackColor
path1Layer.path = path1.CGPath;
[_displayView.layer addSublayer:path1Layer];
// 紅色二次貝塞爾曲線
UIBezierPath *path2 = [UIBezierPath bezierPath];
[path2 moveToPoint:startPoint];
[path2 addQuadCurveToPoint:endPoint controlPoint:CGPointMake(100, 150)]; // 二次貝塞爾曲線
CAShapeLayer *path2Layer = [CAShapeLayer layer];
path2Layer.position = (CGPoint){100,100};
path2Layer.lineWidth = 2;
path2Layer.strokeColor = [UIColor redColor].CGColor;
path2Layer.fillColor = nil; // 默認為blackColor
path2Layer.path = path2.CGPath;
[_displayView.layer addSublayer:path2Layer];
}
12. 三次貝塞爾曲線
- (IBAction)三次貝塞爾曲線:(id)sender {
[self clearDisplayView];
CGPoint startPoint = CGPointMake(0, 100);
CGPoint endPoint = CGPointMake(200, 100);
// 綠色二次貝塞爾曲線
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:startPoint];
[path addCurveToPoint:endPoint controlPoint1:CGPointMake(50, 75) controlPoint2:CGPointMake(150, 125)]; // 二次貝塞爾曲線
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.position = (CGPoint){100,100};
pathLayer.lineWidth = 2;
pathLayer.strokeColor = [UIColor redColor].CGColor;
pathLayer.fillColor = nil; // 默認為blackColor
pathLayer.path = path.CGPath;
[_displayView.layer addSublayer:pathLayer];
}
13. 單控制點曲線
- (IBAction)單控制點曲線:(id)sender {
[self clearDisplayView];
//貝塞爾曲線的畫法是由起點稿辙、終點、控制點三個參數(shù)來畫的气忠,為了解釋清楚這個點邻储,我寫了幾行代碼來解釋它
CGPoint startPoint = CGPointMake(50, 100);
CGPoint endPoint = CGPointMake(300, 100);
CGPoint controlPoint = CGPointMake(175, 10);
// 紅點
CALayer *layer1 = [CALayer layer];
layer1.frame = CGRectMake(startPoint.x, startPoint.y, 5, 5);
layer1.backgroundColor = [UIColor redColor].CGColor;
CALayer *layer2 = [CALayer layer];
layer2.frame = CGRectMake(endPoint.x, endPoint.y, 5, 5);
layer2.backgroundColor = [UIColor redColor].CGColor;
CALayer *layer3 = [CALayer layer];
layer3.frame = CGRectMake(controlPoint.x, controlPoint.y, 5, 5);
layer3.backgroundColor = [UIColor redColor].CGColor;
// 畫線
UIBezierPath *path = [UIBezierPath bezierPath];
CAShapeLayer *layer = [CAShapeLayer layer];
[path moveToPoint:startPoint];
[path addQuadCurveToPoint:endPoint controlPoint:controlPoint];
layer.path = path.CGPath;
layer.fillColor = [UIColor clearColor].CGColor;
layer.strokeColor = [UIColor blackColor].CGColor;
[self.displayView.layer addSublayer:layer];
[self.displayView.layer addSublayer:layer1];
[self.displayView.layer addSublayer:layer2];
[self.displayView.layer addSublayer:layer3];
}
14.雙控制點曲線
- (IBAction)雙控制點曲線:(id)sender {
[self clearDisplayView];
//貝塞爾曲線的畫法是由起點赋咽、終點、控制點三個參數(shù)來畫的吨娜,為了解釋清楚這個點脓匿,我寫了幾行代碼來解釋它
CGPoint startPoint = CGPointMake(50, 70);
CGPoint endPoint = CGPointMake(300, 70);
CGPoint controlPoint1 = CGPointMake(112.5, 10);
CGPoint controlPoint2 = CGPointMake(237.5, 130);
// 紅點
CALayer *layer1 = [CALayer layer];
layer1.frame = CGRectMake(startPoint.x, startPoint.y, 5, 5);
layer1.backgroundColor = [UIColor redColor].CGColor;
>
CALayer *layer2 = [CALayer layer];
layer2.frame = CGRectMake(endPoint.x, endPoint.y, 5, 5);
layer2.backgroundColor = [UIColor redColor].CGColor;
>
CALayer *layer3 = [CALayer layer];
layer3.frame = CGRectMake(controlPoint1.x, controlPoint1.y, 5, 5);
layer3.backgroundColor = [UIColor redColor].CGColor;
>
CALayer *layer4 = [CALayer layer];
layer4.frame = CGRectMake(controlPoint2.x, controlPoint2.y, 5, 5);
layer4.backgroundColor = [UIColor redColor].CGColor;
// 畫線
UIBezierPath *path = [UIBezierPath bezierPath];
CAShapeLayer *layer = [CAShapeLayer layer];
>
[path moveToPoint:startPoint];
[path addCurveToPoint:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2];
>
layer.path = path.CGPath;
layer.fillColor = [UIColor clearColor].CGColor;
layer.strokeColor = [UIColor blackColor].CGColor;
>
[self.displayView.layer addSublayer:layer];
[self.displayView.layer addSublayer:layer1];
[self.displayView.layer addSublayer:layer2];
[self.displayView.layer addSublayer:layer3];
[self.displayView.layer addSublayer:layer4];
}
15.曲面
- (IBAction)曲面:(id)sender {
[self clearDisplayView];
CGSize size = self.displayView.frame.size;
CGFloat startHeight = size.height * 0.2;
CGFloat endHeight = size.height * 0.4;
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, startHeight)];
[path addLineToPoint:CGPointMake(0, endHeight)];
[path addLineToPoint:CGPointMake(size.width, endHeight)];
[path addLineToPoint:CGPointMake(size.width, startHeight)];
[path addQuadCurveToPoint:CGPointMake(0, startHeight) controlPoint:CGPointMake(size.width/2, 0)];
>
CAShapeLayer *layer = [CAShapeLayer layer];
layer.strokeColor = [UIColor purpleColor].CGColor;
layer.fillColor = [UIColor whiteColor].CGColor;
layer.path = path.CGPath;
[self.displayView.layer addSublayer:layer];
}
16.綜合練習- 繪哆啦A夢
#pragma mark - 繪哆啦A夢
- (IBAction)btnDuoLaAMeng_Click:(id)sender
{
[self clearDisplayView];
>
CGFloat arcCenterX = self.view.frame.size.width/2;
CGFloat arcCenterY = 80;
CGFloat delay = LanPangZiDuration;
>
//頭
CAShapeLayer *headLayer = [CAShapeLayer layer];
UIBezierPath *headPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(self.view.frame.size.width/2-80, 0, 160, 160) cornerRadius:80];
[self setLayer:headLayer path:headPath delay:delay*0];
>
//臉
CAShapeLayer *faceLayer = [CAShapeLayer layer];
UIBezierPath *facePath = [UIBezierPath bezierPath];
[facePath moveToPoint:CGPointMake(arcCenterX-80*sqrt(2.0)/2, arcCenterY+80*sqrt(2.0)/2)];
[facePath addCurveToPoint:CGPointMake(arcCenterX-30, arcCenterY-20) controlPoint1:CGPointMake(arcCenterX-80, arcCenterY+25) controlPoint2:CGPointMake(arcCenterX-80, arcCenterY-20)];
[facePath addLineToPoint:CGPointMake(arcCenterX+30, arcCenterY-20)];
[facePath addCurveToPoint:CGPointMake(arcCenterX+80*sqrt(2.0)/2, arcCenterY+80*sqrt(2.0)/2) controlPoint1:CGPointMake(arcCenterX+80, arcCenterY-20) controlPoint2:CGPointMake(arcCenterX+80, arcCenterY+25)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX-80*sqrt(2.0)/2, arcCenterY+80*sqrt(2.0)/2) controlPoint:CGPointMake(arcCenterX, arcCenterY+105)];
[self setLayer:faceLayer path:facePath delay:delay*1];
//左眼
CAShapeLayer *leftEyeLayer = [CAShapeLayer layer];
UIBezierPath *leftEyePath = [UIBezierPath bezierPath];
[leftEyePath moveToPoint:CGPointMake(arcCenterX-30, arcCenterY-25)];
[leftEyePath addQuadCurveToPoint:CGPointMake(arcCenterX-15, arcCenterY-45) controlPoint:CGPointMake(arcCenterX-30, arcCenterY-45)];
[leftEyePath addQuadCurveToPoint:CGPointMake(arcCenterX, arcCenterY-25) controlPoint:CGPointMake(arcCenterX, arcCenterY-45)];
[leftEyePath addQuadCurveToPoint:CGPointMake(arcCenterX-15, arcCenterY-5) controlPoint:CGPointMake(arcCenterX, arcCenterY-5)];
[leftEyePath addQuadCurveToPoint:CGPointMake(arcCenterX-30, arcCenterY-25) controlPoint:CGPointMake(arcCenterX-30, arcCenterY-5)];
[self setLayer:leftEyeLayer path:leftEyePath delay:delay*2];
//左眼珠
CAShapeLayer *leftEyeBallLayer = [CAShapeLayer layer];
UIBezierPath *leftEyeBallPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(arcCenterX-5, arcCenterY-30) radius:2.5 startAngle:0 endAngle:2*M_PI clockwise:YES];
[self setLayer:leftEyeBallLayer path:leftEyeBallPath delay:delay*3];
>
//右眼
CAShapeLayer *rightEyeLayer = [CAShapeLayer layer];
UIBezierPath *rightEyePath = [UIBezierPath bezierPath];
[rightEyePath moveToPoint:CGPointMake(arcCenterX, arcCenterY-25)];
[rightEyePath addQuadCurveToPoint:CGPointMake(arcCenterX+15, arcCenterY-45) controlPoint:CGPointMake(arcCenterX, arcCenterY-45)];
[rightEyePath addQuadCurveToPoint:CGPointMake(arcCenterX+30, arcCenterY-25) controlPoint:CGPointMake(arcCenterX+30, arcCenterY-45)];
[rightEyePath addQuadCurveToPoint:CGPointMake(arcCenterX+15, arcCenterY-5) controlPoint:CGPointMake(arcCenterX+30, arcCenterY-5)];
[rightEyePath addQuadCurveToPoint:CGPointMake(arcCenterX, arcCenterY-25) controlPoint:CGPointMake(arcCenterX, arcCenterY-5)];
[self setLayer:rightEyeLayer path:rightEyePath delay:delay*4];
//右眼珠
CAShapeLayer *rightEyeBallLayer = [CAShapeLayer layer];
UIBezierPath *rightEyeBallPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(arcCenterX+5, arcCenterY-30) radius:2.5 startAngle:0 endAngle:2*M_PI clockwise:YES];
[self setLayer:rightEyeBallLayer path:rightEyeBallPath delay:delay*5];
>
//鼻子
CAShapeLayer *noseLayer = [CAShapeLayer layer];
UIBezierPath *nosePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(arcCenterX, arcCenterY) radius:10 startAngle:0 endAngle:2*M_PI clockwise:YES];
[self setLayer:noseLayer path:nosePath delay:delay*6];
//鼻子光暈
CAShapeLayer *noseHaloLayer = [CAShapeLayer layer];
UIBezierPath *noseHaloPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(arcCenterX-4, arcCenterY-5) radius:2.5 startAngle:0 endAngle:2*M_PI clockwise:YES];
[self setLayer:noseHaloLayer path:noseHaloPath delay:delay*7];
>
//嘴巴
CAShapeLayer *mouthLayer = [CAShapeLayer layer];
UIBezierPath *mouthPath = [UIBezierPath bezierPath];
[mouthPath moveToPoint:CGPointMake(arcCenterX-60, arcCenterY+25)];
[mouthPath addQuadCurveToPoint:CGPointMake(arcCenterX+60, arcCenterY+25) controlPoint:CGPointMake(arcCenterX, arcCenterY+90)];
[self setLayer:mouthLayer path:mouthPath delay:delay*8];
CAShapeLayer *mouthLayer1 = [CAShapeLayer layer];
UIBezierPath *mouthPath1 = [UIBezierPath bezierPath];
[mouthPath1 moveToPoint:CGPointMake(arcCenterX, arcCenterY+10)];
[mouthPath1 addLineToPoint:CGPointMake(arcCenterX, arcCenterY+55)];
[self setLayer:mouthLayer1 path:mouthPath1 delay:delay*9];
//胡子
[self addBeardFromPoint:CGPointMake(arcCenterX-58, arcCenterY-5) toPoint:CGPointMake(arcCenterX-15, arcCenterY+10) delay:delay*10];
[self addBeardFromPoint:CGPointMake(arcCenterX-68, arcCenterY+15) toPoint:CGPointMake(arcCenterX-15, arcCenterY+20) delay:delay*11];
[self addBeardFromPoint:CGPointMake(arcCenterX-61, arcCenterY+45) toPoint:CGPointMake(arcCenterX-15, arcCenterY+30) delay:delay*12];
[self addBeardFromPoint:CGPointMake(arcCenterX+58, arcCenterY-5) toPoint:CGPointMake(arcCenterX+15, arcCenterY+10) delay:delay*13];
[self addBeardFromPoint:CGPointMake(arcCenterX+68, arcCenterY+15) toPoint:CGPointMake(arcCenterX+15, arcCenterY+20) delay:delay*14];
[self addBeardFromPoint:CGPointMake(arcCenterX+61, arcCenterY+45) toPoint:CGPointMake(arcCenterX+15, arcCenterY+30) delay:delay*15];
//左手
CAShapeLayer *leftHandLayer = [CAShapeLayer layer];
UIBezierPath *leftHandPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(arcCenterX-95, arcCenterY+110) radius:20 startAngle:0 endAngle:2*M_PI clockwise:YES];
[self setLayer:leftHandLayer path:leftHandPath delay:delay*16];
//左胳膊
CGFloat distanceXToArcCenter = 80*cos(M_PI_2*4/9);
CGFloat distanceYToArcCenter = 80*sin(M_PI_2*4/9);
CAShapeLayer *leftArmLayer = [CAShapeLayer layer];
UIBezierPath *leftArmPath = [UIBezierPath bezierPath];
[leftArmPath moveToPoint:CGPointMake(arcCenterX-distanceXToArcCenter, arcCenterY+distanceYToArcCenter)];
[leftArmPath addLineToPoint:CGPointMake(arcCenterX-95, arcCenterY+90)];
[leftArmPath addQuadCurveToPoint:CGPointMake(arcCenterX-75, arcCenterY+110) controlPoint:CGPointMake(arcCenterX-92, arcCenterY+107)];
[leftArmPath addLineToPoint:CGPointMake(arcCenterX-distanceXToArcCenter+1.5, arcCenterY+95)];
[self setLayer:leftArmLayer path:leftArmPath delay:delay*17];
//圍巾
CAShapeLayer *mufflerLayer = [CAShapeLayer layer];
UIBezierPath *mufflerPath = [UIBezierPath bezierPath];
[mufflerPath moveToPoint:CGPointMake(arcCenterX-distanceXToArcCenter, arcCenterY+distanceYToArcCenter)];
[mufflerPath addQuadCurveToPoint:CGPointMake(arcCenterX+distanceXToArcCenter, arcCenterY+distanceYToArcCenter) controlPoint:CGPointMake(arcCenterX, arcCenterY+109)];
[mufflerPath addLineToPoint:CGPointMake(arcCenterX+distanceXToArcCenter+2, arcCenterY+distanceYToArcCenter+7)];
[mufflerPath addQuadCurveToPoint:CGPointMake(arcCenterX-distanceXToArcCenter-4, arcCenterY+distanceYToArcCenter+5) controlPoint:CGPointMake(arcCenterX, arcCenterY+115)];
[mufflerPath addLineToPoint:CGPointMake(arcCenterX-distanceXToArcCenter, arcCenterY+distanceYToArcCenter)];
[self setLayer:mufflerLayer path:mufflerPath delay:delay*18];
//身體
CAShapeLayer *bodyLayer = [CAShapeLayer layer];
UIBezierPath *bodyPath = [UIBezierPath bezierPath];
[bodyPath moveToPoint:CGPointMake(arcCenterX-distanceXToArcCenter, arcCenterY+distanceYToArcCenter+7)];
[bodyPath addQuadCurveToPoint:CGPointMake(arcCenterX-distanceXToArcCenter+5, arcCenterY+150) controlPoint:CGPointMake(arcCenterX-distanceXToArcCenter+2, arcCenterY+140)];
[bodyPath addQuadCurveToPoint:CGPointMake(arcCenterX-distanceXToArcCenter+3, arcCenterY+170) controlPoint:CGPointMake(arcCenterX-distanceXToArcCenter, arcCenterY+160)];
[bodyPath addQuadCurveToPoint:CGPointMake(arcCenterX-8, arcCenterY+170) controlPoint:CGPointMake(arcCenterX-(distanceXToArcCenter+5)/2, arcCenterY+175)];
[bodyPath addQuadCurveToPoint:CGPointMake(arcCenterX+8, arcCenterY+170) controlPoint:CGPointMake(arcCenterX, arcCenterY+155)];
[bodyPath addQuadCurveToPoint:CGPointMake(arcCenterX+distanceXToArcCenter-3, arcCenterY+170) controlPoint:CGPointMake(arcCenterX+(distanceXToArcCenter+5)/2, arcCenterY+175)];
[bodyPath addQuadCurveToPoint:CGPointMake(arcCenterX+distanceXToArcCenter-5, arcCenterY+150) controlPoint:CGPointMake(arcCenterX+distanceXToArcCenter-2, arcCenterY+160)];
[bodyPath addQuadCurveToPoint:CGPointMake(arcCenterX+distanceXToArcCenter, arcCenterY+distanceYToArcCenter+8) controlPoint:CGPointMake(arcCenterX+distanceXToArcCenter-2, arcCenterY+140)];
[bodyPath addQuadCurveToPoint:CGPointMake(arcCenterX-distanceXToArcCenter, arcCenterY+distanceYToArcCenter+7) controlPoint:CGPointMake(arcCenterX, arcCenterY+115)];
[self setLayer:bodyLayer path:bodyPath delay:delay*19];
//左腳
CAShapeLayer *leftFootLayer = [CAShapeLayer layer];
UIBezierPath *leftFootPath = [UIBezierPath bezierPath];
[leftFootPath moveToPoint:CGPointMake(arcCenterX-distanceXToArcCenter+3, arcCenterY+170)];
[leftFootPath addQuadCurveToPoint:CGPointMake(arcCenterX-distanceXToArcCenter+3, arcCenterY+195) controlPoint:CGPointMake(arcCenterX-distanceXToArcCenter-20, arcCenterY+185)];
[leftFootPath addQuadCurveToPoint:CGPointMake(arcCenterX-13, arcCenterY+195) controlPoint:CGPointMake(arcCenterX-(distanceXToArcCenter+10)/2, arcCenterY+200)];
[leftFootPath addQuadCurveToPoint:CGPointMake(arcCenterX-10, arcCenterY+170) controlPoint:CGPointMake(arcCenterX+8, arcCenterY+187)];
[self setLayer:leftFootLayer path:leftFootPath delay:delay*20];
//右腳
CAShapeLayer *rightFootLayer = [CAShapeLayer layer];
UIBezierPath *rightFootPath = [UIBezierPath bezierPath];
[rightFootPath moveToPoint:CGPointMake(arcCenterX+10, arcCenterY+170)];
[rightFootPath addQuadCurveToPoint:CGPointMake(arcCenterX+15, arcCenterY+195) controlPoint:CGPointMake(arcCenterX-12, arcCenterY+185)];
[rightFootPath addQuadCurveToPoint:CGPointMake(arcCenterX+distanceXToArcCenter-5, arcCenterY+195) controlPoint:CGPointMake(arcCenterX+(distanceXToArcCenter+20)/2, arcCenterY+200)];
[rightFootPath addQuadCurveToPoint:CGPointMake(arcCenterX+distanceXToArcCenter-3, arcCenterY+170) controlPoint:CGPointMake(arcCenterX+distanceXToArcCenter+18, arcCenterY+185)];
[self setLayer:rightFootLayer path:rightFootPath delay:delay*21];
//肚子
CAShapeLayer *bellyLayer = [CAShapeLayer layer];
UIBezierPath *bellyPath = [UIBezierPath bezierPath];
[bellyPath moveToPoint:CGPointMake(arcCenterX-30, arcCenterY+80)];
[bellyPath addCurveToPoint:CGPointMake(arcCenterX-30, arcCenterY+150) controlPoint1:CGPointMake(arcCenterX-65, arcCenterY+95) controlPoint2:CGPointMake(arcCenterX-60, arcCenterY+140)];
[bellyPath addQuadCurveToPoint:CGPointMake(arcCenterX+30, arcCenterY+150) controlPoint:CGPointMake(arcCenterX, arcCenterY+160)];
[bellyPath addCurveToPoint:CGPointMake(arcCenterX+30, arcCenterY+80) controlPoint1:CGPointMake(arcCenterX+60, arcCenterY+140) controlPoint2:CGPointMake(arcCenterX+65, arcCenterY+95)];
[bellyPath addQuadCurveToPoint:CGPointMake(arcCenterX-30, arcCenterY+80) controlPoint:CGPointMake(arcCenterX, arcCenterY+92)];
[self setLayer:bellyLayer path:bellyPath delay:delay*22];
//鈴鐺
CAShapeLayer *bellLayer = [CAShapeLayer layer];
UIBezierPath *bellPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(arcCenterX, arcCenterY+97) radius:15 startAngle:0 endAngle:2*M_PI clockwise:YES];
[self setLayer:bellLayer path:bellPath delay:delay*23];
//鈴鐺上的線
CAShapeLayer *bellLineLayer = [CAShapeLayer layer];
UIBezierPath *BellLinePath = [UIBezierPath bezierPath];
[BellLinePath moveToPoint:CGPointMake(arcCenterX-(sqrt(pow(15.0, 2)-pow(5.0, 2))), arcCenterY+92)];
[BellLinePath addLineToPoint:CGPointMake(arcCenterX+(sqrt(pow(15.0, 2)-pow(5.0, 2))), arcCenterY+92)];
[BellLinePath moveToPoint:CGPointMake(arcCenterX+(sqrt(pow(15.0, 2)-pow(2.0, 2))), arcCenterY+95)];
[BellLinePath addLineToPoint:CGPointMake(arcCenterX-(sqrt(pow(15.0, 2)-pow(2.0, 2))), arcCenterY+95)];
[self setLayer:bellLineLayer path:BellLinePath delay:delay*24];
//鈴鐺上的小圓點
CAShapeLayer *bellCirLayer = [CAShapeLayer layer];
UIBezierPath *bellCirPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(arcCenterX, arcCenterY+102) radius:2.5 startAngle:0 endAngle:2*M_PI clockwise:YES];
[bellCirPath moveToPoint:CGPointMake(arcCenterX, arcCenterY+104.5)];
[bellCirPath addLineToPoint:CGPointMake(arcCenterX, arcCenterY+112)];
[self setLayer:bellCirLayer path:bellCirPath delay:delay*25];
//口袋
CAShapeLayer *bagLayer = [CAShapeLayer layer];
UIBezierPath *bagPath = [UIBezierPath bezierPath];
[bagPath moveToPoint:CGPointMake(arcCenterX-40, arcCenterY+112)];
[bagPath addQuadCurveToPoint:CGPointMake(arcCenterX+40, arcCenterY+112) controlPoint:CGPointMake(arcCenterX, arcCenterY+120)];
[bagPath addCurveToPoint:CGPointMake(arcCenterX-40, arcCenterY+112) controlPoint1:CGPointMake(arcCenterX+28, arcCenterY+160) controlPoint2:CGPointMake(arcCenterX-28, arcCenterY+160)];
[self setLayer:bagLayer path:bagPath delay:delay*26];
//右手
CAShapeLayer *rightHandLayer = [CAShapeLayer layer];
UIBezierPath *rightHandPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(arcCenterX+85*cos(27/180.0*M_PI), arcCenterY-85*sin(27/180.0*M_PI)) radius:20 startAngle:0 endAngle:2*M_PI clockwise:YES];
[self setLayer:rightHandLayer path:rightHandPath delay:delay*27];
//右胳膊
CAShapeLayer *rightArmLayer = [CAShapeLayer layer];
UIBezierPath *rightArmPath = [UIBezierPath bezierPath];
[rightArmPath moveToPoint:CGPointMake(arcCenterX+80*cos(13/180.0*M_PI), arcCenterY-80*sin(13/180.0*M_PI))];
[rightArmPath addQuadCurveToPoint:CGPointMake(arcCenterX+distanceXToArcCenter, arcCenterY+distanceYToArcCenter) controlPoint:CGPointMake(arcCenterX+80*cos(13/180.0*M_PI)+9, arcCenterY+20)];
[rightArmPath addLineToPoint:CGPointMake(arcCenterX+distanceXToArcCenter, arcCenterY+distanceYToArcCenter+25)];
[rightArmPath addQuadCurveToPoint:CGPointMake(arcCenterX+93*cos(15/180.0*M_PI), arcCenterY-93*sin(15/180.0*M_PI)) controlPoint:CGPointMake(arcCenterX+90*cos(13/180.0*M_PI)+15, arcCenterY+25)];
[rightArmPath addQuadCurveToPoint:CGPointMake(arcCenterX+80*cos(13/180.0*M_PI), arcCenterY-80*sin(13/180.0*M_PI)) controlPoint:CGPointMake(arcCenterX+80*cos(13/180.0*M_PI)+5, arcCenterY-93*sin(15/180.0*M_PI)+5)];
[self setLayer:rightArmLayer path:rightArmPath delay:delay*28];
>
//上色
[self setLayerColor:faceLayer color:[UIColor whiteColor] delay:delay*16];
[self setLayerColor:leftEyeLayer color:[UIColor whiteColor] delay:delay*29];
[self setLayerColor:rightEyeLayer color:[UIColor whiteColor] delay:delay*29];
[self setLayerColor:leftEyeBallLayer color:[UIColor blackColor] delay:delay*29];
[self setLayerColor:rightEyeBallLayer color:[UIColor blackColor] delay:delay*29];
[self setLayerColor:noseLayer color:[UIColor redColor] delay:delay*29];
[self setLayerColor:noseHaloLayer color:[UIColor whiteColor] delay:delay*29];
[self setLayerColor:headLayer color:[UIColor colorWithRed:21/255.0 green:159/255.0 blue:237/255.0 alpha:1] delay:delay*29];
[self setLayerColor:leftArmLayer color:[UIColor colorWithRed:21/255.0 green:159/255.0 blue:237/255.0 alpha:1] delay:delay*29];
[self setLayerColor:leftHandLayer color:[UIColor whiteColor] delay:delay*29];
[self setLayerColor:mufflerLayer color:[UIColor redColor] delay:delay*29];
[self setLayerColor:bellyLayer color:[UIColor whiteColor] delay:delay*29];
[self setLayerColor:bellLayer color:[UIColor yellowColor] delay:delay*29];
[self setLayerColor:bodyLayer color:[UIColor colorWithRed:21/255.0 green:159/255.0 blue:237/255.0 alpha:1] delay:delay*29];
[self setLayerColor:rightHandLayer color:[UIColor whiteColor] delay:delay*29];
[self setLayerColor:rightArmLayer color:[UIColor colorWithRed:21/255.0 green:159/255.0 blue:237/255.0 alpha:1] delay:delay*29];
[self performSelector:@selector(showHello) withObject:nil afterDelay:delay*29];
}
>
- (void)addBeardFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint delay:(CFTimeInterval)delay
{
CAShapeLayer *beardLayer1 = [CAShapeLayer layer];
UIBezierPath *beardPath1 = [UIBezierPath bezierPath];
[beardPath1 moveToPoint:fromPoint];
[beardPath1 addLineToPoint:toPoint];
[self setLayer:beardLayer1 path:beardPath1 delay:delay];
}
- (void)setLayerColor:(CAShapeLayer *)layer color:(UIColor *)color delay:(CFTimeInterval)delay
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
layer.fillColor = color.CGColor;
});
}
- (void)setLayer:(CAShapeLayer *)layer path:(UIBezierPath *)path delay:(CFTimeInterval)delay
{
layer.path = path.CGPath;
layer.fillColor = [UIColor clearColor].CGColor;
layer.strokeColor = [UIColor lightGrayColor].CGColor;
__weak typeof(self) weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf.displayView.layer addSublayer:layer];
[weakSelf addAnimation:layer duration:LanPangZiDuration];
});
}
- (void)showHello
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2+90, 0, 70, 30)];
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor colorWithRed:21/255.0 green:159/255.0 blue:237/255.0 alpha:1];
label.text = @"Hello";
label.font = [UIFont fontWithName:@"Chalkduster" size:20];
[self.displayView addSubview:label];
>
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.fromValue = @(0);
animation.toValue = @(1);
animation.duration = 0.5f;
[label.layer addAnimation:animation forKey:nil];
}
參考:
1. iOS CAShapeLayer & UIBezierPath畫線、畫圖
2. iOS開發(fā) 貝塞爾曲線UIBezierPath
3. iOS_貝塞爾曲線初級篇
4. iOS CAShapeLayer精講
希望: 能遇伯樂宦赠,謀求一份工作陪毡。2016 應屆生