mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-04 23:54:53 +00:00
Fix hit testing when using react-native transform arrays.
This commit is contained in:
@@ -191,12 +191,13 @@ class GroupView extends RenderableView {
|
||||
|
||||
@Override
|
||||
int hitTest(final float[] src) {
|
||||
if (!mInvertible) {
|
||||
if (!mInvertible || !mTransformInvertible) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
float[] dst = new float[2];
|
||||
mInvMatrix.mapPoints(dst, src);
|
||||
mInvTransform.mapPoints(dst, src);
|
||||
|
||||
int x = Math.round(dst[0]);
|
||||
int y = Math.round(dst[1]);
|
||||
|
||||
@@ -428,12 +428,13 @@ abstract public class RenderableView extends VirtualView {
|
||||
|
||||
@Override
|
||||
int hitTest(final float[] src) {
|
||||
if (mPath == null || !mInvertible) {
|
||||
if (mPath == null || !mInvertible || !mTransformInvertible) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
float[] dst = new float[2];
|
||||
mInvMatrix.mapPoints(dst, src);
|
||||
mInvTransform.mapPoints(dst, src);
|
||||
int x = Math.round(dst[0]);
|
||||
int y = Math.round(dst[1]);
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
package com.horcrux.svg;
|
||||
|
||||
import android.graphics.Matrix;
|
||||
import android.view.View;
|
||||
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
@@ -990,8 +991,10 @@ class RenderableViewManager extends ViewGroupManager<VirtualView> {
|
||||
resetTransformProperty(node);
|
||||
} else {
|
||||
setTransformProperty(node, matrix);
|
||||
node.mTransform = node.getMatrix();
|
||||
}
|
||||
Matrix m = node.getMatrix();
|
||||
node.mTransform = m;
|
||||
node.mTransformInvertible = m.invert(node.mInvTransform);
|
||||
}
|
||||
|
||||
@ReactProp(name = "propList")
|
||||
|
||||
@@ -971,12 +971,13 @@ class TSpanView extends TextView {
|
||||
if (mContent == null) {
|
||||
return super.hitTest(src);
|
||||
}
|
||||
if (mPath == null || !mInvertible) {
|
||||
if (mPath == null || !mInvertible || !mTransformInvertible) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
float[] dst = new float[2];
|
||||
mInvMatrix.mapPoints(dst, src);
|
||||
mInvTransform.mapPoints(dst, src);
|
||||
int x = Math.round(dst[0]);
|
||||
int y = Math.round(dst[1]);
|
||||
|
||||
|
||||
@@ -81,12 +81,13 @@ class UseView extends RenderableView {
|
||||
|
||||
@Override
|
||||
int hitTest(float[] src) {
|
||||
if (!mInvertible) {
|
||||
if (!mInvertible || !mTransformInvertible) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
float[] dst = new float[2];
|
||||
mInvMatrix.mapPoints(dst, src);
|
||||
mInvTransform.mapPoints(dst, src);
|
||||
|
||||
VirtualView template = getSvgView().getDefinedTemplate(mHref);
|
||||
int hitChild = template.hitTest(dst);
|
||||
|
||||
@@ -62,7 +62,9 @@ abstract public class VirtualView extends ViewGroup {
|
||||
Matrix mMatrix = new Matrix();
|
||||
Matrix mTransform = new Matrix();
|
||||
Matrix mInvMatrix = new Matrix();
|
||||
Matrix mInvTransform = new Matrix();
|
||||
boolean mInvertible = true;
|
||||
boolean mTransformInvertible = true;
|
||||
private RectF mClientRect;
|
||||
|
||||
private int mClipRule;
|
||||
|
||||
@@ -81,8 +81,7 @@
|
||||
{
|
||||
CGRect clipBounds = CGContextGetClipBoundingBox(context);
|
||||
clipBounds = CGRectApplyAffineTransform(clipBounds, self.matrix);
|
||||
CGAffineTransform transform = CATransform3DGetAffineTransform(self.layer.transform);
|
||||
clipBounds = CGRectApplyAffineTransform(clipBounds, transform);
|
||||
clipBounds = CGRectApplyAffineTransform(clipBounds, self.transform);
|
||||
CGFloat width = CGRectGetWidth(clipBounds);
|
||||
CGFloat height = CGRectGetHeight(clipBounds);
|
||||
|
||||
@@ -128,6 +127,7 @@
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
|
||||
transformed = CGPointApplyAffineTransform(transformed, self.invTransform);
|
||||
|
||||
if (self.clipPath) {
|
||||
RNSVGClipPath *clipNode = (RNSVGClipPath*)[self.svgView getDefinedClipPath:self.clipPath];
|
||||
|
||||
+21
-22
@@ -211,30 +211,29 @@
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
CGPoint transformed = point;
|
||||
if (self.align) {
|
||||
CGPoint transformed = CGPointApplyAffineTransform(point, _invviewBoxTransform);
|
||||
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:transformed withEvent:event];
|
||||
|
||||
if (hitChild) {
|
||||
node.active = YES;
|
||||
return (node.responsible || (node != hitChild)) ? hitChild : self;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
} else {
|
||||
return [super hitTest:point withEvent:event];
|
||||
transformed = CGPointApplyAffineTransform(transformed, _invviewBoxTransform);
|
||||
}
|
||||
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:transformed withEvent:event];
|
||||
|
||||
if (hitChild) {
|
||||
node.active = YES;
|
||||
return (node.responsible || (node != hitChild)) ? hitChild : self;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -73,7 +73,8 @@
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
||||
const CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
|
||||
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
|
||||
transformed = CGPointApplyAffineTransform(transformed, self.invTransform);
|
||||
RNSVGNode const* template = [self.svgView getDefinedTemplate:self.href];
|
||||
if (event) {
|
||||
self.active = NO;
|
||||
|
||||
@@ -34,6 +34,7 @@ extern CGFloat const RNSVG_DEFAULT_FONT_SIZE;
|
||||
@property (nonatomic, assign) BOOL responsible;
|
||||
@property (nonatomic, assign) CGAffineTransform matrix;
|
||||
@property (nonatomic, assign) CGAffineTransform invmatrix;
|
||||
@property (nonatomic, assign) CGAffineTransform invTransform;
|
||||
@property (nonatomic, assign) BOOL active;
|
||||
@property (nonatomic, assign) CGPathRef path;
|
||||
@property (nonatomic, assign) CGRect clientRect;
|
||||
|
||||
@@ -35,6 +35,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
|
||||
{
|
||||
if (self = [super init]) {
|
||||
self.opacity = 1;
|
||||
self.invTransform = CGAffineTransformIdentity;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -169,8 +169,7 @@ UInt32 saturate(CGFloat value) {
|
||||
// This needs to be painted on a layer before being composited.
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, self.matrix);
|
||||
CGAffineTransform transform = CATransform3DGetAffineTransform(self.layer.transform);
|
||||
CGContextConcatCTM(context, transform);
|
||||
CGContextConcatCTM(context, self.transform);
|
||||
CGContextSetAlpha(context, self.opacity);
|
||||
|
||||
[self beginTransparencyLayer:context];
|
||||
@@ -421,6 +420,7 @@ UInt32 saturate(CGFloat value) {
|
||||
}
|
||||
|
||||
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
|
||||
transformed = CGPointApplyAffineTransform(transformed, self.invTransform);
|
||||
|
||||
BOOL evenodd = self.fillRule == kRNSVGCGFCRuleEvenodd;
|
||||
if (!CGPathContainsPoint(_hitArea, nil, transformed, evenodd) &&
|
||||
|
||||
@@ -156,9 +156,10 @@ RCT_EXPORT_VIEW_PROPERTY(opacity, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(matrix, CGAffineTransform)
|
||||
RCT_CUSTOM_VIEW_PROPERTY(transform, CATransform3D, RNSVGNode)
|
||||
{
|
||||
view.layer.transform = json ? [RNSVGNodeManager CATransform3D:json] : defaultView.layer.transform;
|
||||
// TODO: Improve this by enabling edge antialiasing only for transforms with rotation or skewing
|
||||
view.layer.allowsEdgeAntialiasing = !CATransform3DIsIdentity(view.layer.transform);
|
||||
CATransform3D transform3d = json ? [RNSVGNodeManager CATransform3D:json] : defaultView.layer.transform;
|
||||
CGAffineTransform transform = CATransform3DGetAffineTransform(transform3d);
|
||||
view.invTransform = CGAffineTransformInvert(transform);
|
||||
view.transform = transform;
|
||||
[view invalidate];
|
||||
}
|
||||
RCT_EXPORT_VIEW_PROPERTY(mask, NSString)
|
||||
|
||||
Reference in New Issue
Block a user