2011-08-02 32 views
7

Tôi cần một gradient xuyên tâm trong hình dạng của một hình bầu dục hoặc hình elip và có vẻ như nó CGContextDrawRadialGradient chỉ có thể vẽ một vòng tròn hoàn hảo. Tôi đã vẽ một bối cảnh hình vuông sau đó sao chép/vẽ vào một bối cảnh hình chữ nhật.Có cách nào để vẽ một CGContextDrawRadialGradient như một hình bầu dục thay vì một vòng tròn hoàn hảo?

Bất kỳ cách nào tốt hơn để thực hiện việc này?

Cảm ơn!

Trả lời

4

Bạn có thể thay đổi biến đổi ngữ cảnh để vẽ hình elip (ví dụ, áp dụng CGContextScaleCTM (ngữ cảnh, 2.0, 1.0) ngay trước khi gọi CGContextDrawRadialGradient() để vẽ một hình elip có chiều rộng gấp hai lần nó cao). Tuy nhiên, hãy nhớ áp dụng biến đổi nghịch đảo cho điểm bắt đầu và điểm kết thúc của bạn.

+0

này đã giúp tôi có được trên đúng đường. Cảm ơn! Tôi mở rộng điều này với một ví dụ mã dưới đây. –

5

Cách duy nhất tôi đã tìm thấy để làm điều này là như Mark F đề xuất, nhưng tôi nghĩ câu trả lời cần một ví dụ để dễ hiểu hơn.

Vẽ một gradient elip trong một cái nhìn trong iOS (và sử dụng ARC):

- (void)drawRect:(CGRect)rect { 

    CGContextRef ctx = UIGraphicsGetCurrentContext(); 

    // Create gradient 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGFloat locations[] = {0.0, 1.0}; 

    UIColor *centerColor = [UIColor orangeColor]; 
    UIColor *edgeColor = [UIColor purpleColor]; 

    NSArray *colors = [NSArray arrayWithObjects:(__bridge id)centerColor.CGColor, (__bridge id)edgeColor.CGColor, nil]; 
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations); 

    // Scaling transformation and keeping track of the inverse 
    CGAffineTransform scaleT = CGAffineTransformMakeScale(2, 1.0); 
    CGAffineTransform invScaleT = CGAffineTransformInvert(scaleT); 

    // Extract the Sx and Sy elements from the inverse matrix 
    // (See the Quartz documentation for the math behind the matrices) 
    CGPoint invS = CGPointMake(invScaleT.a, invScaleT.d); 

    // Transform center and radius of gradient with the inverse 
    CGPoint center = CGPointMake((self.bounds.size.width/2) * invS.x, (self.bounds.size.height/2) * invS.y); 
    CGFloat radius = (self.bounds.size.width/2) * invS.x; 

    // Draw the gradient with the scale transform on the context 
    CGContextScaleCTM(ctx, scaleT.a, scaleT.d); 
    CGContextDrawRadialGradient(ctx, gradient, center, 0, center, radius, kCGGradientDrawsBeforeStartLocation); 

    // Reset the context 
    CGContextScaleCTM(ctx, invS.x, invS.y); 

    // Continue to draw whatever else ... 

    // Clean up the memory used by Quartz 
    CGGradientRelease(gradient); 
    CGColorSpaceRelease(colorSpace); 
} 

Đặt trong một cái nhìn với một nền đen bạn nhận được:

enter image description here