fix: marker onPress & gestures

This commit is contained in:
Mikael Sand
2019-10-03 16:49:56 +03:00
parent 0c127dc6bc
commit bff92f0bdf
8 changed files with 63 additions and 28 deletions
@@ -37,6 +37,8 @@ class MarkerView extends GroupView {
String mAlign;
int mMeetOrSlice;
Matrix markerTransform = new Matrix();
public MarkerView(ReactContext reactContext) {
super(reactContext);
}
@@ -130,21 +132,19 @@ class MarkerView extends GroupView {
void renderMarker(Canvas canvas, Paint paint, float opacity, RNSVGMarkerPosition position, float strokeWidth) {
int count = saveAndSetupCanvas(canvas, mCTM);
markerTransform.reset();
Point origin = position.origin;
Matrix transform = new Matrix();
transform.setTranslate((float)origin.x * mScale, (float)origin.y * mScale);
markerTransform.setTranslate((float)origin.x * mScale, (float)origin.y * mScale);
double markerAngle = "auto".equals(mOrient) ? -1 : Double.parseDouble(mOrient);
float degrees = 180 + (float) (markerAngle == -1 ? position.angle : markerAngle);
transform.preRotate(degrees);
markerTransform.preRotate(degrees);
boolean useStrokeWidth = "strokeWidth".equals(mMarkerUnits);
if (useStrokeWidth) {
transform.preScale(strokeWidth, strokeWidth);
markerTransform.preScale(strokeWidth, strokeWidth);
}
canvas.concat(transform);
double width = relativeOnWidth(mMarkerWidth) / mScale;
double height = relativeOnHeight(mMarkerHeight) / mScale;
RectF eRect = new RectF(0, 0, (float)width, (float)height);
@@ -153,12 +153,14 @@ class MarkerView extends GroupView {
Matrix viewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mAlign, mMeetOrSlice);
float[] values = new float[9];
viewBoxMatrix.getValues(values);
canvas.scale(values[Matrix.MSCALE_X], values[Matrix.MSCALE_Y]);
markerTransform.preScale(values[Matrix.MSCALE_X], values[Matrix.MSCALE_Y]);
}
double x = relativeOnWidth(mRefX);
double y = relativeOnHeight(mRefY);
canvas.translate((float)-x, (float)-y);
markerTransform.preTranslate((float)-x, (float)-y);
canvas.concat(markerTransform);
drawGroup(canvas, paint, opacity);
@@ -12,6 +12,7 @@ package com.horcrux.svg;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
@@ -382,24 +383,29 @@ abstract public class RenderableView extends VirtualView {
contextElement = this;
ArrayList<RNSVGMarkerPosition> positions = RNSVGMarkerPosition.fromPath(elements);
float width = (float)(this.strokeWidth != null ? relativeOnOther(this.strokeWidth) : 1);
mMarkerPath = new Path();
for (RNSVGMarkerPosition position : positions) {
RNSVGMarkerType type = position.type;
MarkerView marker = null;
switch (type) {
case kStartMarker:
if (markerStart != null) markerStart.renderMarker(canvas, paint, opacity, position, width);
marker = markerStart;
break;
case kMidMarker:
if (markerMid != null) markerMid.renderMarker(canvas, paint, opacity, position, width);
marker = markerMid;
break;
case kEndMarker:
if (markerEnd != null) markerEnd.renderMarker(canvas, paint, opacity, position, width);
break;
default:
marker = markerEnd;
break;
}
if (marker == null) {
continue;
}
marker.renderMarker(canvas, paint, opacity, position, width);
Matrix transform = marker.markerTransform;
mMarkerPath.addPath(marker.getPath(canvas, paint), transform);
}
contextElement = null;
}
@@ -520,9 +526,13 @@ abstract public class RenderableView extends VirtualView {
if (mStrokeRegion == null && mStrokePath != null) {
mStrokeRegion = getRegion(mStrokePath);
}
if (mMarkerRegion == null && mMarkerPath != null) {
mMarkerRegion = getRegion(mMarkerPath);
}
if (
(mRegion == null || !mRegion.contains(x, y)) &&
(mStrokeRegion == null || !mStrokeRegion.contains(x, y))
(mStrokeRegion == null || !mStrokeRegion.contains(x, y) &&
(mMarkerRegion == null || !mMarkerRegion.contains(x, y)))
) {
return -1;
}
@@ -91,8 +91,10 @@ abstract public class VirtualView extends ReactViewGroup {
Path mPath;
Path mFillPath;
Path mStrokePath;
Path mMarkerPath;
RectF mBox;
Region mRegion;
Region mMarkerRegion;
Region mStrokeRegion;
Region mClipRegion;
Path mClipRegionPath;
@@ -114,6 +116,7 @@ abstract public class VirtualView extends ReactViewGroup {
canvasWidth = -1;
fontSize = -1;
mStrokeRegion = null;
mMarkerRegion = null;
mRegion = null;
mPath = null;
}
+1
View File
@@ -140,6 +140,7 @@
if ([node isKindOfClass:[RNSVGNode class]] && ![node isKindOfClass:[RNSVGMask class]]) {
CGAffineTransform transform = CGAffineTransformConcat(node.matrix, node.transforms);
CGPathAddPath(path, &transform, [node getPath:context]);
CGPathAddPath(path, &transform, [node markerPath]);
node.dirty = false;
}
return YES;
+5 -4
View File
@@ -173,8 +173,6 @@ double deg2rad(CGFloat deg) {
transform = CGAffineTransformScale(transform, strokeWidth, strokeWidth);
}
CGContextConcatCTM(context, transform);
CGFloat width = [self relativeOnWidth:self.markerWidth];
CGFloat height = [self relativeOnHeight:self.markerHeight];
CGRect eRect = CGRectMake(0, 0, width, height);
@@ -183,12 +181,15 @@ double deg2rad(CGFloat deg) {
eRect:eRect
align:self.align
meetOrSlice:self.meetOrSlice];
CGContextScaleCTM(context, viewBoxTransform.a, viewBoxTransform.d);
transform = CGAffineTransformScale(transform, viewBoxTransform.a, viewBoxTransform.d);
}
CGFloat x = [self relativeOnWidth:self.refX];
CGFloat y = [self relativeOnHeight:self.refY];
CGContextTranslateCTM(context, -x, -y);
transform = CGAffineTransformTranslate(transform, -x, -y);
self.transform = transform;
CGContextConcatCTM(context, transform);
[self renderGroupTo:context rect:eRect];
+2
View File
@@ -45,8 +45,10 @@ extern CGFloat const RNSVG_DEFAULT_FONT_SIZE;
@property (nonatomic, assign) BOOL skip;
@property (nonatomic, assign) CGPathRef path;
@property (nonatomic, assign) CGPathRef strokePath;
@property (nonatomic, assign) CGPathRef markerPath;
@property (nonatomic, assign) CGRect clientRect;
@property (nonatomic, assign) CGRect pathBounds;
@property (nonatomic, assign) CGRect markerBounds;
@property (nonatomic, copy) RCTDirectEventBlock onLayout;
+1
View File
@@ -30,6 +30,7 @@
@property (nonatomic, assign) CGFloat strokeDashoffset;
@property (nonatomic, assign) RNSVGVectorEffect vectorEffect;
@property (nonatomic, copy) NSArray<NSString *> *propList;
@property (nonatomic, assign) CGPathRef hitArea;
- (void)setHitArea:(CGPathRef)path;
+24 -9
View File
@@ -23,7 +23,6 @@
NSArray<RNSVGLength *> *_sourceStrokeDashArray;
CGFloat *_strokeDashArrayData;
CGPathRef _srcHitPath;
CGPathRef _hitArea;
}
static RNSVGRenderable * _contextElement;
@@ -311,25 +310,39 @@ UInt32 saturate(CGFloat value) {
_contextElement = self;
NSArray<RNSVGMarkerPosition*>* positions = [RNSVGMarkerPosition fromCGPath:path];
CGFloat width = self.strokeWidth ? [self relativeOnOther:self.strokeWidth] : 1;
__block CGRect bounds = CGRectNull;
CGMutablePathRef markerPath = CGPathCreateMutable();
for (RNSVGMarkerPosition* position in positions) {
RNSVGMarkerType type = [position type];
RNSVGMarker *marker;
switch (type) {
case kStartMarker:
[markerStart renderMarker:context rect:*rect position:position strokeWidth:width];
marker = markerStart;
break;
case kMidMarker:
[markerMid renderMarker:context rect:*rect position:position strokeWidth:width];
marker = markerMid;
break;
case kEndMarker:
[markerEnd renderMarker:context rect:*rect position:position strokeWidth:width];
break;
default:
marker = markerEnd;
break;
}
if (!marker) {
continue;
}
[marker renderMarker:context rect:*rect position:position strokeWidth:width];
CGAffineTransform transform = marker.transform;
CGPathRef hitArea = marker.hitArea;
CGPathAddPath(markerPath, &transform, hitArea);
CGRect nodeRect = marker.pathBounds;
if (!CGRectIsEmpty(nodeRect)) {
bounds = CGRectUnion(bounds, CGRectApplyAffineTransform(nodeRect, transform));
}
}
self.markerBounds = bounds;
self.markerPath = markerPath;
_contextElement = nil;
}
}
@@ -513,13 +526,15 @@ UInt32 saturate(CGFloat value) {
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
transformed = CGPointApplyAffineTransform(transformed, self.invTransform);
if (!CGRectContainsPoint(self.pathBounds, transformed)) {
if (!CGRectContainsPoint(self.pathBounds, transformed) &&
!CGRectContainsPoint(self.markerBounds, transformed)) {
return nil;
}
BOOL evenodd = self.fillRule == kRNSVGCGFCRuleEvenodd;
if (!CGPathContainsPoint(_hitArea, nil, transformed, evenodd) &&
!CGPathContainsPoint(self.strokePath, nil, transformed, NO)) {
!CGPathContainsPoint(self.strokePath, nil, transformed, NO) &&
!CGPathContainsPoint(self.markerPath, nil, transformed, NO)) {
return nil;
}