objective-ccgcontextcgcontextref

CGContextDrawLinearGradient confusion. Need clarification


I am have been experimenting with CGContextDrawLinearGradient and I terribly confused with what start point and end point mean? I thought they mean coordinates on the current CGContext so if I define start point to be 0,0 and end point to be 100,100, i would get a square with gradient. I get something else altogether that I just cannot connect to my co-ordinates.

This is the code that I have:

- (void)drawRect:(CGRect)rect {
// Drawing code 
CGContextRef current_context = UIGraphicsGetCurrentContext();
CGContextSaveGState(current_context);

// Gradient
CGFloat locations[3] = {0.0, 0.5, 1.0};
CGFloat components[12] = {1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0};
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, 3);
CGPoint startPoint = CGPointMake(0, 0);
CGPoint endPoint = CGPointMake(40, 40);
CGContextDrawLinearGradient(current_context, gradient, startPoint, endPoint, 0);


// Shadow
CGContextSetShadow(current_context, CGSizeMake(4,7), 1.0);

// Image
UIImage *logoImage = [UIImage imageNamed:@"logo.png"];
[logoImage drawInRect:bounds];
CGContextRestoreGState(current_context);

}

Thanks for your help in advance..


Solution

  • Most of your code is quite OK; the problem occurs in the following lines:

    CGPoint startPoint = CGPointMake(0, 0);
    CGPoint endPoint = CGPointMake(40, 40);
    CGContextDrawLinearGradient(current_context, gradient, startPoint, endPoint, 0);
    

    CGContextDrawLinearGradient expects to get a start and an end point (defining a line, not two diagonal edges of a square!).

    The gradient is then drawn by colored lines perpendicular to this controlling line. The drawing starts with a line going through startPoint (perpendicular to the line between startPoint and endPoint) using the start color (color at location 0). The next line is drawn through a point 'one pixel' closer to the endPoint, with a color calculated to be somewhere between the start and the end or next color (depending of the number of color locations). Finally a line is drawn through the endPoint (again perpendicular...) using the end color.

    The advantage of using a (controlling) line instead of a square is, that the gradient can be drawn in any direction; horizontally, vertically, somewhere between, only depending of the direction of the given line.

    In your example code, the gradient should be diagonally, as your line has an angle of 45° to the x-axis :-).