2011-02-07 36 views
7

網上有許多關於如何使用漸變 - 填充或描邊進行繪製的資源。核心圖形:沿着具有正常梯度的路徑繪圖

然而,AFAICT,沒有解決以下需求:如何繪製路徑與正常梯度,由此正常意味着垂直於路徑。當使用暗 - >亮 - >暗線性梯度時,淨效應可能像牙膏或管。下面是這個想法在一個圓角矩形的情況下:

round-rect tube http://muys.net/cadre_blanc.png

(這是手工繪製和邊角不是很好)。

在圓形矩形的具體情況下,我認爲我可以用4個線性梯度(邊)和4個徑向梯度(邊角)實現這種效果。但是有更好的嗎?

是否有任何路徑的簡單解決方案?

回答

6

我能想到的唯一「簡單」解決方案是多次對路徑進行描邊,減少描邊寬度並每次稍微改變顏色以模擬漸變。

顯然,這對於複雜路徑來說可能是一個昂貴的操作,因此如果可能的話,您會希望緩存結果。

#define RKRandom(x) (arc4random() % ((NSUInteger)(x) + 1)) 

@implementation StrokeView 

- (void)drawRect:(NSRect)rect 
{ 
    NSRect bounds = self.bounds; 

    //first draw using Core Graphics calls 
    CGContextRef c = [[NSGraphicsContext currentContext] graphicsPort]; 

    CGMutablePathRef path = CGPathCreateMutable(); 

    CGPathMoveToPoint(path, NULL, NSMidX(bounds), NSMidY(bounds)); 
    CGContextSetMiterLimit(c,90.0); 
    CGContextSetLineJoin(c, kCGLineJoinRound); 
    CGContextSetLineCap(c, kCGLineCapRound); 

    for(NSUInteger f = 0; f < 20; f++) 
    { 
     CGPathAddCurveToPoint(
           path, 
           NULL, 
           (CGFloat)RKRandom((NSInteger)NSWidth(bounds)) + NSMinX(bounds), 
           (CGFloat)RKRandom((NSInteger)NSHeight(bounds)) + NSMinY(bounds), 
           (CGFloat)RKRandom((NSInteger)NSWidth(bounds)) + NSMinX(bounds), 
           (CGFloat)RKRandom((NSInteger)NSHeight(bounds)) + NSMinY(bounds), 
           (CGFloat)RKRandom((NSInteger)NSWidth(bounds)) + NSMinX(bounds), 
           (CGFloat)RKRandom((NSInteger)NSHeight(bounds)) + NSMinY(bounds) 
          ); 
    } 

    for(NSInteger i = 0; i < 8; i+=2) 
    { 
     CGContextSetLineWidth(c, 8.0 - (CGFloat)i); 
     CGFloat tint = (CGFloat)i * 0.15; 

     CGContextSetRGBStrokeColor (
            c, 
            1.0, 
            tint, 
            tint, 
            1.0 
            ); 
     CGContextAddPath(c, path); 
     CGContextStrokePath(c); 
    } 

    CGPathRelease(path); 

    //now draw using Cocoa drawing 
    NSBezierPath* cocoaPath = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(self.bounds, 20.0, 20.0) xRadius:10.0 yRadius:10.0]; 
    for(NSInteger i = 0; i < 8; i+=2) 
    { 
     [cocoaPath setLineWidth:8.0 - (CGFloat)i]; 
     CGFloat tint = (CGFloat)i * 0.15; 
     NSColor* color = [NSColor colorWithCalibratedRed:tint green:tint blue:1.0 alpha:1.0]; 
     [color set]; 
     [cocoaPath stroke]; 
    } 
} 

@end 

sample output