2013-06-12 4 views
2

Я пытаюсь воссоздать что-то вроде этой формы - http://www.creativeapplications.net/wp-content/uploads/2010/09/horizon_02_1024x768.png - используя UIKit или CoreGraphics на iOS.Триангуляция Делоне с заполнением градиентом?

Изображение на фотографии было выполнено с помощью openFrameworks, и оно работает на iOS. Тем не менее, я хотел бы построить то же самое без использования oF, поэтому я могу сохранить его родным.

Я предполагаю, что форма была создана с помощью триангуляции Делоне, которую я могу сделать в Objective-C. Проблема заключается в заполнении фигур градиентом вместо обычного UIColor!

Есть ли способ сделать что-то подобное изначально с хорошей производительностью на iPad, или я должен просто делать это с помощью openFrameworks и привносить это в приложение как слой?

+0

Я не знаю, почему вы получили downvoted пару раз, так что вот +1, чтобы сделать вас еще раз. – Michael

+0

Спасибо, Майкл, оцените его;) – Andre

ответ

2

Вы спрашиваете, как заполнить треугольник градиентом? Следующий код делает именно это. Для того, чтобы заставить его работать, вы должны добавить рамки QuartzCore и

#import <QuartzCore/QuartzCore.h> 

код создает слой формы в виде треугольника, а затем использует это в качестве маски на слой с градиентом. Надеюсь это поможет.

- (void)drawRect:(CGRect)rect 
{ 
    CGFloat w = self.bounds.size.width/4; 
    CGFloat h = self.bounds.size.height/4; 
    CGFloat x = w * 2; 
    CGFloat y = h; 
    CGMutablePathRef path = CGPathCreateMutable(); 
    CGPathMoveToPoint(path,NULL, x, y); 
    CGPathAddLineToPoint(path, NULL, x+w, y+2*h); 
    CGPathAddLineToPoint(path, NULL, x-w, y+2*h); 
    CGPathCloseSubpath(path); 


    CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 
    shapeLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height); 
    [shapeLayer setPath:path]; 

    CAGradientLayer *gradientLayer = [CAGradientLayer layer]; 
    gradientLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height); 
    gradientLayer.startPoint = CGPointMake(0.25, 1.0); 
    gradientLayer.endPoint = CGPointMake(0.75, 0.0); 
    UIColor *startColour = [UIColor redColor]; 
    UIColor *endColour = [UIColor greenColor]; 
    gradientLayer.colors = [NSArray arrayWithObjects:(id)[startColour CGColor], (id)[endColour CGColor], nil]; 

    [gradientLayer setMask:shapeLayer]; 

    [self.layer addSublayer:gradientLayer]; 

    CGPathRelease(path); 
} 
+0

Привет, Майкл. Я хочу знать, как заполнить несколько треугольников различными градиентными заполнениями, учитывая, что они, вероятно, все используют представление/контекст – Andre

+0

Не похоже, что вам нужен массив градиентных слоев, каждый из которых является одним треугольником, каждый из которых имеет свой собственный маска? Самая сложная часть - это работа над которой. – Michael

+0

Если это возможно в том же контексте, этот метод наслаивания может быть тем, что мне нужно! Тем более, что они никогда не пересекаются! Попробуй это – Andre

1

Я собираюсь сделать один треугольник, но вы можете сделать несколько используя повторение:

//Create the triangle Path and clip the drawing to it 
CGContextSaveGState(context); 
CGContextBeginPath(context); 
CGContextMoveToPoint(context, self.bounds.size.width * .4, self.bounds.size.height * 1/6.); 
CGContextAddLineToPoint(context,self.bounds.size.width * .4, self.bounds.size.height * 3/6.); 
CGContextAddLineToPoint(context,self.bounds.size.width * .2, self.bounds.size.height * 3/6.); 
CGContextClosePath(context); 
CGContextClip(context); 

//Now call the linear gradient drawing function 
[self drawLinearGradient:context withRect:self.bounds startColor:[UIColor colorWithRed:1 green:1 blue:1 alpha:.3] endColor:[UIColor colorWithRed:.5 green:.5 blue:.5 alpha:.3] startFraction:.3 stopFraction:1]; 

//And now restore so that we can clip the next triangle 
CGContextRestoreGState(context); 

Теперь для линейного кода градиента рисования:

- (void) drawLinearGradient: (CGContextRef) context withRect: (CGRect) rect startColor: (UIColor*) startColor endColor: (UIColor*) endColor startFraction:(float)start stopFraction:(float)stop 
{ 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGFloat locations[] = { start, stop }; 

    CGGradientRef myGradient; 
    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB(); 

    CGColorRef startColorRef = [startColor CGColor]; 
    CGColorRef endColorRef = [endColor CGColor]; 

    const CGFloat *components = CGColorGetComponents(startColorRef); 
    CGFloat red  = components[0]; 
    CGFloat green = components[1]; 
    CGFloat blue = components[2]; 
    CGFloat alpha = components[3]; 

    const CGFloat *components2 = CGColorGetComponents(endColorRef); 
    CGFloat red2  = components2[0]; 
    CGFloat green2 = components2[1]; 
    CGFloat blue2 = components2[2]; 
    CGFloat alpha2 = components2[3]; 

    CGFloat colors[] = 
    { 
     red, green, blue, alpha, 
     red2, green2, blue2, alpha2 
    }; 

    myGradient = CGGradientCreateWithColorComponents(rgb, colors, locations, 2); 
    CGColorSpaceRelease(rgb); 

    CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect)); 
    CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect)); 

    CGContextSaveGState(context); 
    CGContextAddRect(context, rect); 
    CGContextClip(context); 
    CGContextDrawLinearGradient(context, myGradient, startPoint, endPoint, 0); 
    CGContextRestoreGState(context); 

    CGGradientRelease(myGradient); 
    CGColorSpaceRelease(colorSpace); 
} 

Вы можете настроить эта функция линейного градиента обрабатывает более двух местоположений/цветов, если вы хотите. Это очень просто, но если вы знаете начало и конец цветов и местоположений каждого треугольника, вы должны выполнить то, что хотите (рисунок изначально) с помощью этого кода (без сотен подслоев). Хотя слои могут рисовать быстрее, я понятия не имею.

+0

Thanks Putz. Отдам! – Andre

Смежные вопросы