2009-08-20 113 views
22

我知道如何繪製簡單的線條:如何使用Core Graphics/iPhone繪製漸變線(淡入/淡出)?

CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); 
CGContextMoveToPoint(context, x, y); 
CGContextAddLineToPoint(context, x2, y2); 
CGContextStrokePath(context); 

而且我知道如何做一個漸變的矩形,i.g:

CGColorSpaceRef myColorspace=CGColorSpaceCreateDeviceRGB(); 
size_t num_locations = 2; 
CGFloat locations[2] = { 1.0, 0.0 }; 
CGFloat components[8] = { 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; 

CGGradientRef myGradient = CGGradientCreateWithColorComponents(myColorspace, components, locations, num_locations); 

CGPoint myStartPoint, myEndPoint; 
myStartPoint.x = 0.0; 
myStartPoint.y = 0.0; 
myEndPoint.x = 0.0; 
myEndPoint.y = 10.0; 
CGContextDrawLinearGradient (context, myGradient, myStartPoint, myEndPoint, 0); 

但我怎麼能畫一條線的漸變,胃內從黑色漸變爲白色(也可能在另一側漸漸變黑)?

+1

快速註釋 - 此處選擇的答案不正確。 **這是可能的筆畫任意路徑與梯度**作爲[這個答案](http://stackoverflow.com/a/25034854/2547229)顯示。 – Benjohn 2015-05-22 12:48:26

回答

20

經過多次嘗試後,我現在確定漸變不會影響筆畫,所以我認爲不可能使用CGContextStrokePath()繪製漸變線。對於水平線和垂直線,解決方案是使用CGContextAddRect(),幸運的是我需要的。我換成

CGContextMoveToPoint(context, x, y); 
CGContextAddLineToPoint(context, x2, y2); 
CGContextStrokePath(context); 

CGContextSaveGState(context); 
CGContextAddRect(context, CGRectMake(x, y, width, height)); 
CGContextClip(context); 
CGContextDrawLinearGradient (context, gradient, startPoint, endPoint, 0); 
CGContextRestoreGState(context); 

,一切工作正常。感謝Brad Larson提供的關鍵提示。

+0

我發現了完全一樣的東西。它會出現漸變需要一個剪輯路徑(或矩形)首先應用於圖形上下文。也許這是因爲漸變渲染在封閉區域而不是路徑(或矩形)邊界本身? – Dalmazio 2011-07-29 14:51:17

+0

這不能顯示斜坡線? – AntiMoron 2016-03-17 03:24:07

8

您可以使用Core Animation圖層。您可以通過設置其路徑屬性來爲您的線使用CAShaperLayer,然後您可以使用CAGradientLayer作爲圖層蒙版到您的形狀圖層,這將導致線條消失。

將您的CGContext ...調用替換爲調用CGPath ...調用以創建行路徑。使用該路徑在圖層上設置路徑字段。然後在您的梯度層,指定要使用的(可能是黑到白)的顏色,然後將面膜是線層是這樣的:

[gradientLayer setMask:lineLayer]; 

什麼是很酷的梯度層是允許你指定漸變將停止的位置列表,以便您可以淡入和淡出。它只支持線性漸變,但聽起來可能符合您的需求。

讓我知道你是否需要澄清。

編輯:現在,我想起它,只需創建一個單一的CAGradientLayer,即您想要的線條的寬度/高度。指定漸變顏色(黑色至白色或黑色以清除顏色)以及startPoint和endtPoints,它應該爲您提供所需的內容。

+0

你說得對,這完全符合我的需求,但不幸的是,這隻適用於iPhone OS 3的版本,我想至少使用2.2。不管怎麼說,還是要謝謝你... – Walchy 2009-08-20 15:54:06

+1

我想你的意思是[gradientLayer setMask:LineLayer]; - 對?您用CAShapeLayer遮罩CAGradientLayer。 – Palimondo 2011-08-19 21:39:00

+0

輝煌。學到了很多。 – Ian1971 2011-10-07 19:11:20

8

之後你畫的線,你可以調用

CGContextClip(context); 

進一步拉夾到你的行區域。如果您繪製漸變,它現在應該包含在線區域內。請注意,如果您只想顯示漸變,而不是下方的線條,則需要爲線條使用清晰的顏色。您可以使用CGContextAddRect()來定義較厚的區域。

我在我的回答here中提供了一個更詳細的使用此上下文剪輯的示例。

+1

我試過你的建議: \t CGContextSetLineWidth(context,10.0); //應該足夠厚 \t CGContextSetRGBStrokeColor(context,0.0,0.0,0.0,0.0); \t CGContextMoveToPoint(context,50,50); \t CGContextAddLineToPoint(context,100,100); \t CGContextStrokePath(context); \t CGContextClip(context); \t CGContextDrawLinearGradient(context,myGradient,myStartPoint,myEndPoint,0); 但這拋出 :doClip:空路徑。 該文檔說, CGContextStrokePath(context); 清除路徑 - 沒有這個方法沒有錯誤被拋出,但沒有任何東西被繪製。 任何想法? – Walchy 2009-08-20 16:04:23

0
CGContextMoveToPoint(context, frame.size.width-200, frame.origin.y+10); 
CGContextAddLineToPoint(context, frame.size.width-200, 100-10); 
CGFloat colors[16] = { 0,0, 0, 0, 
    0, 0, 0, .8, 
    0, 0, 0, .8, 
    0, 0,0 ,0 }; 
CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB(); 
CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 4); 

CGContextSaveGState(context); 
CGContextAddRect(context, CGRectMake(frame.size.width-200,10, 1, 80)); 
CGContextClip(context); 
CGContextDrawLinearGradient (context, gradient, CGPointMake(frame.size.width-200, 10), CGPointMake(frame.size.width-200,80), 0); 
CGContextRestoreGState(context); 

它爲我工作。

25

是可能的中風任意路徑用梯度,或者任何其它填充效果,諸如圖案。

正如你已經發現,描邊路徑不與當前的漸變渲染。這隻充滿路徑使用漸變(當你打開他們的剪輯,然後繪製漸變)。

然而,核芯顯卡有一個驚人的冷靜程序CGContextReplacePathWithStrokedPath將在改變你打算路徑行程到是相當於裝滿時的路徑。

在幕後,CGContextReplacePathWithStrokedPath構建了一個多邊形邊緣周圍的描邊路徑和交換機的路徑已定義。我推測,核心圖形渲染引擎可能在調用CGContextStrokePath做到這一點反正

下面是關於這款蘋果的文檔:

石英創建使用當前圖形上下文的參數描邊路徑。創建新的路徑,以便填充它繪製相同的像素作爲撫摸着原始路徑。您可以像使用任何上下文的路徑一樣使用此路徑。例如,可以通過調用這個函數,然後在函數CGContextClip調用剪輯的路徑描邊版本。

所以,在轉換的東西,你可以填寫你的路徑,轉而在一個剪輯,然後的梯度。效果就好像你已經用漸變撫摸了路徑。

代碼

它會是這個樣子......

// Get the current graphics context. 
    // 
    const CGContextRef context = UIGraphicsGetCurrentContext(); 

    // Define your stroked path. 
    // 
    // You can set up **anything** you like here. 
    // 
    CGContextAddRect(context, yourRectToStrokeWithAGradient); 

    // Set up any stroking parameters like line. 
    // 
    // I'm setting width. You could also set up a dashed stroke 
    // pattern, or whatever you like. 
    // 
    CGContextSetLineWidth(context, 1); 

    // Use the magical call. 
    // 
    // It turns your _stroked_ path in to a **fillable** one. 
    // 
    CGContextReplacePathWithStrokedPath(context); 

    // Use the current _fillable_ path in to define a clipping region. 
    // 
    CGContextClip(context); 

    // Draw the gradient. 
    // 
    // The gradient will be clipped to your original path. 
    // You could use other fill effects like patterns here. 
    // 
    CGContextDrawLinearGradient(
     context, 
     yourGradient, 
     gradientTop, 
     gradientBottom, 
     0 
    ); 

還注意到

值得強調上述文件的一部分:

石英創建描邊路徑使用當前圖形上下文的參數。

明顯的參數是線寬。但是,所有都使用了線條繪製狀態,例如筆畫圖案,斜接限制,線條連接,上限,破折號圖案等。這使得該方法非常強大。

欲瞭解更多詳情,請參閱this answerthis S.O. question