Skip to content

Commit 857b5f5

Browse files
committed
Fix Image not rendering the first time svg is displayed
Fix Image not rendering the first time svg is displayed Add toDataURL method for Svg elements for Android (not finished yet)
1 parent 76a3e8e commit 857b5f5

File tree

6 files changed

+81
-44
lines changed

6 files changed

+81
-44
lines changed

Example/examples/Svg.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import {
22
StyleSheet,
33
View,
4-
Image,
5-
Text
4+
Image
65
} from 'react-native';
76

87
import React, {
@@ -152,6 +151,7 @@ class SvgLayout extends Component{
152151
}
153152

154153
class SvgNativeMethods extends Component {
154+
static title = 'Tap the shapes to render the Image below based on the base64-data of the Svg';
155155
constructor() {
156156
super(...arguments);
157157
this.state = {
@@ -174,7 +174,6 @@ class SvgNativeMethods extends Component {
174174
<Path d="M55.192 27.87l-5.825-1.092a17.98 17.98 0 0 0-1.392-3.37l3.37-4.928c.312-.456.248-1.142-.143-1.532l-4.155-4.156c-.39-.39-1.076-.454-1.532-.143l-4.928 3.37a18.023 18.023 0 0 0-3.473-1.42l-1.086-5.793c-.103-.543-.632-.983-1.185-.983h-5.877c-.553 0-1.082.44-1.185.983l-1.096 5.85a17.96 17.96 0 0 0-3.334 1.393l-4.866-3.33c-.456-.31-1.142-.247-1.532.144l-4.156 4.156c-.39.39-.454 1.076-.143 1.532l3.35 4.896a18.055 18.055 0 0 0-1.37 3.33L8.807 27.87c-.542.103-.982.632-.982 1.185v5.877c0 .553.44 1.082.982 1.185l5.82 1.09a18.013 18.013 0 0 0 1.4 3.4l-3.31 4.842c-.313.455-.25 1.14.142 1.53l4.155 4.157c.39.39 1.076.454 1.532.143l4.84-3.313c1.04.563 2.146 1.02 3.3 1.375l1.096 5.852c.103.542.632.982 1.185.982h5.877c.553 0 1.082-.44 1.185-.982l1.086-5.796c1.2-.354 2.354-.82 3.438-1.4l4.902 3.353c.456.313 1.142.25 1.532-.142l4.155-4.154c.39-.39.454-1.076.143-1.532l-3.335-4.874a18.016 18.016 0 0 0 1.424-3.44l5.82-1.09c.54-.104.98-.633.98-1.186v-5.877c0-.553-.44-1.082-.982-1.185zM32 42.085c-5.568 0-10.083-4.515-10.083-10.086 0-5.568 4.515-10.084 10.083-10.084 5.57 0 10.086 4.516 10.086 10.083 0 5.57-4.517 10.085-10.086 10.085z" fill="blue"/>
175175
</G>
176176
</Svg>
177-
<Text>Tap the shapes to render the Image below based on the base64-data of the Svg</Text>
178177
<Image
179178
source={{url: `data:image/png;base64,${this.state.base64}`}}
180179
style={{width:150, height: 100, borderWidth: 1, marginTop: 5}}

android/src/main/java/com/horcrux/svg/RNSVGImageShadowNode.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,9 @@ public void onNewResultImpl(@Nullable Bitmap bitmap) {
110110
paint.reset();
111111
mLoading.set(false);
112112

113-
getSvgShadowNode().drawChildren(canvas, paint);
114-
getSvgShadowNode().invalidateView(getRect());
113+
RNSVGSvgViewShadowNode svgShadowNode = getSvgShadowNode();
114+
svgShadowNode.drawChildren(canvas, paint);
115+
svgShadowNode.invalidateView();
115116
}
116117
}
117118

android/src/main/java/com/horcrux/svg/RNSVGSvgView.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,6 @@ public class RNSVGSvgView extends ViewGroup {
4444
private final TouchEventCoalescingKeyHelper mTouchEventCoalescingKeyHelper =
4545
new TouchEventCoalescingKeyHelper();
4646

47-
public RNSVGSvgView(Context context, RNSVGSvgViewShadowNode shadowNode) {
48-
super(context);
49-
mSvgViewShadowNode = shadowNode;
50-
}
51-
5247
public RNSVGSvgView(Context context) {
5348
super(context);
5449
}
@@ -86,6 +81,11 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
8681

8782
}
8883

84+
public void setShadowNode(RNSVGSvgViewShadowNode shadowNode) {
85+
mSvgViewShadowNode = shadowNode;
86+
shadowNode.setSvgView(this);
87+
}
88+
8989
public void handleTouchEvent(MotionEvent ev, EventDispatcher eventDispatcher) {
9090
int action = ev.getAction() & MotionEvent.ACTION_MASK;
9191
if (action == MotionEvent.ACTION_DOWN) {

android/src/main/java/com/horcrux/svg/RNSVGSvgViewManager.java

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,29 @@
1010
package com.horcrux.svg;
1111

1212
import android.graphics.Bitmap;
13+
import android.telecom.Call;
14+
import android.util.Log;
1315

16+
import com.facebook.react.bridge.Arguments;
17+
import com.facebook.react.bridge.ReactContext;
18+
import com.facebook.react.bridge.ReactMethod;
19+
import com.facebook.react.bridge.ReadableArray;
20+
import com.facebook.react.bridge.WritableMap;
21+
import com.facebook.react.uimanager.BaseViewManager;
22+
import com.facebook.react.uimanager.LayoutShadowNode;
23+
import com.facebook.react.uimanager.ReactStylesDiffMap;
24+
import com.facebook.react.uimanager.SimpleViewManager;
1425
import com.facebook.react.uimanager.ThemedReactContext;
1526
import com.facebook.react.uimanager.ViewGroupManager;
27+
import com.facebook.react.uimanager.ViewManagerPropertyUpdater;
28+
import com.facebook.react.uimanager.events.RCTEventEmitter;
1629

1730
import java.util.ArrayList;
31+
import java.util.HashMap;
32+
import java.util.Map;
1833

1934
import javax.annotation.Nullable;
35+
import javax.security.auth.callback.Callback;
2036

2137
/**
2238
* ViewManager for RNSVGSvgView React views. Renders as a {@link RNSVGSvgView} and handles
@@ -25,26 +41,54 @@
2541
public class RNSVGSvgViewManager extends ViewGroupManager<RNSVGSvgView> {
2642

2743
private static final String REACT_CLASS = "RNSVGSvgView";
28-
private RNSVGSvgView svgView = null;
29-
3044
// TODO: use an ArrayList to connect RNSVGSvgViewShadowNode with RNSVGSvgView, not sure if there will be a race condition.
3145
// TODO: find a better way to replace this
32-
private ArrayList<RNSVGSvgViewShadowNode> SvgShadowNodes = new ArrayList<>();
46+
private ArrayList<RNSVGSvgViewShadowNode> mSvgShadowNodes = new ArrayList<>();
47+
48+
public static final int COMMAND_TO_DATA_URL = 100;
3349

3450
@Override
3551
public String getName() {
3652
return REACT_CLASS;
3753
}
3854

39-
@Nullable
40-
public RNSVGSvgView getSvgView() {
41-
return this.svgView;
55+
@Override
56+
public @Nullable Map<String, Integer> getCommandsMap() {
57+
Map<String, Integer> commandsMap = super.getCommandsMap();
58+
if (commandsMap == null) {
59+
commandsMap = new HashMap<>();
60+
}
61+
62+
commandsMap.put("toDataURL", COMMAND_TO_DATA_URL);
63+
return commandsMap;
4264
}
4365

66+
@Override
67+
public void receiveCommand(RNSVGSvgView root, int commandId, @Nullable ReadableArray args) {
68+
super.receiveCommand(root, commandId, args);
69+
70+
switch (commandId) {
71+
case COMMAND_TO_DATA_URL:
72+
toDataURL(root);
73+
break;
74+
}
75+
}
76+
77+
private void toDataURL(RNSVGSvgView root) {
78+
WritableMap event = Arguments.createMap();
79+
event.putString("message", "MyMessage");
80+
ReactContext reactContext = (ReactContext)root.getContext();
81+
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
82+
root.getId(),
83+
"onDataURL",
84+
event);
85+
}
86+
87+
4488
@Override
4589
public RNSVGSvgViewShadowNode createShadowNodeInstance() {
46-
RNSVGSvgViewShadowNode node = new RNSVGSvgViewShadowNode(this);
47-
SvgShadowNodes.add(node);
90+
RNSVGSvgViewShadowNode node = new RNSVGSvgViewShadowNode();
91+
mSvgShadowNodes.add(node);
4892
return node;
4993
}
5094

@@ -55,10 +99,9 @@ public Class<RNSVGSvgViewShadowNode> getShadowNodeClass() {
5599

56100
@Override
57101
protected RNSVGSvgView createViewInstance(ThemedReactContext reactContext) {
58-
RNSVGSvgViewShadowNode shadowNode = SvgShadowNodes.get(0);
59-
SvgShadowNodes.remove(0);
60-
this.svgView = new RNSVGSvgView(reactContext, shadowNode);
61-
return this.svgView;
102+
RNSVGSvgView svgView = new RNSVGSvgView(reactContext);
103+
svgView.setShadowNode(mSvgShadowNodes.remove(0));
104+
return svgView;
62105
}
63106

64107
@Override

android/src/main/java/com/horcrux/svg/RNSVGSvgViewShadowNode.java

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
import android.graphics.Paint;
1515
import android.graphics.Point;
1616
import android.graphics.Rect;
17+
import android.util.Log;
1718
import android.view.View;
1819
import android.view.ViewGroup;
1920

2021
import com.facebook.imagepipeline.request.ImageRequest;
2122
import com.facebook.react.uimanager.LayoutShadowNode;
23+
import com.facebook.react.uimanager.ReactShadowNode;
2224
import com.facebook.react.uimanager.UIViewOperationQueue;
2325

2426
import java.util.HashMap;
@@ -32,17 +34,11 @@
3234
public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
3335

3436
private boolean mResponsible = false;
37+
private RNSVGSvgView mSvgView;
3538
private static final Map<String, RNSVGVirtualNode> mDefinedClipPaths = new HashMap<>();
3639
private static final Map<String, RNSVGVirtualNode> mDefinedTemplates = new HashMap<>();
3740
private static final Map<String, PropHelper.RNSVGBrush> mDefinedBrushes = new HashMap<>();
3841

39-
@Nonnull private final RNSVGSvgViewManager viewManager;
40-
41-
public RNSVGSvgViewShadowNode(@Nonnull final RNSVGSvgViewManager viewManager) {
42-
super();
43-
this.viewManager = viewManager;
44-
}
45-
4642
@Override
4743
public void onCollectExtraUpdates(UIViewOperationQueue uiUpdater) {
4844
super.onCollectExtraUpdates(uiUpdater);
@@ -88,16 +84,6 @@ public synchronized void drawChildren(Canvas canvas, Paint paint) {
8884
}
8985
}
9086

91-
protected void invalidateView(@Nonnull final Rect dirtyRect) {
92-
final RNSVGSvgView svgView = this.viewManager.getSvgView();
93-
if (svgView != null) {
94-
final View rootView = svgView.getRootView();
95-
if (rootView != null) {
96-
rootView.invalidate(dirtyRect);
97-
}
98-
}
99-
}
100-
10187
public void enableTouchEvents() {
10288
if (!mResponsible) {
10389
mResponsible = true;
@@ -145,7 +131,15 @@ public void defineBrush(PropHelper.RNSVGBrush brush, String brushRef) {
145131
mDefinedBrushes.put(brushRef, brush);
146132
}
147133

148-
public PropHelper.RNSVGBrush getDefinedBrush(String brushRef) {
134+
public PropHelper.RNSVGBrush getDefinedBrush(String brushRef) {
149135
return mDefinedBrushes.get(brushRef);
150136
}
137+
138+
public void setSvgView(RNSVGSvgView svgView) {
139+
mSvgView = svgView;
140+
}
141+
142+
protected void invalidateView() {
143+
mSvgView.invalidate();
144+
}
151145
}

ios/ViewManagers/RNSVGSvgViewManager.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ - (UIView *)view
2424
RCT_EXPORT_METHOD(toDataURL:(nonnull NSNumber *)reactTag callback:(RCTResponseSenderBlock)callback)
2525
{
2626
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *,UIView *> *viewRegistry) {
27-
UIView *view = viewRegistry[reactTag];
28-
if (![view isKindOfClass:[RNSVGSvgView class]]) {
29-
RCTLogError(@"Invalid svg returned frin registry, expecting RNSVGSvgView, got: %@", view);
30-
} else {
27+
__kindof UIView *view = viewRegistry[reactTag];
28+
if ([view isKindOfClass:[RNSVGSvgView class]]) {
3129
RNSVGSvgView *svg = view;
3230
callback(@[[svg getDataURL]]);
31+
} else {
32+
RCTLogError(@"Invalid svg returned frin registry, expecting RNSVGSvgView, got: %@", view);
3333
}
3434
}];
3535
}

0 commit comments

Comments
 (0)