Add support to base64 data from svg

use `svgRef.toDataURL(function (base64) {console.log(base64);});` to get
base64 data of svgRef
This commit is contained in:
Horcrux
2016-08-12 11:13:27 +08:00
parent 857b5f5207
commit e747cc82a6
17 changed files with 84 additions and 56 deletions

View File

@@ -174,10 +174,12 @@ class SvgNativeMethods extends Component {
<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"/> <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"/>
</G> </G>
</Svg> </Svg>
<Image <View style={{width:150, height: 100, borderWidth: 1, marginTop: 5}}>
source={{url: `data:image/png;base64,${this.state.base64}`}} {this.state.base64 && <Image
style={{width:150, height: 100, borderWidth: 1, marginTop: 5}} source={{uri: `data:image/png;base64,${this.state.base64}`}}
/> style={{width:150, height: 100}}
/>}
</View>
</View>; </View>;
} }
} }

View File

@@ -579,6 +579,7 @@ npm install
2. more Text features support (textPath, tref, tspan) 2. more Text features support (textPath, tref, tspan)
3. Pattern element 3. Pattern element
4. implement Animated elements 4. implement Animated elements
5. more Image features support
#### Thanks: #### Thanks:

View File

@@ -16,7 +16,6 @@ import android.graphics.RadialGradient;
import android.graphics.LinearGradient; import android.graphics.LinearGradient;
import android.graphics.Shader; import android.graphics.Shader;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.util.Log;
import javax.annotation.Nullable; import javax.annotation.Nullable;

View File

@@ -12,7 +12,6 @@ package com.horcrux.svg;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.util.Log;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;

View File

@@ -13,7 +13,6 @@ import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.RectF; import android.graphics.RectF;
import android.util.Log;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;

View File

@@ -14,14 +14,12 @@ 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;
import android.util.Log;
import android.view.View; 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 com.facebook.react.uimanager.ReactShadowNode;
import java.security.PublicKey;
import javax.annotation.Nullable; import javax.annotation.Nullable;

View File

@@ -14,8 +14,6 @@ import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;
import javax.annotation.Nullable;
/** /**
* Shadow node for virtual RNSVGPath view * Shadow node for virtual RNSVGPath view
*/ */

View File

@@ -14,8 +14,6 @@ import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableArray;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;
import java.util.ArrayList;
/** /**
* Shadow node for virtual LinearGradient definition view * Shadow node for virtual LinearGradient definition view
*/ */

View File

@@ -21,7 +21,6 @@ import android.graphics.Point;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.Color; import android.graphics.Color;
import android.util.Log;
import android.view.View; import android.view.View;
import com.facebook.common.logging.FLog; import com.facebook.common.logging.FLog;

View File

@@ -15,8 +15,6 @@ import android.graphics.Path;
import android.graphics.RectF; import android.graphics.RectF;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;
import javax.annotation.Nullable;
/** /**
* Shadow node for virtual RNSVGPath view * Shadow node for virtual RNSVGPath view
*/ */

View File

@@ -13,8 +13,6 @@ import android.content.Context;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
// NativeGestureUtil.notifyNativeGestureStarted
/** /**
* Custom {@link View} implementation that draws an RNSVGSvg React view and its \children. * Custom {@link View} implementation that draws an RNSVGSvg React view and its \children.
*/ */

View File

@@ -21,24 +21,41 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.facebook.infer.annotation.Assertions; import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.SystemClock; import com.facebook.react.common.SystemClock;
import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.facebook.react.uimanager.events.TouchEvent; import com.facebook.react.uimanager.events.TouchEvent;
import com.facebook.react.uimanager.events.TouchEventCoalescingKeyHelper; import com.facebook.react.uimanager.events.TouchEventCoalescingKeyHelper;
import com.facebook.react.uimanager.events.TouchEventType; import com.facebook.react.uimanager.events.TouchEventType;
import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.uimanager.events.EventDispatcher;
// NativeGestureUtil.notifyNativeGestureStarted
/** /**
* Custom {@link View} implementation that draws an RNSVGSvg React view and its \children. * Custom {@link View} implementation that draws an RNSVGSvg React view and its \children.
*/ */
public class RNSVGSvgView extends ViewGroup { public class RNSVGSvgView extends ViewGroup {
public enum Events {
EVENT_DATA_URL("onDataURL");
private final String mName;
Events(final String name) {
mName = name;
}
@Override
public String toString() {
return mName;
}
}
private @Nullable Bitmap mBitmap; private @Nullable Bitmap mBitmap;
private RCTEventEmitter mEventEmitter;
private RNSVGSvgViewShadowNode mSvgViewShadowNode; private RNSVGSvgViewShadowNode mSvgViewShadowNode;
private int mTargetTag; private int mTargetTag;
private final TouchEventCoalescingKeyHelper mTouchEventCoalescingKeyHelper = private final TouchEventCoalescingKeyHelper mTouchEventCoalescingKeyHelper =
@@ -48,6 +65,11 @@ public class RNSVGSvgView extends ViewGroup {
super(context); super(context);
} }
public RNSVGSvgView(ReactContext reactContext) {
super(reactContext);
mEventEmitter = reactContext.getJSModule(RCTEventEmitter.class);
}
public void setBitmap(Bitmap bitmap) { public void setBitmap(Bitmap bitmap) {
if (mBitmap != null) { if (mBitmap != null) {
mBitmap.recycle(); mBitmap.recycle();
@@ -183,4 +205,10 @@ public class RNSVGSvgView extends ViewGroup {
androidEvent.getY(), androidEvent.getY(),
mTouchEventCoalescingKeyHelper)); mTouchEventCoalescingKeyHelper));
} }
public void onDataURL() {
WritableMap event = Arguments.createMap();
event.putString("base64", mSvgViewShadowNode.getBase64());
mEventEmitter.receiveEvent(getId(), Events.EVENT_DATA_URL.toString(), event);
}
} }

