博客原地址:http://blog.csdn.net/hello_hwc?viewmode=list
让我们继续跟着大神的脚步前进吧。这一次 我们学习一些Quartz 2D 最基本的一些用法。
前言:一个路径可以包含由一个或者多个shape以及子路径subpath,Quartz提供了很多方便的shape可以直接调用。例如:point line Arc(圆弧),Curves(曲线),Ellipse(椭圆), Rectangle(矩形)。
对这些path可以进行stroke(描边),也可以进行fill(填充),也可以利用path对一个区域进行截取(clip)
例如 使用截取圆形区域
绘制 Points / lines
Quartz 2D中 使用方法 CGContextMoveToPoint移动画笔到一个点来开始一个新的子路径,使用CGContextAddLineToPint来从当前开始点添加一条线到结束点。
注意:CGContextAddLineToPoint调用后,开始点会重新设置,直到结束点。
举个例子:
- (void)drawRect:(CGRect)rect { [super drawRect:rect]; CGContextRef context = UIGraphicsGetCurrentContext(); //设置填充颜色 CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); //设置描边颜色 CGContextSetStrokeColorWithColor(context, [UIColor darkGrayColor].CGColor); //为了颜色更好的区分 对矩形进行描边 CGContextFillRect(context, rect); CGContextStrokeRect(context, rect); //实际line和point代码 CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); //设置画笔的宽度 CGContextSetLineWidth(context, 4.0); //设置线的顶端的样式 CGContextSetLineCap(context, kCGLineCapRound); //设置线相交处的样式 CGContextSetLineJoin(context, kCGLineJoinRound); CGPoint selfCent = CGPointMake(self.bounds.size.width / 2 + 10, self.bounds.size.height / 2); CGFloat width = 40; //设置画线的起点 CGContextMoveToPoint(context, selfCent.x - width / 2, selfCent.y - width / 2); //移动画笔到结束点,并将结束点作为下一次画线的起点 CGContextAddLineToPoint(context, selfCent.x - width / 2, selfCent.y + width / 2); CGContextAddLineToPoint(context, selfCent.x + width / 2, selfCent.y); CGContextAddLineToPoint(context, selfCent.x - width / 2, selfCent.y - width / 2); //提交 开始渲染 CGContextStrokePath(context); }
效果:
这里 我们提一下线的顶端模式 使用CGContextLineCao来设置
线的相交模式 使用CGContextLineJoin来设置,一共也有三种
画虚线
//画虚线 - (void)drawDashLineInRect:(CGRect)rect andContext:(CGContextRef)context { CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor); CGContextFillRect(context, rect); CGContextStrokeRect(context, rect); //设置描边颜色 CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); //设置下画笔的宽度 CGContextSetLineWidth(context, 1.0); //设置线的顶端样式 CGContextSetLineCap(context, kCGLineCapRound); //设置相交线的样式 CGContextSetLineJoin(context, kCGLineJoinRound); //开始画线 CGFloat lengths[] = {5,15}; //参数说明 /* context 这个不用多书 phase 表示第一个虚线绘制的时候要跳过多少个点 lengths = {10,10}表示先绘制10个点 跳过十个点 在绘制10个点 如此反复 如果把lengths值改为{10, 20, 10},则表示先绘制10个点,跳过20个点,绘制10个点,跳过10个点,再绘制20个点,如此反复,如图: count 表示lengths数组的长度 */ CGContextSetLineDash(context, 1, lengths, 2); CGContextMoveToPoint(context,70,50); CGContextAddLineToPoint(context, 30, 30); CGContextAddLineToPoint(context, 30, 70); CGContextAddLineToPoint(context, 70, 50); CGContextStrokePath(context); }
效果图:
参数说明
void CGContextSetLineDash ( CGContextRef _Nullable c, CGFloat phase, const CGFloat * _Nullable lengths, size_t count );
c 绘制的context,这个不用多说
phase,第一个虚线段从哪里开始,例如传入3,则从第三个单位开始 如果lengths = {10,10}则从第三个单位开始 画七个单位 跳过十个单位 在画是个单位 跳过十个单位 以此类推。
lengths,一个C数组,表示绘制部分和空白部分的分配。例如传入[2,2],则绘制2个单位,然后空白两个单位,以此重复
count lengths的数量
画圆弧
Quartz 2D提供了两个方法来绘制圆弧
CGContextAddArc:普通的圆弧的一部分(以某个点为圆心,指定半径 和多大弧度的圆弧)
CGContextAddArcToPoint:用来绘制圆角,下文会详细阐述。
CGContextAddArc 参数说明:
void CGContextAddArc ( CGContextRef _Nullable c, CGFloat x, CGFloat y, CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise );
c,context不用说了 日常传上下文
x , y 指定坐标原点
radius 指定半径的长度
startAngle/endAngle 指定某一段弧度
clockwise 1 表示顺时针 0 表示逆时针
代码示例 哈哈哈哈哈
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor); CGContextFillRect(context, rect); CGContextStrokeRect(context, rect); CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor); CGContextAddArc(context, 100, 100, 50, 0, M_PI, 1); CGContextStrokePath(context);
效果:
CGContextAddArcToPoint这个方法比较复杂 但是理解了也没有什么难度
函数体
void CGContextAddArcToPoint ( CGContextRef _Nullable c, CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2, CGFloat radius );
参数
c context 不用说了
x1,y1和当前点(x0,y0)决定了第一条切线(x0,y0)->(x1,y1)
x2,y2和(x1,y1)决定了第二条切线
radius,想切的半径。
也就是说
绘制一个半径为radius的圆弧 和上述两条直线都相切。
代码
CGContextMoveToPoint(context, 100, 50); CGContextAddArcToPoint(context,100,0,50,0, 50); CGContextStrokePath(context);
效果
解释为什么
图中的两条红线就是上文提到的两条线,分别是(x0,y0)->(x1,y1)和(x1,y1)->(x2,y2),那么和这两条线都想切的自然就是图中的蓝色圆弧了
椭圆/矩形
这两个比较简单 就不再多说了
- (void)addEllipseAndRectInRect:(CGRect)rect{ CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor); CGContextFillRect(context, rect); CGContextStrokeRect(context, rect); //设置画笔的颜色 CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor); CGContextSetLineWidth(context, 2.0f); //画椭圆 CGContextAddEllipseInRect(context, CGRectMake(10, 10, 100, 70)); //画矩形 CGContextAddRect(context, CGRectMake(10, 10, 100, 70)); //渲染 CGContextStrokePath(context); }
效果:
曲线
Quartz 2D 使用计算机图形学中的多项式绘制曲线 支持二次和三次曲线
利用函数CGContextAddCurveToPoint可以绘制三次曲线
函数体
void CGContextAddCurveToPoint ( CGContextRef _Nullable c, CGFloat cp1x, CGFloat cp1y, CGFloat cp2x, CGFloat cp2y, CGFloat x, CGFloat y );
参数说明
c context 不用多说
cp1/cp2第一个控制点
cp2/cp2第二个控制点
x/y 结束点
具体效果如图
使用函数CGContextAddQuadCurveToPoint 来绘制二次曲线
函数体
void CGContextAddQuadCurveToPoint ( CGContextRef _Nullable c, CGFloat cpx, CGFloat cpy, CGFloat x, CGFloat y );
参数说明
c context
cpx/cpy 控制点
x/y 结束点
效果
来个例子看一下
吼吼哈嘿
//画曲线 - (void)addCurveInRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor); CGContextFillRect(context, rect); CGContextStrokeRect(context, rect); //画二次曲线 //设置起点 CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor); CGContextMoveToPoint(context, 10, 150); CGContextAddQuadCurveToPoint(context, 30, 10, 150, 160); CGContextStrokePath(context); //画三次曲线 //保存上下文 同时也是结束上次的绘制 CGContextSaveGState(context); CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); //设置起点 CGContextMoveToPoint(context, 10, 190); CGContextAddCurveToPoint(context, 50, 100, 200, 150, 200, 10); CGContextStrokePath(context); //提出最新的上下文 CGContextRestoreGState(context); }
效果图
当曲线和动画结合起来,用处会很大。如果写到动画那一部分 会结合起来讲解。