fix fillOpacity with gradients

This commit is contained in:
Horcrux 2016-07-21 19:11:36 +08:00
Родитель 16a1f89bf6
Коммит 63f793c54e
7 изменённых файлов: 39 добавлений и 23 удалений

Просмотреть файл

@ -28,6 +28,7 @@ class Ellipse extends Shape{
render() { render() {
let props = this.props; let props = this.props;
return <RNSVGEllipse return <RNSVGEllipse
ref={ele => this.root = ele} ref={ele => this.root = ele}
{...this.extractProps(props)} {...this.extractProps(props)}

Просмотреть файл

@ -28,6 +28,11 @@
- (void)paint:(CGContextRef)context opacity:(CGFloat)opacity brushConverter:(RNSVGBrushConverter *)brushConverter - (void)paint:(CGContextRef)context opacity:(CGFloat)opacity brushConverter:(RNSVGBrushConverter *)brushConverter
{ {
BOOL transparency = opacity < 1;
if (transparency) {
CGContextSetAlpha(context, opacity);
CGContextBeginTransparencyLayer(context, NULL);
}
if (brushConverter.type == kRNSVGLinearGradient) { if (brushConverter.type == kRNSVGLinearGradient) {
[brushConverter drawLinearGradient:context]; [brushConverter drawLinearGradient:context];
@ -36,6 +41,10 @@
} else if (brushConverter.type == kRNSVGPattern) { } else if (brushConverter.type == kRNSVGPattern) {
// todo: // todo:
} }
if (transparency) {
CGContextEndTransparencyLayer(context);
}
} }
@end @end

Просмотреть файл

@ -58,6 +58,7 @@
CGAffineTransform transform = CGAffineTransformMakeScale(1, ry / rx); CGAffineTransform transform = CGAffineTransformMakeScale(1, ry / rx);
CGContextConcatCTM(context, transform); CGContextConcatCTM(context, transform);
CGContextDrawRadialGradient(context, gradient, CGPointMake(fx, fy), 0, CGPointMake(cx, cy), rx, extendOptions); CGContextDrawRadialGradient(context, gradient, CGPointMake(fx, fy), 0, CGPointMake(cx, cy), rx, extendOptions);
CGGradientRelease(gradient); CGGradientRelease(gradient);
} }

Просмотреть файл

@ -59,7 +59,7 @@
CGContextAddPath(context, self.d); CGContextAddPath(context, self.d);
CGContextClip(context); CGContextClip(context);
RNSVGBrushConverter *brushConverter = [[self getSvgView] getDefinedBrushConverter:[self.fill brushRef]]; RNSVGBrushConverter *brushConverter = [[self getSvgView] getDefinedBrushConverter:[self.fill brushRef]];
[self.fill paint:context opacity:self.strokeOpacity brushConverter:brushConverter]; [self.fill paint:context opacity:self.fillOpacity brushConverter:brushConverter];
CGContextRestoreGState(context); CGContextRestoreGState(context);
if (!self.stroke) { if (!self.stroke) {
return; return;

Просмотреть файл

@ -23,21 +23,12 @@
{ {
RNSVGNode* template = [[self getSvgView] getDefinedTemplate:self.href]; RNSVGNode* template = [[self getSvgView] getDefinedTemplate:self.href];
if (template) { if (template) {
CGFloat opacity = self.opacity; [self beginTransparencyLayer:context];
BOOL transparent = opacity < 1;
if (transparent) {
CGContextBeginTransparencyLayer(context, NULL);
}
[self clip:context]; [self clip:context];
[template mergeProperties:self mergeList:self.mergeList]; [template mergeProperties:self mergeList:self.mergeList];
[template renderTo:context]; [template renderTo:context];
[template resetProperties]; [template resetProperties];
[self endTransparencyLayer:context];
if (transparent) {
CGContextEndTransparencyLayer(context);
}
} else if (self.href) { } else if (self.href) {
// TODO: calling yellow box here // TODO: calling yellow box here
RCTLogWarn(@"`Use` element expected a pre-defined svg template as `href` prop, template named: %@ is not defined.", self.href); RCTLogWarn(@"`Use` element expected a pre-defined svg template as `href` prop, template named: %@ is not defined.", self.href);

Просмотреть файл

@ -76,4 +76,8 @@
*/ */
- (void)resetProperties; - (void)resetProperties;
- (void)beginTransparencyLayer:(CGContextRef)context;
- (void)endTransparencyLayer:(CGContextRef)context;
@end @end

Просмотреть файл

@ -11,6 +11,9 @@
#import "RNSVGClipPath.h" #import "RNSVGClipPath.h"
@implementation RNSVGNode @implementation RNSVGNode
{
BOOL transparent;
}
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex - (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
{ {
@ -52,8 +55,9 @@
} else if (opacity > 1) { } else if (opacity > 1) {
opacity = 1; opacity = 1;
} }
[self invalidate]; [self invalidate];
transparent = opacity < 1;
_opacity = opacity; _opacity = opacity;
} }
@ -63,27 +67,33 @@
super.transform = transform; super.transform = transform;
} }
- (void)beginTransparencyLayer:(CGContextRef)context
{
if (transparent) {
CGContextBeginTransparencyLayer(context, NULL);
}
}
- (void)endTransparencyLayer:(CGContextRef)context
{
if (transparent) {
CGContextEndTransparencyLayer(context);
}
}
- (void)renderTo:(CGContextRef)context - (void)renderTo:(CGContextRef)context
{ {
float opacity = self.opacity; float opacity = self.opacity;
BOOL transparent = opacity < 1;
// This needs to be painted on a layer before being composited. // This needs to be painted on a layer before being composited.
CGContextSaveGState(context); CGContextSaveGState(context);
CGContextConcatCTM(context, self.transform); CGContextConcatCTM(context, self.transform);
CGContextSetAlpha(context, opacity); CGContextSetAlpha(context, opacity);
if (transparent) { [self beginTransparencyLayer:context];
CGContextBeginTransparencyLayer(context, NULL);
}
[self renderClip:context]; [self renderClip:context];
[self renderLayerTo:context]; [self renderLayerTo:context];
[self endTransparencyLayer:context];
if (transparent) {
CGContextEndTransparencyLayer(context);
}
CGContextRestoreGState(context); CGContextRestoreGState(context);
} }