View File

@@ -10,29 +10,16 @@
package com.horcrux.svg; package com.horcrux.svg;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.telecom.Call;
import android.util.Log;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.BaseViewManager;
import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.ReactStylesDiffMap;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.ViewManagerPropertyUpdater;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.security.auth.callback.Callback;
/** /**
* ViewManager for RNSVGSvgView React views. Renders as a {@link RNSVGSvgView} and handles * ViewManager for RNSVGSvgView React views. Renders as a {@link RNSVGSvgView} and handles
@@ -63,27 +50,27 @@ public class RNSVGSvgViewManager extends ViewGroupManager<RNSVGSvgView> {
return commandsMap; return commandsMap;
} }
@Override
@Nullable
public Map getExportedCustomDirectEventTypeConstants() {
MapBuilder.Builder builder = MapBuilder.builder();
for (RNSVGSvgView.Events event : RNSVGSvgView.Events.values()) {
builder.put(event.toString(), MapBuilder.of("registrationName", event.toString()));
}
return builder.build();
}
@Override @Override
public void receiveCommand(RNSVGSvgView root, int commandId, @Nullable ReadableArray args) { public void receiveCommand(RNSVGSvgView root, int commandId, @Nullable ReadableArray args) {
super.receiveCommand(root, commandId, args); super.receiveCommand(root, commandId, args);
switch (commandId) { switch (commandId) {
case COMMAND_TO_DATA_URL: case COMMAND_TO_DATA_URL:
toDataURL(root); root.onDataURL();
break; break;
} }
} }
private void toDataURL(RNSVGSvgView root) {
WritableMap event = Arguments.createMap();
event.putString("message", "MyMessage");
ReactContext reactContext = (ReactContext)root.getContext();
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
root.getId(),
"onDataURL",
event);
}
@Override @Override
public RNSVGSvgViewShadowNode createShadowNodeInstance() { public RNSVGSvgViewShadowNode createShadowNodeInstance() {

View File

@@ -13,21 +13,17 @@ import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.Rect; import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.facebook.imagepipeline.request.ImageRequest; import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.ReactShadowNode;
import com.facebook.react.uimanager.UIViewOperationQueue; import com.facebook.react.uimanager.UIViewOperationQueue;
import java.io.ByteArrayOutputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.annotation.Nonnull;
/** /**
* Shadow node for RNSVG virtual tree root - RNSVGSvgView * Shadow node for RNSVG virtual tree root - RNSVGSvgView
*/ */
@@ -57,6 +53,15 @@ public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
return bitmap; return bitmap;
} }
public String getBase64() {
Bitmap bitmap = (Bitmap)drawOutput();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
bitmap.recycle();
byte[] bitmapBytes = stream.toByteArray();
return Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
}
/** /**
* Draw all of the child nodes of this root node * Draw all of the child nodes of this root node
* *

View File

@@ -21,7 +21,6 @@ import android.graphics.Rect;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.view.View; import android.view.View;
import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableArray;

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.common.logging.FLog; import com.facebook.common.logging.FLog;
import com.facebook.react.common.ReactConstants; import com.facebook.react.common.ReactConstants;

View File

@@ -8,10 +8,12 @@ import {
StyleSheet, StyleSheet,
UIManager, UIManager,
findNodeHandle, findNodeHandle,
NativeModules NativeModules,
Platform
} from 'react-native'; } from 'react-native';
import ViewBox from './ViewBox'; import ViewBox from './ViewBox';
import _ from 'lodash'; import _ from 'lodash';
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
const RNSVGSvgViewManager = NativeModules.RNSVGSvgViewManager; const RNSVGSvgViewManager = NativeModules.RNSVGSvgViewManager;
// Svg - Root node of all Svg elements // Svg - Root node of all Svg elements
@@ -39,6 +41,7 @@ class Svg extends Component{
super(...arguments); super(...arguments);
id++; id++;
this.id = id; this.id = id;
this.onDataURLCallbacks = [];
} }
measureInWindow = (...args) => { measureInWindow = (...args) => {
this.root.measureInWindow(...args); this.root.measureInWindow(...args);
@@ -56,8 +59,24 @@ class Svg extends Component{
this.root.setNativeProps(...args); this.root.setNativeProps(...args);
}; };
toDataURL = (callback = _.noop) => {
toDataURL = Platform.OS === 'ios' ? (callback = _.noop) => {
RNSVGSvgViewManager.toDataURL(findNodeHandle(this.root), callback); RNSVGSvgViewManager.toDataURL(findNodeHandle(this.root), callback);
} : (callback = _.noop) => {
let node = findNodeHandle(this.root);
this.onDataURLCallbacks.push(callback);
UIManager.dispatchViewManagerCommand(
node,
UIManager.RNSVGSvgView.Commands.toDataURL,
null
);
};
_onDataURL = (e) => {
let callback;
while (callback = this.onDataURLCallbacks.shift()) {
callback(e.nativeEvent.base64);
}
}; };
render() { render() {
@@ -99,6 +118,7 @@ class Svg extends Component{
}, },
dimensions dimensions
]} ]}
onDataURL={this._onDataURL}
> >
{content} {content}
</NativeSvgView>; </NativeSvgView>;
@@ -107,4 +127,5 @@ class Svg extends Component{
const NativeSvgView = requireNativeComponent('RNSVGSvgView', null); const NativeSvgView = requireNativeComponent('RNSVGSvgView', null);
export default Svg; export default Svg;