2011-02-07 10 views
7

Hay una serie de recursos aquí y en otras partes de la web sobre cómo dibujar con un degradado: relleno o trazo.Gráficos básicos: dibujo a lo largo de una ruta con un degradado normal

Sin embargo, AFAICT, ninguno aborda el siguiente requisito: cómo dibujar un camino con un gradiente normal , con lo que normal de significa ortogonal a la trayectoria. El efecto neto podría ser algo así como pasta de dientes o un tubo cuando se aplica con un gradiente lineal oscuro-> claro-> oscuro. Aquí está esta idea en el caso de un rectángulo redondeado:

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

(esto fue dibujado a mano y las esquinas no son muy buenos).

En el caso específico de la rectitud redonda, creo que puedo lograr este efecto con 4 gradientes lineales (los lados) y 4 gradientes radiales (las esquinas). Pero, ¿hay algo mejor?

¿Existe una solución fácil para cualquier ruta?

Respuesta

6

La única solución "fácil" que puedo pensar sería recorrer la ruta varias veces, reduciendo el ancho de la carrera y cambiando el color ligeramente cada vez, para simular un degradado.

Obviamente, esta podría ser una operación costosa para rutas complejas, por lo que le conviene almacenar en caché el resultado si es posible.

#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

Cuestiones relacionadas