From 777b3532cec7b87967aa98aed1c265ccaee5c9bc Mon Sep 17 00:00:00 2001 From: Horcrux Date: Sun, 22 Jan 2017 20:39:42 +0800 Subject: [PATCH] Fix touchEvents with viewBox prop on SVG --- .../com/horcrux/svg/SvgViewShadowNode.java | 10 ++--- ios/Elements/RNSVGSvgView.m | 44 +++++++++++++++---- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/android/src/main/java/com/horcrux/svg/SvgViewShadowNode.java b/android/src/main/java/com/horcrux/svg/SvgViewShadowNode.java index 83644fea..3ec3d0c6 100644 --- a/android/src/main/java/com/horcrux/svg/SvgViewShadowNode.java +++ b/android/src/main/java/com/horcrux/svg/SvgViewShadowNode.java @@ -17,9 +17,6 @@ import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.util.Base64; -import android.graphics.Color; -import android.graphics.PorterDuff; -import android.util.Log; import com.facebook.react.uimanager.DisplayMetricsHolder; import com.facebook.react.uimanager.LayoutShadowNode; @@ -48,6 +45,7 @@ public class SvgViewShadowNode extends LayoutShadowNode { private float mVbHeight; private String mAlign; private int mMeetOrSlice; + private Matrix mViewBoxMatrix; public SvgViewShadowNode() { mScale = DisplayMetricsHolder.getScreenDisplayMetrics().density; @@ -131,8 +129,8 @@ public class SvgViewShadowNode extends LayoutShadowNode { if (mAlign != null) { RectF vbRect = new RectF(mMinX * mScale, mMinY * mScale, (mMinX + mVbWidth) * mScale, (mMinY + mVbHeight) * mScale); RectF eRect = new RectF(0, 0, getLayoutWidth(), getLayoutHeight()); - Matrix viewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mAlign, mMeetOrSlice, false); - canvas.concat(viewBoxMatrix); + mViewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mAlign, mMeetOrSlice, false); + canvas.concat(mViewBoxMatrix); } Paint paint = new Paint(); @@ -188,7 +186,7 @@ public class SvgViewShadowNode extends LayoutShadowNode { continue; } - viewTag = ((VirtualNode) getChildAt(i)).hitTest(point); + viewTag = ((VirtualNode) getChildAt(i)).hitTest(point, mViewBoxMatrix); if (viewTag != -1) { break; } diff --git a/ios/Elements/RNSVGSvgView.m b/ios/Elements/RNSVGSvgView.m index e03556c2..81170dcf 100644 --- a/ios/Elements/RNSVGSvgView.m +++ b/ios/Elements/RNSVGSvgView.m @@ -17,6 +17,7 @@ NSMutableDictionary *templates; NSMutableDictionary *brushConverters; CGRect _boundingBox; + CGAffineTransform _viewBoxTransform; } - (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex @@ -111,12 +112,12 @@ CGContextRef context = UIGraphicsGetCurrentContext(); if (self.align) { - CGAffineTransform viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight) - eRect:rect - align:self.align - meetOrSlice:self.meetOrSlice - fromSymbol:NO]; - CGContextConcatCTM(context, viewBoxTransform); + _viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight) + eRect:rect + align:self.align + meetOrSlice:self.meetOrSlice + fromSymbol:NO]; + CGContextConcatCTM(context, _viewBoxTransform); } for (RNSVGNode *node in self.subviews) { @@ -131,12 +132,39 @@ } } +- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event +{ + if (self.align) { + for (RNSVGNode *node in [self.subviews reverseObjectEnumerator]) { + 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; + } + } + return nil; + } else { + return [super hitTest:point withEvent:event]; + } +} + + - (NSString *)getDataURL { UIGraphicsBeginImageContextWithOptions(_boundingBox.size, NO, 0); [self drawRect:_boundingBox]; - UIImage * image = UIGraphicsGetImageFromCurrentImageContext(); - NSData *imageData = UIImagePNGRepresentation(image); + NSData *imageData = UIImagePNGRepresentation(UIGraphicsGetImageFromCurrentImageContext()); NSString *base64 = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; UIGraphicsEndImageContext(); return base64;