mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-20 14:05:09 +00:00
fix touch events within the elements which are nested in G
This commit is contained in:
@@ -56,6 +56,8 @@ class HoverExample extends Component {
|
||||
|
||||
render () {
|
||||
return <Svg height="120" width="120">
|
||||
<G>
|
||||
<G>
|
||||
<Path
|
||||
d="M50,5L20,99L95,39L5,39L80,99z"
|
||||
stroke={this.state.hover ? 'rgba(10, 10, 10, 0.5)' : 'black'}
|
||||
@@ -65,9 +67,12 @@ class HoverExample extends Component {
|
||||
onPressIn={this.toggle}
|
||||
onPressOut={this.toggle}
|
||||
x="0"
|
||||
y="10"
|
||||
scale="0.5"
|
||||
y="0"
|
||||
scale="1.2"
|
||||
opacity="0.3"
|
||||
/>
|
||||
</G>
|
||||
</G>
|
||||
</Svg>;
|
||||
}
|
||||
}
|
||||
@@ -82,12 +87,14 @@ class GroupExample extends Component {
|
||||
viewBox="0 0 240 240"
|
||||
>
|
||||
<G>
|
||||
<G onPress={() => alert('Pressed')}>
|
||||
<Circle cx="80" cy="80" r="30" fill="green" x="20" />
|
||||
<Rect x="20" y="20" width="40" height="40" fill="yellow"/>
|
||||
<G scale="1.4">
|
||||
<G>
|
||||
<Circle cx="80" cy="80" r="30" fill="green" x="20" scale="1.2" onPress={() => alert('Pressed')}/>
|
||||
<Rect x="20" y="20" width="40" height="40" fill="yellow" />
|
||||
<Text fontWeight="bold" fontSize="40" x="100" y="100" scale="2">H</Text>
|
||||
</G>
|
||||
</G>
|
||||
</G>
|
||||
</Svg>;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +73,7 @@ class Svg extends Component{
|
||||
|
||||
const nativeProps = _.omit(props, ['width', 'height', 'viewBox', 'preserveAspectRatio', 'opacity']);
|
||||
|
||||
return (
|
||||
<NativeSvgView
|
||||
return <NativeSvgView
|
||||
{...nativeProps}
|
||||
ref={ele => {this.root = ele;}}
|
||||
style={[
|
||||
@@ -87,8 +86,7 @@ class Svg extends Component{
|
||||
]}
|
||||
>
|
||||
{content}
|
||||
</NativeSvgView>
|
||||
);
|
||||
</NativeSvgView>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,4 @@
|
||||
#import "RNSVGRenderable.h"
|
||||
|
||||
@interface RNSVGGroup : RNSVGRenderable <RNSVGContainer>
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
|
||||
|
||||
@end
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
[node renderTo:context];
|
||||
|
||||
if (node.responsible && !svg.responsible) {
|
||||
self.responsible = YES;
|
||||
svg.responsible = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,21 +32,33 @@
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
for (RNSVGNode *node in self.subviews) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
CGAffineTransform transform = node.transform;
|
||||
CGAffineTransform transform = node.matrix;
|
||||
CGPathAddPath(path, &transform, [node getPath:context]);
|
||||
}
|
||||
}
|
||||
return (CGPathRef)CFAutorelease(path);
|
||||
}
|
||||
|
||||
// hitTest delagate
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event withTransform:(CGAffineTransform)transform
|
||||
{
|
||||
CGAffineTransform matrix = CGAffineTransformConcat(self.matrix, transform);
|
||||
|
||||
for (RNSVGNode *node in [self.subviews reverseObjectEnumerator]) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
UIView *view = [node hitTest: point withEvent:event];
|
||||
if (event) {
|
||||
node.active = NO;
|
||||
}
|
||||
|
||||
if (node.active) {
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
UIView *view = [node hitTest: point withEvent:event withTransform:matrix];
|
||||
|
||||
if (view) {
|
||||
if (node.responsible || node != view) {
|
||||
node.active = YES;
|
||||
if (node.responsible || (node != view)) {
|
||||
return view;
|
||||
} else {
|
||||
return self;
|
||||
|
||||
@@ -71,10 +71,7 @@
|
||||
{
|
||||
CGRect rect = [self getRect:context];
|
||||
// add hit area
|
||||
self.hitArea = CGPathCreateMutable();
|
||||
CGPathRef path = CGPathCreateWithRect(rect, nil);
|
||||
CGPathAddPath(self.hitArea, nil, path);
|
||||
CGPathRelease(path);
|
||||
self.hitArea = CGPathCreateWithRect(rect, nil);
|
||||
[self clip:context];
|
||||
|
||||
CGContextSaveGState(context);
|
||||
@@ -97,9 +94,7 @@
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGPathAddRect(path, nil, [self getRect:context]);
|
||||
return (CGPathRef)CFAutorelease(path);
|
||||
return CGPathCreateWithRect([self getRect:context], nil);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
if (d == _d) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self invalidate];
|
||||
CGPathRelease(_d);
|
||||
_d = CGPathRetain(d);
|
||||
@@ -27,20 +28,25 @@
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
if ((!self.fill && !self.stroke) || !self.d) {
|
||||
CGPathRef path = [self getPath:context];
|
||||
if ((!self.fill && !self.stroke) || !path) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add path to hitArea
|
||||
self.hitArea = CGPathCreateMutableCopy(_d);
|
||||
|
||||
CGMutablePathRef hitArea = CGPathCreateMutableCopy(path);
|
||||
if (self.stroke) {
|
||||
// Add stroke to hitArea
|
||||
CGPathRef strokePath = CGPathCreateCopyByStrokingPath(_d, nil, self.strokeWidth, self.strokeLinecap, self.strokeLinejoin, self.strokeMiterlimit);
|
||||
CGPathAddPath(self.hitArea, nil, strokePath);
|
||||
CGPathRef strokePath = CGPathCreateCopyByStrokingPath(hitArea, nil, self.strokeWidth, self.strokeLinecap, self.strokeLinejoin, self.strokeMiterlimit);
|
||||
CGPathAddPath(hitArea, nil, strokePath);
|
||||
CGPathRelease(strokePath);
|
||||
}
|
||||
|
||||
CGAffineTransform transform = self.matrix;
|
||||
self.hitArea = CGPathCreateCopyByTransformingPath(hitArea, &transform);
|
||||
|
||||
CGPathRelease(hitArea);
|
||||
|
||||
if (self.opacity == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -56,7 +62,7 @@
|
||||
[self clip:context];
|
||||
|
||||
CGContextSaveGState(context);
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextAddPath(context, path);
|
||||
CGContextClip(context);
|
||||
RNSVGBrushConverter *brushConverter = [[self getSvgView] getDefinedBrushConverter:[self.fill brushRef]];
|
||||
[self.fill paint:context opacity:self.fillOpacity brushConverter:brushConverter];
|
||||
@@ -78,7 +84,7 @@
|
||||
}
|
||||
|
||||
if (!fillColor) {
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextAddPath(context, path);
|
||||
CGContextReplacePathWithStrokedPath(context);
|
||||
CGContextClip(context);
|
||||
}
|
||||
@@ -92,11 +98,11 @@
|
||||
} else {
|
||||
// draw fill
|
||||
[self clip:context];
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextAddPath(context, path);
|
||||
CGContextDrawPath(context, mode);
|
||||
|
||||
// draw stroke
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextAddPath(context, path);
|
||||
CGContextReplacePathWithStrokedPath(context);
|
||||
CGContextClip(context);
|
||||
RNSVGBrushConverter *brushConverter = [[self getSvgView] getDefinedBrushConverter:[self.stroke brushRef]];
|
||||
@@ -106,7 +112,7 @@
|
||||
}
|
||||
|
||||
[self clip:context];
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextAddPath(context, path);
|
||||
CGContextDrawPath(context, mode);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
@property (nonatomic, strong) NSString *clipPathRef; // use clipPath="url(#clip)" as ClipPath
|
||||
@property (nonatomic, assign) BOOL responsible;
|
||||
@property (nonatomic, assign) CGAffineTransform matrix;
|
||||
@property (nonatomic, assign) BOOL active;
|
||||
|
||||
- (void)invalidate;
|
||||
|
||||
@@ -52,7 +53,7 @@
|
||||
/**
|
||||
* run hitTest
|
||||
*/
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event withTransform:(CGAffineTransform)transfrom;
|
||||
|
||||
- (RNSVGSvgView *)getSvgView;
|
||||
|
||||
|
||||
@@ -69,12 +69,6 @@
|
||||
_opacity = opacity;
|
||||
}
|
||||
|
||||
- (void)setMatrix:(CGAffineTransform)matrix
|
||||
{
|
||||
self.transform = matrix;
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
- (void)setClipPath:(CGPathRef)clipPath
|
||||
{
|
||||
if (_clipPath == clipPath) {
|
||||
@@ -147,7 +141,15 @@
|
||||
// abstract
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
|
||||
// hitTest delagate
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
|
||||
// abstract
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event withTransform:(CGAffineTransform)transfrom
|
||||
{
|
||||
// abstract
|
||||
return nil;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
@property (nonatomic, assign) CGFloat strokeMiterlimit;
|
||||
@property (nonatomic, assign) RNSVGCGFloatArray strokeDasharray;
|
||||
@property (nonatomic, assign) CGFloat strokeDashoffset;
|
||||
@property (nonatomic, assign) CGMutablePathRef hitArea;
|
||||
@property (nonatomic, assign) CGPathRef hitArea;
|
||||
@property (nonatomic, copy) NSArray<NSString *> *propList;
|
||||
|
||||
- (void)setBoundingBox:(CGContextRef)context;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setHitArea:(CGMutablePathRef)hitArea
|
||||
- (void)setHitArea:(CGPathRef)hitArea
|
||||
{
|
||||
if (hitArea == _hitArea) {
|
||||
return;
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
[self invalidate];
|
||||
CGPathRelease(_hitArea);
|
||||
_hitArea = hitArea;
|
||||
_hitArea = CGPathRetain(hitArea);
|
||||
}
|
||||
|
||||
- (void)setFill:(RNSVGBrush *)fill
|
||||
@@ -116,7 +116,7 @@
|
||||
{
|
||||
// This needs to be painted on a layer before being composited.
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, self.transform);
|
||||
CGContextConcatCTM(context, self.matrix);
|
||||
CGContextSetAlpha(context, self.opacity);
|
||||
|
||||
[self beginTransparencyLayer:context];
|
||||
@@ -130,8 +130,22 @@
|
||||
// hitTest delagate
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
return [self hitTest:point withEvent:event withTransform:CGAffineTransformMakeRotation(0)];
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event withTransform:(CGAffineTransform)transfrom
|
||||
{
|
||||
if (self.active) {
|
||||
if (!event) {
|
||||
self.active = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
CGPathRef hitArea = CGPathCreateCopyByTransformingPath(self.hitArea, &transfrom);
|
||||
CGPathRef clipPath = self.clipPath;
|
||||
if (self.hitArea && CGPathContainsPoint(self.hitArea, nil, point, NO)) {
|
||||
BOOL contains = CGPathContainsPoint(hitArea, nil, point, NO);
|
||||
if (contains) {
|
||||
if (!clipPath) {
|
||||
return self;
|
||||
} else {
|
||||
@@ -142,7 +156,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)setBoundingBox:(CGContextRef)context
|
||||
{
|
||||
_boundingBox = CGContextGetClipBoundingBox(context);
|
||||
|
||||
@@ -96,8 +96,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
self.transform = CGAffineTransformScale(self.transform, scaleX, scaleY);
|
||||
self.transform = CGAffineTransformTranslate(self.transform, -translateX * (_fromSymbol ? scaleX : 1), -translateY * (_fromSymbol ? scaleY : 1));
|
||||
self.matrix = CGAffineTransformMakeScale(scaleX, scaleY);
|
||||
self.matrix = CGAffineTransformTranslate(self.matrix, -translateX * (_fromSymbol ? scaleX : 1), -translateY * (_fromSymbol ? scaleY : 1));
|
||||
[super renderTo:context];
|
||||
}
|
||||
|
||||
|
||||
@@ -38,12 +38,6 @@
|
||||
_r = r;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
self.d = [self getPath: context];
|
||||
[super renderLayerTo:context];
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
[self setBoundingBox:context];
|
||||
|
||||
@@ -47,12 +47,6 @@
|
||||
_ry = ry;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
self.d = [self getPath: context];
|
||||
[super renderLayerTo:context];
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
[self setBoundingBox:context];
|
||||
|
||||
@@ -47,12 +47,6 @@
|
||||
_y2 = y2;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
self.d = [self getPath: context];
|
||||
[super renderLayerTo:context];
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
[self setBoundingBox:context];
|
||||
|
||||
@@ -65,12 +65,6 @@
|
||||
_ry = ry;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
self.d = [self getPath: context];
|
||||
[super renderLayerTo:context];
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
[self setBoundingBox:context];
|
||||
|
||||
@@ -53,12 +53,6 @@ static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
|
||||
RNSVGFreeTextFrame(_textFrame);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
self.d = [self getPath: context];
|
||||
[super renderLayerTo:context];
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
@@ -124,6 +118,7 @@ static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
|
||||
transform = CGAffineTransformTranslate(upsideDown, point.x, point.y);
|
||||
}
|
||||
|
||||
|
||||
CGPathAddPath(path, &transform, letter);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#define NEXT_VALUE [self double:arr[i++]]
|
||||
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGPathMoveToPoint(path, NULL, 0, 0);
|
||||
CGPathMoveToPoint(path, nil, 0, 0);
|
||||
|
||||
@try {
|
||||
NSUInteger i = 0;
|
||||
@@ -34,28 +34,28 @@
|
||||
NSUInteger type = [arr[i++] unsignedIntegerValue];
|
||||
switch (type) {
|
||||
case 0:
|
||||
CGPathMoveToPoint(path, NULL, NEXT_VALUE, NEXT_VALUE);
|
||||
CGPathMoveToPoint(path, nil, NEXT_VALUE, NEXT_VALUE);
|
||||
break;
|
||||
case 1:
|
||||
CGPathCloseSubpath(path);
|
||||
break;
|
||||
case 2:
|
||||
CGPathAddLineToPoint(path, NULL, NEXT_VALUE, NEXT_VALUE);
|
||||
CGPathAddLineToPoint(path, nil, NEXT_VALUE, NEXT_VALUE);
|
||||
break;
|
||||
case 3:
|
||||
CGPathAddCurveToPoint(path, NULL, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE);
|
||||
CGPathAddCurveToPoint(path, nil, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE);
|
||||
break;
|
||||
default:
|
||||
RCTLogError(@"Invalid CGPath type %zd at element %zd of %@", type, i, arr);
|
||||
CGPathRelease(path);
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
RCTLogError(@"Invalid CGPath format: %@", arr);
|
||||
CGPathRelease(path);
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
|
||||
return (CGPathRef)CFAutorelease(path);
|
||||
@@ -123,7 +123,7 @@ RCT_ENUM_CONVERTER(RNSVGVBMOS, (@{
|
||||
CFRelease(attrString);
|
||||
|
||||
frame.lines[i] = line;
|
||||
frame.widths[i] = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
|
||||
frame.widths[i] = CTLineGetTypographicBounds(line, nil, nil, nil);
|
||||
}];
|
||||
|
||||
return frame;
|
||||
@@ -136,7 +136,7 @@ RCT_ENUM_CONVERTER(RNSVGVBMOS, (@{
|
||||
|
||||
RNSVGCGFloatArray array;
|
||||
array.count = count;
|
||||
array.array = NULL;
|
||||
array.array = nil;
|
||||
|
||||
if (count) {
|
||||
// Ideally, these arrays should already use the same memory layout.
|
||||
@@ -213,13 +213,13 @@ RCT_ENUM_CONVERTER(RNSVGVBMOS, (@{
|
||||
break;
|
||||
default:
|
||||
RCTLogError(@"Invalid RNSVGBezier type %zd at element %zd of %@", type, i, arr);
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
RCTLogError(@"Invalid RNSVGBezier format: %@", arr);
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
|
||||
return beziers;
|
||||
@@ -256,7 +256,7 @@ RCT_ENUM_CONVERTER(RNSVGVBMOS, (@{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset + 4) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %zd): %@", 4 + offset, arr);
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
return [self CGColor:[arr subarrayWithRange:(NSRange){offset, 4}]];
|
||||
}
|
||||
@@ -266,7 +266,7 @@ RCT_ENUM_CONVERTER(RNSVGVBMOS, (@{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %zd): %@", offset, arr);
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
arr = [arr subarrayWithRange:(NSRange){offset, arr.count - offset}];
|
||||
RNSVGCGFloatArray colorsAndOffsets = [self RNSVGCGFloatArray:arr];
|
||||
|
||||
Reference in New Issue
Block a user