views:

46

answers:

1

I am trying to draw a shape's reflection using Cocoa. I have already applied an NSAffineTransform and redrawn the shape successfully, but now I can't figure out how to draw an alpha mask over it. I'm using an NSCompositeDestinationOut operation, but it's giving me an unwanted result:alt text

I'm not exactly sure how to fix this - I need to make it so the gradient acts only as an alpha mask and is not actually displayed. Am I using the wrong compositing mode?

Thanks! Here's the gradient code if needed:

- (void)fadeOutRect:(NSRect)rect {
    [NSGraphicsContext saveGraphicsState];
    [[NSGraphicsContext currentContext] setCompositingOperation:NSCompositeDestinationOut];

    NSGradient *gradient = [[NSGradient alloc] initWithColorsAndLocations:
                            [[NSColor blackColor] colorWithAlphaComponent:0.5], 0.0,
                            [[NSColor blackColor] colorWithAlphaComponent:1.0], 0.8, nil];
    [gradient drawInRect:NSMakeRect(rect.origin.x, rect.origin.y + rect.size.height - ( PILL_HEIGHT * 2 ),
                                    rect.size.width, PILL_HEIGHT) angle:270];

    [NSGraphicsContext restoreGraphicsState];
}
A: 

Yep. Here's an example of the code we use to do this. It uses a source image, and has a bit of funny business with a scale factor, but you should be able to use the basic structure and compositing choices to do what you need. (This code is within the [reflectionImage lockFocus] block, and self is the NSImage that we're making the reflection of.)

// Draw our mask into the image
NSGradient* fade = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0 alpha:0.5]
                                                 endingColor:[NSColor clearColor]];
[fade drawFromPoint:NSMakePoint(0.0, size.height)
            toPoint:NSMakePoint(0.0, 0.0)
            options:0];

// Composite the original image, upside-down
NSAffineTransform* flipper = [NSAffineTransform transform];
[flipper scaleXBy:1.0 yBy:-1.0];
[flipper concat];
[self drawInRect:NSMakeRect(0.0, -1.0*size.height, size.width, size.height)
        fromRect:NSMakeRect(0.0, 0.0, self.size.width, size.height / scaleFactor)
       operation:NSCompositeSourceIn fraction:1.0];
bdrister
Okay, I am now drawing the shape into an NSImage and compositing it using the method you showed, but all that is displayed is a black box.
hansengel
You'll need to be more specific--as in, post your code--about what exactly you're doing. I assure you that this code works, as it's used in a production app and is doing just fine, so there's nothing that we can really do to help you based just on an assertion that it's not working. :-/
bdrister