標籤:
Stroke-描邊
影響描邊的因素
- 線的寬度-CGContextSetLineWidth
- 交叉線的處理方式-CGContextSetLineJoin
- 線頂端的處理方式-CGContextSetLineCap
- 進一步限制交叉線的處理方式 -CGContextSetMiterLimit
- 是否要虛線-Line dash pattern
- 顏色控制項-CGContextSetStrokeColorSpace
- 畫筆顏色-CGContextSetStrokeColor/CGContextSetStrokeColorWithColor
- 描邊模式-CGContextSetStrokePattern
虛線,畫筆顏色,交叉的處理方式,頂端的處理方式,線寬度在之前這篇文章裡有講過,這裡不再贅述。
CGContextSetMiterLimit
如果當前交叉線繪圖模式是kCGLineJoinMiter( CGContextSetLineJoin),quartz根據設定的miter值來判斷線的join是bevel或者miter。具體的模式是:將miter的長度除以線的寬度,如果小於設定的mitetLimit值,則join style為bevel;
先看看三種join效果
舉個例子就懂了
CGContextMoveToPoint(context,10,10); CGContextAddLineToPoint(context, 50, 50); CGContextAddLineToPoint(context, 10, 90); CGContextSetLineWidth(context, 10.0); CGContextSetLineJoin(context, kCGLineJoinMiter); CGContextSetMiterLimit(context,20.0); CGContextStrokePath(context);
效果
將Miter設定為1,則效果如下
CGContextSetStrokeColorSpace和pattern會在以後的文章詳細闡述,這裡暫時先略去
Fill-填充
Quartz填充的時候會認為subpath是封閉的,然後根據規則來填充。有兩種規則:
nonzero winding number rule.沿著當前點,畫一條直線到地區外,檢查交叉點,如果交叉點從左至右,則加一,從右至左,則減去一。如果結果不為0,則繪製。參見這個link
even-odd rule,沿著當前點,花一條線到地區外,然後檢查相交的路徑,偶數則繪製,奇數則不繪製。
具體效果如下
相關函數
- CGContextEOFillPath - 用even-odd rule來填充
- CGContextFillPath - 用nonzero winding number rule方式填充
- CGContextFillRect/CGContextFillRects - 填充指定矩形地區內path
- CGContextFillEllipseInRect - 填充橢圓
- CGContextDrawPath - 繪製當前path(根據參數stroke/fill)
Clip-切割
顧名思義,根據path只繪製指定的地區,在地區外的都不會繪製。
舉個例子,截取圓形地區
效果
注意,切割是和狀態相關的,以為這切割以後都是在切割後context中繪製的。
如果要儲存狀態,參照這篇文章裡講的壓棧和出棧
- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextBeginPath (context); CGContextAddArc(context,50, 50,20,0, M_PI * 2,true); CGContextClosePath (context); CGContextClip (context); CGContextSetFillColorWithColor(context, [UIColor lightGrayColor].CGColor); CGContextFillRect(context, rect); //New Code CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor); CGContextMoveToPoint(context,10,10); CGContextAddLineToPoint(context, 50, 50); CGContextAddLineToPoint(context, 10, 90); CGContextSetLineWidth(context, 10.0); CGContextSetLineJoin(context, kCGLineJoinMiter); CGContextSetMiterLimit(context,20.0); CGContextStrokePath(context);}-(instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { self.opaque = NO; } return self;}
相關函數
- CGContextClip 按照nonzero winding number rule規則切割
- CGContextEOClip 按照even-odd規則切割
- CGContextClipToRect 切割到指定矩形
- CGContextClipToRects 切割到指定矩形組
- CGContextClipToMask 切割到mask
Subpath - 子路徑
很簡單,在stroke/fill或者CGContextBeginPath/CGContextClosePath以後就新開啟一個子路徑。
注意:
CGContextClosePath,會串連第一個點和最後一個點
Blend-混合模式
Quartz中,預設的顏色混合模式採用如下公式
result = (alpha * foreground) + (1 - alpha) * background
可以使用CGContextSetBlendMode來設定不同的顏色混合模式,注意設定blend是與context繪製狀態相關的,一切與狀態相關的設定都要想到狀態堆棧(如果看不懂這句,看我之前的那兩篇文章裡講的)。
先看看官方文檔裡的例子,最後我會寫個自己的例子
background
foreGround
Normal Blend Mode
效果
Multiply Blend Mode
交叉部分會顯得比較暗,用上一層和底層相乘,至少和一層一樣暗
Screen Blend Mode
交叉部分比較亮,上層的reverse和下層的reverse相乘,至少和一個一樣亮
blend模式較多,這裡不一一列舉了,參見官方文檔
iOS 2D繪圖詳解(Quartz 2D)之路徑(stroke,fill,clip,subpath,blend)