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

View File

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

View File

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

View File

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

View File

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

View File

@@ -14,14 +14,12 @@ import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.uimanager.ReactShadowNode;
import java.security.PublicKey;
import javax.annotation.Nullable;

View File

@@ -14,8 +14,6 @@ import android.graphics.Paint;
import android.graphics.Path;
import com.facebook.react.uimanager.annotations.ReactProp;
import javax.annotation.Nullable;
/**
* 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.uimanager.annotations.ReactProp;
import java.util.ArrayList;
/**
* Shadow node for virtual LinearGradient definition view
*/

View File

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

View File

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

View File

@@ -13,8 +13,6 @@ import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
// NativeGestureUtil.notifyNativeGestureStarted
/**
* 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 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.uimanager.ThemedReactContext;
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.TouchEventCoalescingKeyHelper;
import com.facebook.react.uimanager.events.TouchEventType;
import com.facebook.react.uimanager.events.EventDispatcher;
// NativeGestureUtil.notifyNativeGestureStarted
/**
* Custom {@link View} implementation that draws an RNSVGSvg React view and its \children.
*/
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 RCTEventEmitter mEventEmitter;
private RNSVGSvgViewShadowNode mSvgViewShadowNode;
private int mTargetTag;
private final TouchEventCoalescingKeyHelper mTouchEventCoalescingKeyHelper =
@@ -48,6 +65,11 @@ public class RNSVGSvgView extends ViewGroup {
super(context);
}
public RNSVGSvgView(ReactContext reactContext) {
super(reactContext);
mEventEmitter = reactContext.getJSModule(RCTEventEmitter.class);
}
public void setBitmap(Bitmap bitmap) {
if (mBitmap != null) {
mBitmap.recycle();
@@ -183,4 +205,10 @@ public class RNSVGSvgView extends ViewGroup {
androidEvent.getY(),
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;
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.WritableMap;
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.common.MapBuilder;
import com.facebook.react.uimanager.ThemedReactContext;
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.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
import javax.security.auth.callback.Callback;
/**
* ViewManager for RNSVGSvgView React views. Renders as a {@link RNSVGSvgView} and handles
@@ -63,27 +50,27 @@ public class RNSVGSvgViewManager extends ViewGroupManager<RNSVGSvgView> {
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
public void receiveCommand(RNSVGSvgView root, int commandId, @Nullable ReadableArray args) {
super.receiveCommand(root, commandId, args);
switch (commandId) {
case COMMAND_TO_DATA_URL:
toDataURL(root);
root.onDataURL();
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
public RNSVGSvgViewShadowNode createShadowNodeInstance() {

View File

@@ -13,21 +13,17 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.Log;
import android.view.View;
import android.util.Base64;
import android.view.ViewGroup;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.ReactShadowNode;
import com.facebook.react.uimanager.UIViewOperationQueue;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nonnull;
/**
* Shadow node for RNSVG virtual tree root - RNSVGSvgView
*/
@@ -57,6 +53,15 @@ public class RNSVGSvgViewShadowNode extends LayoutShadowNode {
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
*

View File

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

View File

@@ -11,7 +11,6 @@ package com.horcrux.svg;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.Log;
import com.facebook.common.logging.FLog;
import com.facebook.react.common.ReactConstants;

View File

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