Add G touch events on Android

This commit is contained in:
Horcrux
2016-08-01 13:38:46 +08:00
parent 6c7c2fdf3f
commit 5482a667ca
7 changed files with 88 additions and 36 deletions

View File

@@ -6,7 +6,8 @@ import Svg, {
Circle, Circle,
Path, Path,
Rect, Rect,
G G,
Text
} from 'react-native-svg'; } from 'react-native-svg';
class PressExample extends Component { class PressExample extends Component {
@@ -63,19 +64,28 @@ class HoverExample extends Component {
delayPressIn={0} delayPressIn={0}
onPressIn={this.toggle} onPressIn={this.toggle}
onPressOut={this.toggle} onPressOut={this.toggle}
x="20"
y="10"
scale="0.75"
/> />
</Svg>; </Svg>;
} }
} }
class GroupExample extends Component { class GroupExample extends Component {
static title = 'Bind touch events callback on Group element'; static title = 'Bind touch events callback on Group element with viewBox';
render () { render () {
return <Svg height="120" width="120"> return <Svg
height="120"
width="120"
viewBox="0 0 240 240"
preserveAspectRatio="none"
>
<G onPress={() => alert('Pressed')}> <G onPress={() => alert('Pressed')}>
<Rect x="20" y="20" width="40" height="40" fill="yellow" /> <Rect x="20" y="20" width="40" height="40" fill="yellow"/>
<Circle cx="80" cy="80" r="30" fill="green" /> <Circle cx="80" cy="80" r="30" fill="green"/>
<Text fontWeight="bold" fontSize="40" x="100" y="100">H</Text>
</G> </G>
</Svg>; </Svg>;
} }

View File

@@ -10,6 +10,7 @@
package com.horcrux.svg; package com.horcrux.svg;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.Point; import android.graphics.Point;
@@ -29,17 +30,27 @@ public class RNSVGDefinitionShadowNode extends RNSVGVirtualNode {
return false; return false;
} }
@Override
protected Path getPath(Canvas canvas, Paint paint) { protected Path getPath(Canvas canvas, Paint paint) {
return null; return null;
} }
@Override
public int hitTest(Point point, View view, Matrix matrix) {
return -1;
}
@Override
public int hitTest(Point point, View view) { public int hitTest(Point point, View view) {
return -1; return -1;
} }
@Override
public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList, boolean inherited) {} public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList, boolean inherited) {}
@Override
public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList) {} public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList) {}
@Override
public void resetProperties() {} public void resetProperties() {}
} }

View File

