diff --git a/Example/examples.js b/Example/examples.js
index d9992710..e8f46b19 100644
--- a/Example/examples.js
+++ b/Example/examples.js
@@ -13,6 +13,7 @@ import * as Use from './examples/Use';
import * as Symbol from './examples/Symbol';
import * as Gradients from './examples/Gradients';
import * as Clipping from './examples/Clipping';
+import * as Image from './examples/Image';
export {
Svg,
@@ -29,5 +30,6 @@ export {
Use,
Symbol,
Gradients,
- Clipping
+ Clipping,
+ Image
};
diff --git a/Example/examples/Image.js b/Example/examples/Image.js
new file mode 100644
index 00000000..c8772147
--- /dev/null
+++ b/Example/examples/Image.js
@@ -0,0 +1,83 @@
+import React, {
+ Component
+} from 'react-native';
+
+import Svg, {
+ Image,
+ Defs,
+ Circle,
+ ClipPath,
+ Text
+} from 'react-native-svg';
+
+class ImageExample extends Component{
+ static title = 'Image';
+
+ render() {
+ return ;
+ }
+}
+
+class ClipImage extends Component{
+ static title = 'Clip Image';
+
+ render() {
+ return ;
+ }
+}
+
+const icon = ;
+
+const samples = [ImageExample, ClipImage];
+
+export {
+ icon,
+ samples
+};
diff --git a/Example/image.jpg b/Example/image.jpg
new file mode 100644
index 00000000..8fddd5c1
Binary files /dev/null and b/Example/image.jpg differ
diff --git a/Example/main.js b/Example/main.js
index 2d5d1028..86bf18c8 100644
--- a/Example/main.js
+++ b/Example/main.js
@@ -105,7 +105,7 @@ const styles = StyleSheet.create({
}
});
-const names = ['Svg', 'Stroking', 'Path', 'Line', 'Rect', 'Polygon', 'Polyline', 'Circle', 'Ellipse', 'G', 'Text', 'Use', 'Symbol', 'Gradients', 'Clipping'];
+const names = ['Svg', 'Stroking', 'Path', 'Line', 'Rect', 'Polygon', 'Polyline', 'Circle', 'Ellipse', 'G', 'Text', 'Use', 'Symbol', 'Gradients', 'Clipping', 'Image'];
class ArtSvgExample extends Component {
constructor() {
diff --git a/elements/Image.js b/elements/Image.js
index de76f1ea..99d2c2de 100644
--- a/elements/Image.js
+++ b/elements/Image.js
@@ -1,25 +1,41 @@
-import {
+import React, {
Component,
PropTypes
} from 'react-native';
-
-let propType = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
+import {NativeGroup} from './G';
+import extractProps from '../lib/extract/extractProps';
+import {ImageAttributes} from '../lib/attributes';
+import Rect from './Rect';
+import {numberProp} from '../lib/props';
+import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
+import createReactNativeComponentClass from 'react-native/Libraries/ReactNative/createReactNativeComponentClass';
+import formatPercentageProps from '../lib/formatPercentageProps';
class Image extends Component{
static displayName = 'Image';
static propTypes = {
- x1: propType,
- x2: propType,
- y1: propType,
- y2: propType,
- href: PropTypes.string
+ x: numberProp,
+ y: numberProp,
+ width: numberProp,
+ height: numberProp,
+ href: PropTypes.number.isRequired
//preserveAspectRatio: PropTypes.string
};
render() {
- return null;
+ return ;
}
}
+let RNSVGImage = createReactNativeComponentClass({
+ validAttributes: ImageAttributes,
+ uiViewClassName: 'RNSVGImage'
+});
+
+
export default Image;
diff --git a/elements/Shape.js b/elements/Shape.js
index 9a1b7eb3..a3319bba 100644
--- a/elements/Shape.js
+++ b/elements/Shape.js
@@ -1,11 +1,11 @@
import React, {
Component
} from 'react-native';
-import './Path'; // must import Path first, don`t know why. without this will throw an `Super expression must either be null or a function, not undefined`, maybe cyclic dependencies issue
+import './Path'; // must import Path first, don`t know why. without this will throw an `Super expression must either be null or a function, not undefined`
import _ from 'lodash';
import extractProps from '../lib/extract/extractProps';
import {ShapeAttributes} from '../lib/attributes';
-import SerializableShape from '../lib/SerializableShape';
+import formatPercentageProps from '../lib/formatPercentageProps';
import createReactNativeComponentClass from 'react-native/Libraries/ReactNative/createReactNativeComponentClass';
import {circleProps, ellipseProps, lineProps, rectProps} from '../lib/props';
@@ -55,8 +55,6 @@ class Shape extends Component{
});
}
- let shape = new SerializableShape(props, COORD_PROPS[this.type]).toJSON();
-
return ;
diff --git a/ios/RNSVG.xcodeproj/project.pbxproj b/ios/RNSVG.xcodeproj/project.pbxproj
index ec2ad54f..43856bf4 100644
--- a/ios/RNSVG.xcodeproj/project.pbxproj
+++ b/ios/RNSVG.xcodeproj/project.pbxproj
@@ -21,6 +21,8 @@
0CF68B121AF0549300FF9E5C /* RNSVGNodeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFC1AF0549300FF9E5C /* RNSVGNodeManager.m */; };
0CF68B131AF0549300FF9E5C /* RNSVGRenderableManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFE1AF0549300FF9E5C /* RNSVGRenderableManager.m */; };
0CF68B161AF0549300FF9E5C /* RNSVGTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B041AF0549300FF9E5C /* RNSVGTextManager.m */; };
+ 108FD88C1CDAF09B00A65FB3 /* RNSVGImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 108FD88B1CDAF09B00A65FB3 /* RNSVGImageManager.m */; };
+ 108FD88F1CDAF0A300A65FB3 /* RNSVGImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 108FD88E1CDAF0A300A65FB3 /* RNSVGImage.m */; };
10A062FE1CC732020000CEEF /* RNSVGPathManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10A062FB1CC732020000CEEF /* RNSVGPathManager.m */; };
10A062FF1CC732020000CEEF /* RNSVGSvgViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10A062FD1CC732020000CEEF /* RNSVGSvgViewManager.m */; };
10A063041CC7320C0000CEEF /* RNSVGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 10A063011CC7320C0000CEEF /* RNSVGPath.m */; };
@@ -74,6 +76,10 @@
0CF68AFE1AF0549300FF9E5C /* RNSVGRenderableManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGRenderableManager.m; sourceTree = ""; };
0CF68B031AF0549300FF9E5C /* RNSVGTextManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGTextManager.h; sourceTree = ""; };
0CF68B041AF0549300FF9E5C /* RNSVGTextManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGTextManager.m; sourceTree = ""; };
+ 108FD88A1CDAF09B00A65FB3 /* RNSVGImageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGImageManager.h; sourceTree = ""; };
+ 108FD88B1CDAF09B00A65FB3 /* RNSVGImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGImageManager.m; sourceTree = ""; };
+ 108FD88D1CDAF0A300A65FB3 /* RNSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGImage.h; sourceTree = ""; };
+ 108FD88E1CDAF0A300A65FB3 /* RNSVGImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGImage.m; sourceTree = ""; };
10A062FA1CC732020000CEEF /* RNSVGPathManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGPathManager.h; sourceTree = ""; };
10A062FB1CC732020000CEEF /* RNSVGPathManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGPathManager.m; sourceTree = ""; };
10A062FC1CC732020000CEEF /* RNSVGSvgViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSvgViewManager.h; sourceTree = ""; };
@@ -112,6 +118,8 @@
0CF68ADE1AF0549300FF9E5C /* RNSVGGroup.m */,
10C068641CCF0F87007C6982 /* RNSVGShape.h */,
10C068651CCF0F87007C6982 /* RNSVGShape.m */,
+ 108FD88D1CDAF0A300A65FB3 /* RNSVGImage.h */,
+ 108FD88E1CDAF0A300A65FB3 /* RNSVGImage.m */,
10A063001CC7320C0000CEEF /* RNSVGPath.h */,
10A063011CC7320C0000CEEF /* RNSVGPath.m */,
0CF68ADF1AF0549300FF9E5C /* RNSVGNode.h */,
@@ -157,6 +165,8 @@
0CF68AF81AF0549300FF9E5C /* ViewManagers */ = {
isa = PBXGroup;
children = (
+ 108FD88A1CDAF09B00A65FB3 /* RNSVGImageManager.h */,
+ 108FD88B1CDAF09B00A65FB3 /* RNSVGImageManager.m */,
10C068681CCF1061007C6982 /* RNSVGShapeManager.h */,
10C068691CCF1061007C6982 /* RNSVGShapeManager.m */,
10A062FA1CC732020000CEEF /* RNSVGPathManager.h */,
@@ -240,11 +250,13 @@
0CF68B051AF0549300FF9E5C /* RNSVGGroup.m in Sources */,
10A062FF1CC732020000CEEF /* RNSVGSvgViewManager.m in Sources */,
0CF68B131AF0549300FF9E5C /* RNSVGRenderableManager.m in Sources */,
+ 108FD88F1CDAF0A300A65FB3 /* RNSVGImage.m in Sources */,
0CF68B0E1AF0549300FF9E5C /* RNSVGRadialGradient.m in Sources */,
10A063051CC7320C0000CEEF /* RNSVGSvgView.m in Sources */,
0CF68B071AF0549300FF9E5C /* RNSVGRenderable.m in Sources */,
0CF68B101AF0549300FF9E5C /* RCTConvert+RNSVG.m in Sources */,
10C0686A1CCF1061007C6982 /* RNSVGShapeManager.m in Sources */,
+ 108FD88C1CDAF09B00A65FB3 /* RNSVGImageManager.m in Sources */,
10A062FE1CC732020000CEEF /* RNSVGPathManager.m in Sources */,
0CF68B061AF0549300FF9E5C /* RNSVGNode.m in Sources */,
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColor.m in Sources */,
diff --git a/ios/RNSVGImage.h b/ios/RNSVGImage.h
new file mode 100644
index 00000000..6ffb0f7d
--- /dev/null
+++ b/ios/RNSVGImage.h
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2015-present, Horcrux.
+ * All rights reserved.
+ *
+ * This source code is licensed under the MIT-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+#import
+
+#import "RNSVGRenderable.h"
+
+@interface RNSVGImage : RNSVGRenderable
+@property (nonatomic, strong) NSDictionary* layout;
+@property (nonatomic, assign) id src;
+
+- (CGFloat)getActualProp:(NSString *)name relative:(float)relative;
+
+@end
diff --git a/ios/RNSVGImage.m b/ios/RNSVGImage.m
new file mode 100644
index 00000000..2e67f96a
--- /dev/null
+++ b/ios/RNSVGImage.m
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2015-present, Horcrux.
+ * All rights reserved.
+ *
+ * This source code is licensed under the MIT-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+#import "RNSVGImage.h"
+#import "RCTConvert+RNSVG.h"
+#import "RCTLog.h"
+
+@implementation RNSVGImage
+{
+ CGImageRef image;
+}
+- (void)setSrc:(id)src
+{
+ if (src == _src) {
+ return;
+ }
+ _src = src;
+ CGImageRelease(image);
+ image = CGImageRetain([RCTConvert CGImage:src]);
+ [self invalidate];
+}
+
+- (void)setLayout:(NSDictionary *)layout
+{
+ if (layout == _layout) {
+ return;
+ }
+ _layout = layout;
+ [self invalidate];
+}
+
+- (void)dealloc
+{
+ CGImageRelease(image);
+}
+
+- (void)renderLayerTo:(CGContextRef)context
+{
+ CGRect box = CGContextGetClipBoundingBox(context);
+ float height = CGRectGetHeight(box);
+ float width = CGRectGetWidth(box);
+
+ CGFloat x = [self getActualProp:@"x" relative:width];
+ CGFloat y = [self getActualProp:@"y" relative:height];
+ CGFloat w = [self getActualProp:@"width" relative:width];
+ CGFloat h = [self getActualProp:@"height" relative:height];
+ [self clip:context];
+ CGContextSaveGState(context);
+ CGContextTranslateCTM(context, 0, h);
+ CGContextScaleCTM(context, 1.0, -1.0);
+ CGContextDrawImage(context, CGRectMake(x, -y, w, h), image);
+ CGContextRestoreGState(context);
+}
+
+- (CGFloat)getActualProp:(NSString *)name relative:(float)relative
+{
+ NSDictionary *prop = [self.layout objectForKey:name];
+ return [super getActualProp:prop relative:relative];
+
+}
+
+@end
diff --git a/ios/RNSVGRenderable.h b/ios/RNSVGRenderable.h
index c941e081..490dd122 100644
--- a/ios/RNSVGRenderable.h
+++ b/ios/RNSVGRenderable.h
@@ -24,4 +24,6 @@
@property (nonatomic, assign) RNSVGCGFloatArray strokeDasharray;
@property (nonatomic, assign) CGFloat strokeDashoffset;
+- (CGFloat)getActualProp:(NSDictionary *) prop relative:(float)relative;
+
@end
diff --git a/ios/RNSVGRenderable.m b/ios/RNSVGRenderable.m
index 1d3b324b..6e1b9431 100644
--- a/ios/RNSVGRenderable.m
+++ b/ios/RNSVGRenderable.m
@@ -81,6 +81,17 @@
CGContextRestoreGState(context);
}
+- (CGFloat)getActualProp:(NSDictionary *) prop relative:(float)relative
+{
+ CGFloat value = [[prop objectForKey:@"value"] floatValue];
+ if ([[prop objectForKey:@"percentage"] integerValue] == 1) {
+ return relative * value;
+ } else {
+ return value;
+ }
+}
+
+
- (void)renderLayerTo:(CGContextRef)context
{
// abstract
diff --git a/ios/RNSVGShape.h b/ios/RNSVGShape.h
index 17a28727..bdf815fe 100644
--- a/ios/RNSVGShape.h
+++ b/ios/RNSVGShape.h
@@ -14,4 +14,6 @@
@interface RNSVGShape : RNSVGPath
@property (nonatomic, strong) NSDictionary* shape;
+- (CGFloat)getActualProp:(NSString *)name relative:(float)relative;
+
@end
diff --git a/ios/RNSVGShape.m b/ios/RNSVGShape.m
index 38702d32..1fd30bf2 100644
--- a/ios/RNSVGShape.m
+++ b/ios/RNSVGShape.m
@@ -112,12 +112,7 @@
- (CGFloat)getActualProp:(NSString *)name relative:(float)relative
{
NSDictionary *prop = [self.shape objectForKey:name];
- CGFloat value = [[prop objectForKey:@"value"] floatValue];
- if ([[prop objectForKey:@"percentage"] integerValue] == 1) {
- return relative * value;
- } else {
- return value;
- }
+ return [super getActualProp:prop relative:relative];
}
@end
diff --git a/ios/ViewManagers/RNSVGImageManager.h b/ios/ViewManagers/RNSVGImageManager.h
new file mode 100644
index 00000000..c799d3e5
--- /dev/null
+++ b/ios/ViewManagers/RNSVGImageManager.h
@@ -0,0 +1,13 @@
+/**
+ * Copyright (c) 2015-present, Horcrux.
+ * All rights reserved.
+ *
+ * This source code is licensed under the MIT-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+#import "RNSVGRenderableManager.h"
+
+@interface RNSVGImageManager : RNSVGRenderableManager
+
+@end
diff --git a/ios/ViewManagers/RNSVGImageManager.m b/ios/ViewManagers/RNSVGImageManager.m
new file mode 100644
index 00000000..1284602a
--- /dev/null
+++ b/ios/ViewManagers/RNSVGImageManager.m
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2015-present, Horcrux.
+ * All rights reserved.
+ *
+ * This source code is licensed under the MIT-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+#import "RNSVGImageManager.h"
+
+#import "RNSVGImage.h"
+#import "RCTConvert+RNSVG.h"
+
+@implementation RNSVGImageManager
+
+RCT_EXPORT_MODULE()
+
+- (RNSVGRenderable *)node
+{
+ return [RNSVGImage new];
+}
+
+RCT_EXPORT_VIEW_PROPERTY(layout, NSDictionary)
+RCT_EXPORT_VIEW_PROPERTY(src, id)
+
+@end
diff --git a/lib/SerializablePath.js b/lib/SerializablePath.js
index 0577e84d..b69cc518 100644
--- a/lib/SerializablePath.js
+++ b/lib/SerializablePath.js
@@ -17,7 +17,6 @@ export default class SerializablePath {
}
/* parser */
-
push = () => {
let p = Array.prototype.join.call(arguments, ' ')
.replace(/(\.[\d]+)(\-?\.)/ig, '$1,$2') //-.3-.575 => -.3,-.575
@@ -33,65 +32,27 @@ export default class SerializablePath {
while (cmd){
switch (cmd){
- case 'm':
- this.move(p[i++], p[i++]);
- break;
- case 'l':
- this.line(p[i++], p[i++]);
- break;
- case 'c':
- this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]);
- break;
- case 's':
- this.curve(p[i++], p[i++], null, null, p[i++], p[i++]);
- break;
- case 'q':
- this.curve(p[i++], p[i++], p[i++], p[i++]);
- break;
- case 't':
- this.curve(p[i++], p[i++]);
- break;
- case 'a':
- this.arc(p[i + 5], p[i + 6], p[i], p[i + 1], p[i + 3], !+p[i + 4], p[i + 2]); i += 7;
- break;
- case 'h':
- this.line(p[i++], 0);
- break;
- case 'v':
- this.line(0, p[i++]);
- break;
+ case 'm': this.move(p[i++], p[i++]); break;
+ case 'l': this.line(p[i++], p[i++]); break;
+ case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
+ case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break;
+ case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break;
+ case 't': this.curve(p[i++], p[i++]); break;
+ case 'a': this.arc(p[i + 5], p[i + 6], p[i], p[i + 1], p[i + 3], !+p[i + 4], p[i + 2]); i += 7; break;
+ case 'h': this.line(p[i++], 0); break;
+ case 'v': this.line(0, p[i++]); break;
- case 'M':
- this.moveTo(p[i++], p[i++]);
- break;
- case 'L':
- this.lineTo(p[i++], p[i++]);
- break;
- case 'C':
- this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]);
- break;
- case 'S':
- this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]);
- break;
- case 'Q':
- this.curveTo(p[i++], p[i++], p[i++], p[i++]);
- break;
- case 'T':
- this.curveTo(p[i++], p[i++]);
- break;
- case 'A':
- this.arcTo(p[i + 5], p[i + 6], p[i], p[i + 1], p[i + 3], !+p[i + 4], p[i + 2]); i += 7;
- break;
- case 'H':
- this.lineTo(p[i++], this.penY);
- break;
- case 'V':
- this.lineTo(this.penX, p[i++]);
- break;
- case 'Z':
- case 'z':
- this.close();
- break;
+ case 'M': this.moveTo(p[i++], p[i++]); break;
+ case 'L': this.lineTo(p[i++], p[i++]); break;
+ case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
+ case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break;
+ case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break;
+ case 'T': this.curveTo(p[i++], p[i++]); break;
+ case 'A': this.arcTo(p[i + 5], p[i + 6], p[i], p[i + 1], p[i + 3], !+p[i + 4], p[i + 2]); i += 7; break;
+ case 'H': this.lineTo(p[i++], this.penY); break;
+ case 'V': this.lineTo(this.penX, p[i++]); break;
+
+ case 'Z': case 'z': this.close(); break;
default:
cmd = last;
i--;
diff --git a/lib/attributes.js b/lib/attributes.js
index e982e5e9..d5cf4ecb 100644
--- a/lib/attributes.js
+++ b/lib/attributes.js
@@ -15,7 +15,7 @@ function arrayDiffer(a, b) {
return false;
}
-function shapeDiffer(a, b) {
+function percentageDiffer(a, b) {
if (a === b) {
return false;
}
@@ -111,15 +111,24 @@ const TextAttributes = {
const ShapeAttributes = {
shape: {
- diff: shapeDiffer
+ diff: percentageDiffer
},
...RenderableAttributes
};
+const ImageAttributes = {
+ ...NodeAttributes,
+ layout: {
+ diff: percentageDiffer
+ },
+ src: true
+};
+
export {
GroupAttributes,
PathAttributes,
TextAttributes,
- ShapeAttributes
+ ShapeAttributes,
+ ImageAttributes
};
diff --git a/lib/extract/extractProps.js b/lib/extract/extractProps.js
index 355ce61f..bd58553a 100644
--- a/lib/extract/extractProps.js
+++ b/lib/extract/extractProps.js
@@ -4,7 +4,7 @@ import extractTransform from './extractTransform';
import extractClipping from './extractClipping';
import _ from 'lodash';
-export default function(props, options = {stroke: true, join: true, transform: true, fill: true}) {
+export default function(props, options = {stroke: true, transform: true, fill: true}) {
if (props.visible === false) {
return {
opacity: 0
diff --git a/lib/SerializableShape.js b/lib/formatPercentageProps.js
similarity index 68%
rename from lib/SerializableShape.js
rename to lib/formatPercentageProps.js
index fca9af43..ddc74156 100644
--- a/lib/SerializableShape.js
+++ b/lib/formatPercentageProps.js
@@ -38,18 +38,12 @@ function percentageTransform(value) {
};
}
-export default class {
- constructor(props, list) {
- this.shape = {};
- list.forEach(name => {
- if (!_.isNil(props[name])) {
- this.shape[name] = percentageTransform(props[name]);
- }
- });
- }
+export default function (props, list) {
+ return _.reduce(list, (prev, name) => {
+ if (!_.isNil(props[name])) {
+ prev[name] = percentageTransform(props[name]);
+ }
- toJSON = () => {
- return this.shape;
- };
+ return prev;
+ }, {});
}
-