mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-02 14:50:43 +00:00
First attempt at nested svg support.
This commit is contained in:
@@ -19,7 +19,9 @@
|
||||
- (void)parseReference
|
||||
{
|
||||
[self traverseSubviews:^(RNSVGNode *node) {
|
||||
[node parseReference];
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
[node parseReference];
|
||||
}
|
||||
return YES;
|
||||
}];
|
||||
}
|
||||
|
||||
+27
-13
@@ -34,19 +34,29 @@
|
||||
{
|
||||
[self pushGlyphContext];
|
||||
RNSVGSvgView* svg = [self getSvgView];
|
||||
[self traverseSubviews:^(RNSVGNode *node) {
|
||||
if (node.responsible && !svg.responsible) {
|
||||
svg.responsible = YES;
|
||||
}
|
||||
[self traverseSubviews:^(UIView *node) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
RNSVGNode* svgNode = (RNSVGNode*)node;
|
||||
if (svgNode.responsible && !svg.responsible) {
|
||||
svg.responsible = YES;
|
||||
}
|
||||
|
||||
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
||||
[(RNSVGRenderable*)node mergeProperties:self];
|
||||
}
|
||||
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
||||
[(RNSVGRenderable*)node mergeProperties:self];
|
||||
}
|
||||
|
||||
[node renderTo:context];
|
||||
[svgNode renderTo:context];
|
||||
|
||||
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
||||
[(RNSVGRenderable*)node resetProperties];
|
||||
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
||||
[(RNSVGRenderable*)node resetProperties];
|
||||
}
|
||||
} else if ([node isKindOfClass:[RNSVGSvgView class]]) {
|
||||
RNSVGSvgView* svgView = (RNSVGSvgView*)node;
|
||||
CGRect rect = CGRectMake(0, 0, [svgView.bbWidth floatValue], [svgView.bbHeight floatValue]);
|
||||
CGContextClipToRect(context, rect);
|
||||
[svgView drawToContext:context withRect:(CGRect)rect];
|
||||
} else {
|
||||
RCTLogWarn(@"Not a RNSVGNode: %@", node.class);
|
||||
}
|
||||
|
||||
return YES;
|
||||
@@ -89,8 +99,10 @@
|
||||
{
|
||||
CGMutablePathRef __block path = CGPathCreateMutable();
|
||||
[self traverseSubviews:^(RNSVGNode *node) {
|
||||
CGAffineTransform transform = node.matrix;
|
||||
CGPathAddPath(path, &transform, [node getPath:context]);
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
CGAffineTransform transform = node.matrix;
|
||||
CGPathAddPath(path, &transform, [node getPath:context]);
|
||||
}
|
||||
return YES;
|
||||
}];
|
||||
|
||||
@@ -147,7 +159,9 @@
|
||||
}
|
||||
|
||||
[self traverseSubviews:^(__kindof RNSVGNode *node) {
|
||||
[node parseReference];
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
[node parseReference];
|
||||
}
|
||||
return YES;
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
@interface RNSVGSvgView : UIView <RNSVGContainer>
|
||||
|
||||
@property (nonatomic, strong) NSString *bbWidth;
|
||||
@property (nonatomic, strong) NSString *bbHeight;
|
||||
@property (nonatomic, assign) CGFloat minX;
|
||||
@property (nonatomic, assign) CGFloat minY;
|
||||
@property (nonatomic, assign) CGFloat vbWidth;
|
||||
@@ -22,6 +24,8 @@
|
||||
@property (nonatomic, strong) NSString *align;
|
||||
@property (nonatomic, assign) RNSVGVBMOS meetOrSlice;
|
||||
@property (nonatomic, assign) BOOL responsible;
|
||||
@property (nonatomic, assign) CGRect boundingBox;
|
||||
|
||||
|
||||
/**
|
||||
* define <ClipPath></ClipPath> content as clipPath template.
|
||||
@@ -42,4 +46,8 @@
|
||||
|
||||
- (CGRect)getContextBounds;
|
||||
|
||||
- (void)drawRect:(CGRect)rect;
|
||||
|
||||
- (void)drawToContext:(CGContextRef)context withRect:(CGRect)rect;
|
||||
|
||||
@end
|
||||
|
||||
+57
-29
@@ -16,7 +16,6 @@
|
||||
NSMutableDictionary<NSString *, RNSVGNode *> *_clipPaths;
|
||||
NSMutableDictionary<NSString *, RNSVGNode *> *_templates;
|
||||
NSMutableDictionary<NSString *, RNSVGPainter *> *_painters;
|
||||
CGRect _boundingBox;
|
||||
CGAffineTransform _viewBoxTransform;
|
||||
}
|
||||
|
||||
@@ -48,7 +47,7 @@
|
||||
if (minX == _minX) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self invalidate];
|
||||
_minX = minX;
|
||||
}
|
||||
@@ -58,7 +57,7 @@
|
||||
if (minY == _minY) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self invalidate];
|
||||
_minY = minY;
|
||||
}
|
||||
@@ -68,7 +67,7 @@
|
||||
if (vbWidth == _vbWidth) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self invalidate];
|
||||
_vbWidth = vbWidth;
|
||||
}
|
||||
@@ -78,17 +77,37 @@
|
||||
if (_vbHeight == vbHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self invalidate];
|
||||
_vbHeight = vbHeight;
|
||||
}
|
||||
|
||||
- (void)setBBWidth:(NSString *)bbWidth
|
||||
{
|
||||
if ([bbWidth isEqualToString:_bbWidth]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self invalidate];
|
||||
_bbWidth = bbWidth;
|
||||
}
|
||||
|
||||
- (void)setBBHeight:(NSString *)bbHeight
|
||||
{
|
||||
if ([bbHeight isEqualToString:_bbHeight]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self invalidate];
|
||||
_bbHeight = bbHeight;
|
||||
}
|
||||
|
||||
- (void)setAlign:(NSString *)align
|
||||
{
|
||||
if ([align isEqualToString:_align]) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self invalidate];
|
||||
_align = align;
|
||||
}
|
||||
@@ -98,11 +117,29 @@
|
||||
if (meetOrSlice == _meetOrSlice) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self invalidate];
|
||||
_meetOrSlice = meetOrSlice;
|
||||
}
|
||||
|
||||
- (void)drawToContext:(CGContextRef)context withRect:(CGRect)rect {
|
||||
|
||||
if (self.align) {
|
||||
_viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
|
||||
eRect:rect
|
||||
align:self.align
|
||||
meetOrSlice:self.meetOrSlice];
|
||||
CGContextConcatCTM(context, _viewBoxTransform);
|
||||
}
|
||||
|
||||
for (UIView *node in self.subviews) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
RNSVGNode *svg = (RNSVGNode *)node;
|
||||
[svg renderTo:context];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
_clipPaths = nil;
|
||||
@@ -110,30 +147,21 @@
|
||||
_painters = nil;
|
||||
_boundingBox = rect;
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
if (self.align) {
|
||||
_viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
|
||||
eRect:rect
|
||||
align:self.align
|
||||
meetOrSlice:self.meetOrSlice];
|
||||
CGContextConcatCTM(context, _viewBoxTransform);
|
||||
}
|
||||
|
||||
for (RNSVGNode *node in self.subviews) {
|
||||
|
||||
for (UIView *node in self.subviews) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
if (node.responsible && !self.responsible) {
|
||||
RNSVGNode *svg = (RNSVGNode *)node;
|
||||
if (svg.responsible && !self.responsible) {
|
||||
self.responsible = YES;
|
||||
}
|
||||
|
||||
[node parseReference];
|
||||
}
|
||||
}
|
||||
|
||||
for (RNSVGNode *node in self.subviews) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
[node renderTo:context];
|
||||
|
||||
[svg parseReference];
|
||||
} else {
|
||||
RCTLogWarn(@"Not a RNSVGNode: %@", node.class);
|
||||
}
|
||||
}
|
||||
|
||||
[self drawToContext:context withRect:rect];
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
@@ -143,15 +171,15 @@
|
||||
if (![node isKindOfClass:[RNSVGNode class]]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (event) {
|
||||
node.active = NO;
|
||||
} else if (node.active) {
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
UIView *hitChild = [node hitTest: point withEvent:event withTransform:_viewBoxTransform];
|
||||
|
||||
|
||||
if (hitChild) {
|
||||
node.active = YES;
|
||||
return (node.responsible || (node != hitChild)) ? hitChild : self;
|
||||
|
||||
+1
-1
@@ -103,6 +103,6 @@ extern CGFloat const RNSVG_DEFAULT_FONT_SIZE;
|
||||
|
||||
- (void)endTransparencyLayer:(CGContextRef)context;
|
||||
|
||||
- (void)traverseSubviews:(BOOL (^)(__kindof RNSVGNode *node))block;
|
||||
- (void)traverseSubviews:(BOOL (^)(__kindof UIView *node))block;
|
||||
|
||||
@end
|
||||
|
||||
+8
-2
@@ -310,13 +310,19 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)traverseSubviews:(BOOL (^)(__kindof RNSVGNode *node))block
|
||||
- (void)traverseSubviews:(BOOL (^)(__kindof UIView *node))block
|
||||
{
|
||||
for (RNSVGNode *node in self.subviews) {
|
||||
for (UIView *node in self.subviews) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
if (!block(node)) {
|
||||
break;
|
||||
}
|
||||
} else if ([node isKindOfClass:[RNSVGSvgView class]]) {
|
||||
if (!block(node)) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
RCTLogWarn(@"Not a RNSVGNode: %@", node.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ RCT_EXPORT_MODULE()
|
||||
return [RNSVGSvgView new];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(bbWidth, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(bbHeight, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(minX, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(minY, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(vbWidth, CGFloat)
|
||||
|
||||
Reference in New Issue
Block a user