2011-02-07 11 views
7

Ci sono un certo numero di risorse qui e altrove sul web su come disegnare con un gradiente - riempimento o tratto.Grafica principale: disegnare lungo un percorso con un gradiente normale

Tuttavia, AFAICT, nessuno risolve il seguente requisito: come disegnare un percorso con un normale gradiente , per cui normale mezzi ortogonale al percorso. L'effetto netto potrebbe essere qualcosa come il dentifricio o un tubo quando applicato con un gradiente scuro scuro-> chiaro-> scuro. Ecco questa idea nel caso di un rettangolo arrotondato:

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

(questa è stata disegnata a mano e gli angoli non sono molto buone).

Nel caso specifico del retto rotondo, penso di poter ottenere questo effetto con 4 gradienti lineari (i lati) e 4 gradienti radiali (gli angoli). Ma c'è di meglio?

C'è una soluzione facile per qualsiasi percorso?

risposta

6

L'unica soluzione "facile" che posso pensare sarebbe quella di accarezzare il percorso più volte, riducendo la larghezza del tratto e cambiando leggermente il colore ogni volta, per simulare un gradiente.

Ovviamente, questa potrebbe essere un'operazione dispendiosa per percorsi complessi, pertanto se possibile si desidera memorizzare nella cache il risultato.

#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

Problemi correlati