@@ -10,6 +10,7 @@
package com.horcrux.svg; package com.horcrux.svg;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.Point; import android.graphics.Point;
@@ -18,6 +19,11 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.uimanager.ReactShadowNode;
import java.security.PublicKey;
import javax.annotation.Nullable;
/** /**
* Shadow node for virtual RNSVGGroup view * Shadow node for virtual RNSVGGroup view
@@ -67,22 +73,38 @@ public class RNSVGGroupShadowNode extends RNSVGPathShadowNode {
} }
@Override @Override
public int hitTest(Point point, View view) { public int hitTest(Point point, View view, @Nullable Matrix matrix) {
int viewTag = -1; int viewTag = -1;
Matrix combinedMatrix = new Matrix();
if (matrix != null) {
combinedMatrix.postConcat(matrix);
}
combinedMatrix.postConcat(mMatrix);
for (int i = getChildCount() - 1; i >= 0; i--) { for (int i = getChildCount() - 1; i >= 0; i--) {
if (!(getChildAt(i) instanceof RNSVGVirtualNode)) { ReactShadowNode child = getChildAt(i);
if (!(child instanceof RNSVGVirtualNode)) {
continue; continue;
} }
viewTag = ((RNSVGVirtualNode) getChildAt(i)).hitTest(point, ((ViewGroup) view).getChildAt(i)); RNSVGVirtualNode node = (RNSVGVirtualNode) child;
viewTag = node.hitTest(point, ((ViewGroup) view).getChildAt(i), combinedMatrix);
if (viewTag != -1) { if (viewTag != -1) {
break; return node.isResponsible() ? viewTag : view.getId();
} }
} }
return viewTag; return viewTag;
} }
@Override
public int hitTest(Point point, View view) {
return this.hitTest(point, view, null);
}
protected void saveDefinition() { protected void saveDefinition() {
if (mName != null) { if (mName != null) {
getSvgShadowNode().defineTemplate(this, mName); getSvgShadowNode().defineTemplate(this, mName);

View File

@@ -14,6 +14,7 @@ import javax.annotation.Nullable;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.DashPathEffect; import android.graphics.DashPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.Point; import android.graphics.Point;
@@ -326,24 +327,25 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
} }
@Override @Override
public int hitTest(Point point, View view) { public int hitTest(Point point, View view, @Nullable Matrix matrix) {
Bitmap bitmap = Bitmap.createBitmap( Bitmap bitmap = Bitmap.createBitmap(
mCanvasWidth, mCanvasWidth,
mCanvasHeight, mCanvasHeight,
Bitmap.Config.ARGB_8888); Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap); Canvas canvas = new Canvas(bitmap);
if (mMatrix != null) {
canvas.concat(mMatrix); if (matrix != null) {
canvas.concat(matrix);
} }
canvas.concat(mMatrix);
Paint paint = new Paint(); Paint paint = new Paint();
clip(canvas, paint); clip(canvas, paint);
setHitTestFill(paint); setHitTestFill(paint);
canvas.drawPath(mPath, paint); canvas.drawPath(mPath, paint);
if (setHitTestStroke(paint)) { if (setHitTestStroke(paint)) {
canvas.drawPath(mPath, paint); canvas.drawPath(mPath, paint);
} }
@@ -361,6 +363,11 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
return -1; return -1;
} }
@Override
public int hitTest(Point point, View view) {
return this.hitTest(point, view, null);
}
protected void setHitTestFill(Paint paint) { protected void setHitTestFill(Paint paint) {
paint.reset(); paint.reset();
paint.setARGB(255, 0, 0, 0); paint.setARGB(255, 0, 0, 0);

View File

@@ -49,7 +49,7 @@ public class RNSVGTextShadowNode extends RNSVGPathShadowNode {
private @Nullable ReadableMap mFrame; private @Nullable ReadableMap mFrame;
private int mTextAlignment = TEXT_ALIGNMENT_LEFT; private int mTextAlignment = TEXT_ALIGNMENT_LEFT;
private Path mPath; private Path mTextPath;
@ReactProp(name = "frame") @ReactProp(name = "frame")
public void setFrame(@Nullable ReadableMap frame) { public void setFrame(@Nullable ReadableMap frame) {
@@ -64,14 +64,13 @@ public class RNSVGTextShadowNode extends RNSVGPathShadowNode {
@ReactProp(name = "path") @ReactProp(name = "path")
public void setPath(@Nullable ReadableArray textPath) { public void setPath(@Nullable ReadableArray textPath) {
float[] pathData = PropHelper.toFloatArray(textPath); float[] pathData = PropHelper.toFloatArray(textPath);
mPath = new Path(); mTextPath = new Path();
super.createPath(pathData, mPath); super.createPath(pathData, mTextPath);
markUpdated(); markUpdated();
} }
@Override @Override
public void draw(Canvas canvas, Paint paint, float opacity) { public void draw(Canvas canvas, Paint paint, float opacity) {
opacity *= mOpacity; opacity *= mOpacity;
if (opacity > MIN_OPACITY_FOR_DRAW) { if (opacity > MIN_OPACITY_FOR_DRAW) {
String text = formatText(); String text = formatText();
@@ -99,13 +98,13 @@ public class RNSVGTextShadowNode extends RNSVGPathShadowNode {
private void drawText(Canvas canvas, Paint paint, String text) { private void drawText(Canvas canvas, Paint paint, String text) {
applyTextPropertiesToPaint(paint); applyTextPropertiesToPaint(paint);
if (mPath == null) { if (mTextPath == null) {
canvas.drawText(text, 0, -paint.ascent(), paint); canvas.drawText(text, 0, -paint.ascent(), paint);
} else { } else {
Matrix matrix = new Matrix(); Matrix matrix = new Matrix();
matrix.setTranslate(0, -paint.getTextSize() * 1.1f); matrix.setTranslate(0, -paint.getTextSize() * 1.1f);
mPath.transform(matrix); mTextPath.transform(matrix);
canvas.drawTextOnPath(text, mPath, 0, -paint.ascent(), paint); canvas.drawTextOnPath(text, mTextPath, 0, -paint.ascent(), paint);
} }
} }
@@ -175,7 +174,6 @@ public class RNSVGTextShadowNode extends RNSVGPathShadowNode {
} }
} }
@Override @Override
protected Path getPath(Canvas canvas, Paint paint) { protected Path getPath(Canvas canvas, Paint paint) {
Path path = new Path(); Path path = new Path();
@@ -196,17 +194,20 @@ public class RNSVGTextShadowNode extends RNSVGPathShadowNode {
} }
@Override @Override
public int hitTest(Point point, View view) { public int hitTest(Point point, View view, @Nullable Matrix matrix) {
Bitmap bitmap = Bitmap.createBitmap( Bitmap bitmap = Bitmap.createBitmap(
mCanvasWidth, mCanvasWidth,
mCanvasHeight, mCanvasHeight,
Bitmap.Config.ARGB_8888); Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap); Canvas canvas = new Canvas(bitmap);
if (mMatrix != null) {
canvas.concat(mMatrix); if (matrix != null) {
canvas.concat(matrix);
} }
canvas.concat(mMatrix);
String text = formatText(); String text = formatText();
if (text == null) { if (text == null) {
return -1; return -1;
@@ -233,4 +234,10 @@ public class RNSVGTextShadowNode extends RNSVGPathShadowNode {
} }
return -1; return -1;
} }
@Override
public int hitTest(Point point, View view) {
return this.hitTest(point, view, null);
}
} }

View File

@@ -11,7 +11,6 @@ package com.horcrux.svg;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.util.Log;
import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;
@@ -160,8 +159,8 @@ public class RNSVGViewBoxShadowNode extends RNSVGGroupShadowNode {
} }
canvas.scale(scaleX, scaleY); mMatrix.postScale(scaleX, scaleY);
canvas.translate(-translateX * (mFromSymbol ? scaleX : 1), -translateY * (mFromSymbol ? scaleY : 1)); mMatrix.postTranslate(-translateX * (mFromSymbol ? scaleX : 1), -translateY * (mFromSymbol ? scaleY : 1));
super.draw(canvas, paint, opacity); super.draw(canvas, paint, opacity);
} }

View File

@@ -38,7 +38,7 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
private static final float[] sMatrixData = new float[9]; private static final float[] sMatrixData = new float[9];
private static final float[] sRawMatrix = new float[9]; private static final float[] sRawMatrix = new float[9];
protected float mOpacity = 1f; protected float mOpacity = 1f;
protected @Nullable Matrix mMatrix = new Matrix(); protected Matrix mMatrix = new Matrix();
protected @Nullable Path mClipPath; protected @Nullable Path mClipPath;
protected @Nullable String mClipPathRef; protected @Nullable String mClipPathRef;
@@ -80,10 +80,7 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
*/ */
protected final int saveAndSetupCanvas(Canvas canvas) { protected final int saveAndSetupCanvas(Canvas canvas) {
final int count = canvas.save(); final int count = canvas.save();
if (mMatrix != null) {
canvas.concat(mMatrix); canvas.concat(mMatrix);
}
return count; return count;
} }
@@ -181,9 +178,6 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
sRawMatrix[6] = 0; sRawMatrix[6] = 0;
sRawMatrix[7] = 0; sRawMatrix[7] = 0;
sRawMatrix[8] = 1; sRawMatrix[8] = 1;
if (mMatrix == null) {
mMatrix = new Matrix();
}
mMatrix.setValues(sRawMatrix); mMatrix.setValues(sRawMatrix);
} }
@@ -255,6 +249,8 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
} }
} }
abstract public int hitTest(Point point, View view, @Nullable Matrix matrix);
abstract public int hitTest(Point point, View view); abstract public int hitTest(Point point, View view);
public boolean isResponsible() { public boolean isResponsible() {