save clipPath into svg instance

This commit is contained in:
Horcrux
2016-05-21 17:02:46 +08:00
parent 404bdf3782
commit bb9380b049
4 changed files with 38 additions and 27 deletions

View File

@@ -35,28 +35,29 @@ public class RNSVGGroupShadowNode extends RNSVGVirtualNode {
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) {
int count = saveAndSetupCanvas(canvas);
clip(canvas, paint);
RNSVGSvgViewShadowNode svg = getSvgShadowNode(); RNSVGSvgViewShadowNode svg = getSvgShadowNode();
if (mAsClipPath == null) { if (mAsClipPath == null) {
if (opacity > MIN_OPACITY_FOR_DRAW) {
int count = saveAndSetupCanvas(canvas);
clip(canvas, paint);
for (int i = 0; i < getChildCount(); i++) { for (int i = 0; i < getChildCount(); i++) {
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i); RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
child.setupDimensions(canvas); child.setupDimensions(canvas);
child.draw(canvas, paint, opacity); child.draw(canvas, paint, opacity);
//child.markUpdateSeen();
if (child.isTouchable()) { if (child.isTouchable()) {
svg.enableTouchEvents(); svg.enableTouchEvents();
} }
} }
} else {
defineClipPath(getPath(canvas, paint), mAsClipPath);
}
restoreCanvas(canvas, count); restoreCanvas(canvas, count);
} }
} else {
svg.defineClipPath(getPath(canvas, paint), mAsClipPath);
}
} }
@Override @Override

View File

@@ -13,6 +13,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point; import android.graphics.Point;
import android.util.Log; import android.util.Log;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -20,6 +21,9 @@ import android.view.ViewGroup;
import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.UIViewOperationQueue; import com.facebook.react.uimanager.UIViewOperationQueue;
import java.util.HashMap;
import java.util.Map;
/** /**
* Shadow node for RNSVG virtual tree root - RNSVGSvgView * Shadow node for RNSVG virtual tree root - RNSVGSvgView
*/ */
@@ -29,6 +33,8 @@ public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
private boolean mTouchable = false; private boolean mTouchable = false;
private static final Map<String, Path> mDefinedClipPaths = new HashMap<>();
@Override @Override
public void onCollectExtraUpdates(UIViewOperationQueue uiUpdater) { public void onCollectExtraUpdates(UIViewOperationQueue uiUpdater) {
super.onCollectExtraUpdates(uiUpdater); super.onCollectExtraUpdates(uiUpdater);
@@ -53,7 +59,6 @@ public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i); RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
child.setupDimensions(canvas); child.setupDimensions(canvas);
child.draw(canvas, paint, 1f); child.draw(canvas, paint, 1f);
//child.markUpdateSeen();
if (child.isTouchable() && !mTouchable) { if (child.isTouchable() && !mTouchable) {
mTouchable = true; mTouchable = true;
@@ -84,6 +89,19 @@ public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
return viewTag; return viewTag;
} }
public void defineClipPath(Path clipPath, String clipPathId) {
mDefinedClipPaths.put(clipPathId, clipPath);
}
// TODO: remove unmounted clipPath
public void removeClipPath(String clipPathId) {
mDefinedClipPaths.remove(clipPathId);
}
public Path getDefinedClipPath(String clipPathId) {
return mDefinedClipPaths.get(clipPathId);
}
public void increaseCounter() { public void increaseCounter() {
mCounter++; mCounter++;
} }

View File

@@ -39,7 +39,6 @@ import java.util.Map;
* indirectly for {@link RNSVGTextShadowNode}. * indirectly for {@link RNSVGTextShadowNode}.
*/ */
public abstract class RNSVGVirtualNode extends LayoutShadowNode { public abstract class RNSVGVirtualNode extends LayoutShadowNode {
private static final Map<String, Path> CLIP_PATHS = new HashMap<>();
protected static final float MIN_OPACITY_FOR_DRAW = 0.01f; protected static final float MIN_OPACITY_FOR_DRAW = 0.01f;
@@ -48,7 +47,6 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
protected float mOpacity = 1f; protected float mOpacity = 1f;
protected @Nullable Matrix mMatrix = new Matrix(); protected @Nullable Matrix mMatrix = new Matrix();
private @Nullable String mDefinedClipPathId;
protected @Nullable Path mClipPath; protected @Nullable Path mClipPath;
protected @Nullable String mClipPathId; protected @Nullable String mClipPathId;
private static final int PATH_TYPE_ARC = 4; private static final int PATH_TYPE_ARC = 4;
@@ -68,6 +66,8 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
protected int mWidth; protected int mWidth;
protected int mHeight; protected int mHeight;
private RNSVGSvgViewShadowNode mSvgShadowNode;
public RNSVGVirtualNode() { public RNSVGVirtualNode() {
mScale = DisplayMetricsHolder.getWindowDisplayMetrics().density; mScale = DisplayMetricsHolder.getWindowDisplayMetrics().density;
} }
@@ -267,7 +267,7 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
protected void clip(Canvas canvas, Paint paint) { protected void clip(Canvas canvas, Paint paint) {
Path clip = mClipPath; Path clip = mClipPath;
if (clip == null && mClipPathId != null) { if (clip == null && mClipPathId != null) {
clip = CLIP_PATHS.get(mClipPathId); clip = getSvgShadowNode().getDefinedClipPath(mClipPathId);
} }
if (clip != null) { if (clip != null) {
@@ -278,11 +278,6 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
abstract public int hitTest(Point point, View view); abstract public int hitTest(Point point, View view);
protected void defineClipPath(Path clipPath, String clipPathId) {
CLIP_PATHS.put(clipPathId, clipPath);
mDefinedClipPathId = clipPathId;
}
public boolean isTouchable() { public boolean isTouchable() {
return mTouchable; return mTouchable;
} }
@@ -290,6 +285,10 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
abstract protected Path getPath(Canvas canvas, Paint paint); abstract protected Path getPath(Canvas canvas, Paint paint);
protected RNSVGSvgViewShadowNode getSvgShadowNode() { protected RNSVGSvgViewShadowNode getSvgShadowNode() {
if (mSvgShadowNode != null) {
return mSvgShadowNode;
}
ReactShadowNode parent = getParent(); ReactShadowNode parent = getParent();
while (!(parent instanceof RNSVGSvgViewShadowNode)) { while (!(parent instanceof RNSVGSvgViewShadowNode)) {
@@ -299,18 +298,12 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
parent = parent.getParent(); parent = parent.getParent();
} }
} }
return (RNSVGSvgViewShadowNode)parent; mSvgShadowNode = (RNSVGSvgViewShadowNode) parent;
return mSvgShadowNode;
} }
protected void setupDimensions(Canvas canvas) { protected void setupDimensions(Canvas canvas) {
mWidth = canvas.getWidth(); mWidth = canvas.getWidth();
mHeight = canvas.getHeight(); mHeight = canvas.getHeight();
} }
protected void finalize() {
if (mDefinedClipPathId != null) {
CLIP_PATHS.remove(mDefinedClipPathId);
}
}
} }

View File

@@ -29,7 +29,6 @@ class ClipPath extends Component{
return <NativeGroup return <NativeGroup
asClipPath={this.id} asClipPath={this.id}
opacity={1}
>{this.props.children}</NativeGroup>; >{this.props.children}</NativeGroup>;
} }
} }