From 37f07050e4867da33b58ece871881efdb4cd1123 Mon Sep 17 00:00:00 2001 From: Mikael Sand Date: Sat, 8 Dec 2018 23:04:53 +0200 Subject: [PATCH] [ios] Improve gesture responder and onPress/In/Out transform handling --- .../main/java/com/horcrux/svg/SvgView.java | 2 +- ios/Elements/RNSVGGroup.m | 23 +++++++++---------- ios/Elements/RNSVGSvgView.m | 6 ++++- ios/RNSVGNode.h | 1 + ios/RNSVGNode.m | 2 ++ ios/RNSVGRenderable.m | 18 +++++++++++---- ios/ViewManagers/RNSVGNodeManager.m | 3 ++- 7 files changed, 35 insertions(+), 20 deletions(-) diff --git a/android/src/main/java/com/horcrux/svg/SvgView.java b/android/src/main/java/com/horcrux/svg/SvgView.java index c8931e6a..a5af4319 100644 --- a/android/src/main/java/com/horcrux/svg/SvgView.java +++ b/android/src/main/java/com/horcrux/svg/SvgView.java @@ -91,7 +91,7 @@ public class SvgView extends ReactViewGroup implements ReactCompoundView, ReactC if (mBitmap != null) canvas.drawBitmap(mBitmap, 0, 0, null); } - + @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); diff --git a/ios/Elements/RNSVGGroup.m b/ios/Elements/RNSVGGroup.m index 418cd0bb..639d9734 100644 --- a/ios/Elements/RNSVGGroup.m +++ b/ios/Elements/RNSVGGroup.m @@ -35,7 +35,7 @@ { [self pushGlyphContext]; - __block CGRect groupRect = CGRectNull; + __block CGRect bounds = CGRectNull; [self traverseSubviews:^(UIView *node) { if ([node isKindOfClass:[RNSVGNode class]]) { @@ -52,7 +52,7 @@ CGRect nodeRect = svgNode.clientRect; if (!CGRectIsEmpty(nodeRect)) { - groupRect = CGRectUnion(groupRect, nodeRect); + bounds = CGRectUnion(bounds, nodeRect); } if ([node isKindOfClass:[RNSVGRenderable class]]) { @@ -72,16 +72,16 @@ return YES; }]; [self setHitArea:[self getPath:context]]; - self.clientRect = groupRect; + self.clientRect = bounds; - const CGAffineTransform matrix = self.matrix; - const CGAffineTransform current = CGContextGetCTM(context); - const CGAffineTransform svgToClientTransform = CGAffineTransformConcat(current, self.svgView.invInitialCTM); - const CGRect clientRect = CGRectApplyAffineTransform(groupRect, svgToClientTransform); - const CGSize clientSize = clientRect.size; + CGAffineTransform matrix = self.transform; + CGPoint mid = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds)); + CGPoint center = CGPointApplyAffineTransform(mid, matrix); + CGRect frame = CGRectApplyAffineTransform(bounds, matrix); - self.bounds = CGRectMake(0, 0, clientSize.width, clientSize.height); - self.frame = CGRectMake(matrix.tx, matrix.ty, clientSize.width, clientSize.height); + self.bounds = bounds; + self.center = center; + self.frame = frame; [self popGlyphContext]; } @@ -89,7 +89,6 @@ - (void)setupGlyphContext:(CGContextRef)context { CGRect clipBounds = CGContextGetClipBoundingBox(context); - clipBounds = CGRectApplyAffineTransform(clipBounds, self.matrix); clipBounds = CGRectApplyAffineTransform(clipBounds, self.transform); CGFloat width = CGRectGetWidth(clipBounds); CGFloat height = CGRectGetHeight(clipBounds); @@ -124,7 +123,7 @@ CGMutablePathRef __block path = CGPathCreateMutable(); [self traverseSubviews:^(RNSVGNode *node) { if ([node isKindOfClass:[RNSVGNode class]]) { - CGAffineTransform transform = node.matrix; + CGAffineTransform transform = node.transform; CGPathAddPath(path, &transform, [node getPath:context]); } return YES; diff --git a/ios/Elements/RNSVGSvgView.m b/ios/Elements/RNSVGSvgView.m index 980c7034..098f4e92 100644 --- a/ios/Elements/RNSVGSvgView.m +++ b/ios/Elements/RNSVGSvgView.m @@ -163,12 +163,16 @@ self.initialCTM = CGContextGetCTM(context); self.invInitialCTM = CGAffineTransformInvert(self.initialCTM); if (self.align) { - _viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight) + CGRect tRect = CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight); + _viewBoxTransform = [RNSVGViewBox getTransform:tRect eRect:rect align:self.align meetOrSlice:self.meetOrSlice]; _invviewBoxTransform = CGAffineTransformInvert(_viewBoxTransform); CGContextConcatCTM(context, _viewBoxTransform); + } else { + _viewBoxTransform = CGAffineTransformIdentity; + _invviewBoxTransform = CGAffineTransformIdentity; } for (UIView *node in self.subviews) { diff --git a/ios/RNSVGNode.h b/ios/RNSVGNode.h index d241078a..bb361b21 100644 --- a/ios/RNSVGNode.h +++ b/ios/RNSVGNode.h @@ -33,6 +33,7 @@ extern CGFloat const RNSVG_DEFAULT_FONT_SIZE; @property (nonatomic, strong) NSString *mask; @property (nonatomic, assign) BOOL responsible; @property (nonatomic, assign) CGAffineTransform matrix; +@property (nonatomic, assign) CGAffineTransform transforms; @property (nonatomic, assign) CGAffineTransform invmatrix; @property (nonatomic, assign) CGAffineTransform invTransform; @property (nonatomic, assign) BOOL active; diff --git a/ios/RNSVGNode.m b/ios/RNSVGNode.m index f70ceae9..b1d50eb4 100644 --- a/ios/RNSVGNode.m +++ b/ios/RNSVGNode.m @@ -36,6 +36,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12; { if (self = [super init]) { self.opacity = 1; + self.transforms = CGAffineTransformIdentity; self.invTransform = CGAffineTransformIdentity; } return self; @@ -165,6 +166,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12; } _matrix = matrix; _invmatrix = CGAffineTransformInvert(matrix); + self.transform = CGAffineTransformConcat(matrix, self.transforms); id container = (id)self.superview; [container invalidate]; } diff --git a/ios/RNSVGRenderable.m b/ios/RNSVGRenderable.m index a748af88..75d50fa5 100644 --- a/ios/RNSVGRenderable.m +++ b/ios/RNSVGRenderable.m @@ -168,7 +168,6 @@ UInt32 saturate(CGFloat value) { { // This needs to be painted on a layer before being composited. CGContextSaveGState(context); - CGContextConcatCTM(context, self.matrix); CGContextConcatCTM(context, self.transform); CGContextSetAlpha(context, self.opacity); @@ -297,15 +296,24 @@ UInt32 saturate(CGFloat value) { const CGRect pathBounding = CGPathGetBoundingBox(self.path); - const CGAffineTransform matrix = self.matrix; const CGAffineTransform current = CGContextGetCTM(context); const CGAffineTransform svgToClientTransform = CGAffineTransformConcat(current, self.svgView.invInitialCTM); const CGRect clientRect = CGRectApplyAffineTransform(pathBounding, svgToClientTransform); - const CGSize clientSize = clientRect.size; self.clientRect = clientRect; - self.bounds = CGRectMake(0, 0, clientSize.width, clientSize.height); - self.frame = CGRectMake(matrix.tx, matrix.ty, clientSize.width, clientSize.height); + + const CGAffineTransform vbmatrix = self.svgView.getViewBoxTransform; + const CGAffineTransform matrix = CGAffineTransformConcat(self.transform, vbmatrix); + + const CGRect bounds = CGRectMake(0, 0, CGRectGetWidth(clientRect), CGRectGetHeight(clientRect)); + const CGPoint mid = CGPointMake(CGRectGetMidX(pathBounding), CGRectGetMidY(pathBounding)); + CGPoint center = CGPointApplyAffineTransform(mid, matrix); + + const CGRect frame = CGRectApplyAffineTransform(pathBounding, matrix); + + self.bounds = bounds; + self.center = center; + self.frame = frame; CGPathDrawingMode mode = kCGPathStroke; BOOL fillColor = NO; diff --git a/ios/ViewManagers/RNSVGNodeManager.m b/ios/ViewManagers/RNSVGNodeManager.m index c36de86b..ebcd652a 100644 --- a/ios/ViewManagers/RNSVGNodeManager.m +++ b/ios/ViewManagers/RNSVGNodeManager.m @@ -159,7 +159,8 @@ RCT_CUSTOM_VIEW_PROPERTY(transform, CATransform3D, RNSVGNode) CATransform3D transform3d = json ? [RNSVGNodeManager CATransform3D:json] : defaultView.layer.transform; CGAffineTransform transform = CATransform3DGetAffineTransform(transform3d); view.invTransform = CGAffineTransformInvert(transform); - view.transform = transform; + view.transforms = transform; + view.transform = CGAffineTransformConcat(view.matrix, transform); [view invalidate]; } RCT_EXPORT_VIEW_PROPERTY(mask, NSString)