diff --git a/Example/examples.js b/Example/examples.js
index da57257a..a0108eea 100644
--- a/Example/examples.js
+++ b/Example/examples.js
@@ -14,24 +14,9 @@ import * as Symbol from './examples/Symbol';
import * as Gradients from './examples/Gradients';
import * as Clipping from './examples/Clipping';
import * as Image from './examples/Image';
+import * as Definations from './examples/Definations';
import * as TouchEvents from './examples/TouchEvents';
export {
- Svg,
- Rect,
- Circle,
- Ellipse,
- Line,
- Polygon,
- Polyline,
- Path,
- Text,
- Stroking,
- G,
- Use,
- Symbol,
- Gradients,
- Clipping,
- Image,
- TouchEvents
+ Definations
};
diff --git a/Example/examples/Definations.js b/Example/examples/Definations.js
new file mode 100644
index 00000000..18dfea41
--- /dev/null
+++ b/Example/examples/Definations.js
@@ -0,0 +1,51 @@
+import React, {
+ Component
+} from 'react';
+
+import Svg, {
+ Defs,
+ G,
+ Path,
+ Use,
+ Rect
+} from 'react-native-svg';
+
+class DefsExample extends Component{
+ static title = 'basic Defs usage';
+
+ render() {
+ return ;
+ }
+}
+
+const icon = ;
+
+
+
+const samples = [DefsExample];
+
+export {
+ icon,
+ samples
+};
diff --git a/Example/main.js b/Example/main.js
index 5db80fd7..d1ea1a18 100644
--- a/Example/main.js
+++ b/Example/main.js
@@ -111,7 +111,8 @@ const styles = StyleSheet.create({
}
});
-const names = ['Svg', 'Stroking', 'Path', 'Line', 'Rect', 'Polygon', 'Polyline', 'Circle', 'Ellipse', 'G', 'Text', 'Use', 'Symbol', 'Gradients', 'Clipping', 'Image', 'TouchEvents'];
+//const names = ['Svg', 'Stroking', 'Path', 'Line', 'Rect', 'Polygon', 'Polyline', 'Circle', 'Ellipse', 'G', 'Text', 'Use', 'Symbol', 'Gradients', 'Clipping', 'Image', 'TouchEvents'];
+const names = ['Definations'];
class SvgExample extends Component {
constructor() {
diff --git a/elements/Circle.js b/elements/Circle.js
index 4d0b125f..d8fd363e 100644
--- a/elements/Circle.js
+++ b/elements/Circle.js
@@ -15,9 +15,7 @@ class Circle extends Shape {
static contextTypes = {
...fillProps,
...strokeProps,
- ...circleProps,
- isInGroup: PropTypes.bool,
- svgId: numberProp
+ ...circleProps
};
setNativeProps = (...args) => {
diff --git a/elements/Defs.js b/elements/Defs.js
index 5fc7da09..d18bb699 100644
--- a/elements/Defs.js
+++ b/elements/Defs.js
@@ -1,102 +1,19 @@
-import React, {Children, Component, cloneElement, PropTypes} from 'react';
-import {NativeGroup} from './G';
-let map = {};
+import React, {
+ Component,
+} from 'react'
+import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
-import LinearGradient from './LinearGradient';
-import RadialGradient from './RadialGradient';
-import ClipPath from './ClipPath';
-let onlyChild = Children.only;
-
-class DefsItem extends Component{
- static displayName = 'DefsItem';
- static propType = {
- visible: PropTypes.bool
- };
-
- static defaultProps = {
- visible: false
- };
-
- constructor() {
- super(...arguments);
- this.id = this.props.id + ':' + this.props.svgId;
- map[this.id] = cloneElement(onlyChild(this.props.children), {
- id: null
- });
- }
-
- componentWillReceiveProps = nextProps => {
- let id = nextProps.id + ':' + nextProps.svgId;
- if (id !== this.id) {
- delete map[this.id];
- }
- map[id] = cloneElement(onlyChild(nextProps.children), {
- id: null
- });
- };
-
- componentWillUnmount = () => {
- delete map[this.id];
- };
-
- render() {
- return this.props.visible ? onlyChild(this.props.children) : ;
- }
-}
-
-let idReg = /^#(.+)/;
-class DefsUse extends Component{
- static displayName = 'DefsUse';
- static propType = {
- href: PropTypes.string
- };
- render() {
- let href = this.props.href;
- if (href) {
- let matched = href.match(idReg);
- if (matched) {
- let template = map[matched[1] + ':' + this.props.svgId];
- if (template) {
- return cloneElement(template, {
- ...this.props,
- href: null
- });
- }
- }
- }
-
- console.warn(`Invalid href: '${href}' for Use element.\n Please check if '${href}' if defined`);
- return ;
- }
-}
-
-// TODO: defination scope, global or local?
-class Defs extends Component{
+class Defs extends Component {
static displayName = 'Defs';
- static Item = DefsItem;
- static Use = DefsUse;
-
- getChildren = () => {
- return Children.map(this.props.children, child => {
- let {type} = child;
-
- if (type === LinearGradient || type === RadialGradient || type === ClipPath) {
- return cloneElement(child, {
- svgId: this.props.svgId
- });
- }
- if (child.props.id) {
- return {child};
- }
- });
- };
render() {
- return {this.getChildren()};
+ return {this.props.children};
}
}
+const RNSVGDefination = createReactNativeComponentClass({
+ validAttributes: {},
+ uiViewClassName: 'RNSVGDefination'
+});
+
export default Defs;
diff --git a/elements/Ellipse.js b/elements/Ellipse.js
index 31eb41b4..7beece7f 100644
--- a/elements/Ellipse.js
+++ b/elements/Ellipse.js
@@ -15,9 +15,7 @@ class Ellipse extends Shape{
static contextTypes = {
...fillProps,
...strokeProps,
- ...ellipseProps,
- isInGroup: PropTypes.bool,
- svgId: numberProp
+ ...ellipseProps
};
setNativeProps = (...args) => {
diff --git a/elements/G.js b/elements/G.js
index 9c7fdcd2..94d34dbe 100644
--- a/elements/G.js
+++ b/elements/G.js
@@ -1,5 +1,4 @@
import React, {Component, PropTypes} from 'react';
-import Defs from './Defs';
import _ from 'lodash';
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
import {numberProp, contextProps} from '../lib/props';
@@ -10,13 +9,10 @@ class G extends Component{
static displayName = 'G';
static contextTypes = {
- svgId: numberProp,
...contextProps
};
static childContextTypes = {
- svgId: numberProp,
- isInGroup: PropTypes.bool,
...contextProps
};
@@ -26,43 +22,23 @@ class G extends Component{
props[key] = this.props[key];
}
return props;
- }, {
- svgId: this.props.svgId || this.context.svgId,
- isInGroup: true
- });
+ }, {});
+
return _.defaults({}, this.context, context);
};
setNativeProps = (...args) => {
- this.getNativeElement().setNativeProps(...args);
- };
-
- getNativeElement = () => {
- return this.refs.root || this.root;
+ this.root.setNativeProps(...args);
};
render() {
- if (this.props.id) {
- return
- this.root = ele.refs.root}
- id={null}
- />
- ;
- } else {
- return
- {this.props.children}
- ;
- }
+ return this.root = ele}
+ asClipPath={this.props.asClipPath}
+ >
+ {this.props.children}
+ ;
}
}
diff --git a/elements/Line.js b/elements/Line.js
index dd76166b..19a2dafc 100644
--- a/elements/Line.js
+++ b/elements/Line.js
@@ -15,9 +15,7 @@ class Line extends Shape {
static contextTypes = {
...fillProps,
...strokeProps,
- ...lineProps,
- isInGroup: PropTypes.bool,
- svgId: numberProp
+ ...lineProps
};
setNativeProps = (...args) => {
diff --git a/elements/Path.js b/elements/Path.js
index a91776d7..a78f9fe4 100644
--- a/elements/Path.js
+++ b/elements/Path.js
@@ -1,5 +1,4 @@
import React, {PropTypes} from 'react';
-import Defs from './Defs';
import SerializablePath from '../lib/SerializablePath';
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
import {PathAttributes} from '../lib/attributes';
@@ -16,9 +15,7 @@ class Path extends Shape {
};
static contextTypes = {
- ...pathProps,
- isInGroup: PropTypes.bool,
- svgId: numberProp
+ ...pathProps
};
@@ -31,34 +28,16 @@ class Path extends Shape {
};
setNativeProps = (...args) => {
- this.getNativeElement().setNativeProps(...args);
- };
-
- getNativeElement = () => {
- return this.refs.root || this.root;
+ this.root.setNativeProps(...args);
};
render() {
let props = mergeContext(this.props, this.context);
- if (props.id) {
- return
- this.root = ele.refs.root}
- {...props}
- id={null}
- />
- ;
- }
-
let d = new SerializablePath(props.d).toJSON();
return (
this.root = ele}
{...this.extractProps(props)}
d={d}
/>
diff --git a/elements/Rect.js b/elements/Rect.js
index bc315b0d..11879a61 100644
--- a/elements/Rect.js
+++ b/elements/Rect.js
@@ -16,9 +16,7 @@ class Rect extends Shape {
static contextTypes = {
...fillProps,
...strokeProps,
- ...rectProps,
- isInGroup: PropTypes.bool,
- svgId: numberProp
+ ...rectProps
};
setNativeProps = (...args) => {
diff --git a/elements/Shape.js b/elements/Shape.js
index 9d859e53..8e8120c4 100644
--- a/elements/Shape.js
+++ b/elements/Shape.js
@@ -12,8 +12,8 @@ class Shape extends Component {
this.state = this.touchableGetInitialState();
}
- extractProps = (props) => {
- let extractedProps = extractProps(props);
+ extractProps = (props, options = {stroke: true, fill: true, responder: true}) => {
+ let extractedProps = extractProps(props, options);
if (extractedProps.touchable && !extractedProps.disabled) {
_.assign(extractedProps, {
onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder,
diff --git a/elements/Text.js b/elements/Text.js
index c4a8b62f..e3b8f8f7 100644
--- a/elements/Text.js
+++ b/elements/Text.js
@@ -20,17 +20,11 @@ class Text extends Shape {
static contextTypes = {
...textProps,
...fillProps,
- ...strokeProps,
- isInGroup: PropTypes.bool,
- svgId: numberProp
+ ...strokeProps
};
setNativeProps = (...args) => {
- this.getNativeElement().setNativeProps(...args);
- };
-
- getNativeElement = () => {
- return this.refs.root || this.root;
+ this.root.setNativeProps(...args);
};
render() {
@@ -45,21 +39,9 @@ class Text extends Shape {
y = props.dy ? +props.y + (+props.dy) : +props.y;
}
- if (this.props.id) {
- return this.root = ele.refs.root}
- id={this.props.id}
- svgId={this.props.svgId}
- visible={true}
- text={true}
- >
-
- ;
- }
-
return (
this.root = ele}
{...extractProps({...props, x, y})}
{...extractText(props)}
/>
diff --git a/elements/Use.js b/elements/Use.js
index 7f42dee0..7e86a4dd 100644
--- a/elements/Use.js
+++ b/elements/Use.js
@@ -1,14 +1,54 @@
-import React, {Component, PropTypes} from 'react';
-import Defs from './Defs';
-class Use extends Component{
+import {PropTypes} from 'react';
+import {pathProps} from '../lib/props';
+import {UseAttributes} from '../lib/attributes';
+import Shape from './Shape';
+import React from 'react';
+import patternReg from '../lib/extract/patternReg';
+import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
+
+class Defs extends Shape {
static displayName = 'Use';
- static propType = {
- href: PropTypes.string
+
+ static propTypes = {
+ href: PropTypes.string.isRequired,
+ ...pathProps
+ };
+
+ setNativeProps = (...args) => {
+ this.root.setNativeProps(...args);
};
render() {
- return ;
+ let {props} = this;
+ // 尝试匹配 "url(#pattern)"
+ let matched = props.href.match(patternReg);
+ let href;
+
+ if (matched) {
+ href = matched[1];
+ }
+
+ if (!href) {
+ console.warn('Invalid `href` prop for `Use` element, expected a href like `"url(#id)"`, but got: "' + props.href + '"');
+ }
+
+ return this.root = ele}
+ {...this.extractProps(props, {
+ stroke: true,
+ fill: true,
+ responder: true,
+ transform: true
+ })}
+ href={href}
+ >{props.children};
}
}
-export default Use;
+const RNSVGUse = createReactNativeComponentClass({
+ validAttributes: UseAttributes,
+ uiViewClassName: 'RNSVGUse'
+});
+
+export default Defs;
+
diff --git a/ios/Elements/RNSVGClipPath.h b/ios/Elements/RNSVGClipPath.h
index 84fd6eac..d99db001 100644
--- a/ios/Elements/RNSVGClipPath.h
+++ b/ios/Elements/RNSVGClipPath.h
@@ -13,7 +13,6 @@
#import "RNSVGSvgView.h"
@interface RNSVGClipPath : RNSVGGroup
-@property (nonatomic, strong) NSString *name;
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
diff --git a/ios/Elements/RNSVGClipPath.m b/ios/Elements/RNSVGClipPath.m
index b4041d75..a1d0764b 100644
--- a/ios/Elements/RNSVGClipPath.m
+++ b/ios/Elements/RNSVGClipPath.m
@@ -10,16 +10,23 @@
@implementation RNSVGClipPath
-- (void)renderLayerTo:(CGContextRef)context
+- (void)saveDefination:(CGContextRef)context
{
[[self getSvgView] defineClipPath:[self getPath:context] clipPathRef:self.name];
}
-// hitTest delagate
-
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return nil;
}
+- (void)removeDefination
+{
+ if (self.name) {
+ [[self getSvgView] removeClipPath: self.name];
+ }
+}
+
+
+
@end
diff --git a/ios/Elements/RNSVGDefination.h b/ios/Elements/RNSVGDefination.h
new file mode 100644
index 00000000..dee64827
--- /dev/null
+++ b/ios/Elements/RNSVGDefination.h
@@ -0,0 +1,21 @@
+/**
+ * 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 "RNSVGNode.h"
+
+/**
+ * RNSVG defination are implemented as abstract UIViews for all elements inside Defs.
+ */
+
+@interface RNSVGDefination : RNSVGNode
+
+- (void)renderTo:(CGContextRef)context;
+
+- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
+
+@end
diff --git a/ios/Elements/RNSVGDefination.m b/ios/Elements/RNSVGDefination.m
new file mode 100644
index 00000000..6ef998c7
--- /dev/null
+++ b/ios/Elements/RNSVGDefination.m
@@ -0,0 +1,27 @@
+/**
+ * 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 "RNSVGDefination.h"
+
+@class RNSVGNode;
+
+@implementation RNSVGDefination
+
+- (void)renderTo:(CGContextRef)context
+{
+ for (RNSVGNode *node in self.subviews) {
+ [node saveDefination: context];
+ }
+}
+
+- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
+{
+ return nil;
+}
+
+@end
+
diff --git a/ios/Elements/RNSVGGroup.m b/ios/Elements/RNSVGGroup.m
index 39b14b19..7abb2c76 100644
--- a/ios/Elements/RNSVGGroup.m
+++ b/ios/Elements/RNSVGGroup.m
@@ -7,6 +7,7 @@
*/
#import "RNSVGGroup.h"
+#import
@implementation RNSVGGroup
@@ -35,17 +36,39 @@
}
// hitTest delagate
-
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
for (RNSVGNode *node in [self.subviews reverseObjectEnumerator]) {
UIView *view = [node hitTest: point withEvent:event];
- if (view != NULL) {
+ if (view) {
return view;
}
}
return nil;
}
+- (void)saveDefination:(CGContextRef)context
+{
+ if (self.name) {
+ RNSVGSvgView* svg = [self getSvgView];
+ [svg defineTemplate:self templateRef:self.name];
+ }
+
+ for (RNSVGNode *node in self.subviews) {
+ [node saveDefination:context];
+ }
+}
+
+- (void)willRemoveSubview:(UIView *)subview
+{
+ [super willRemoveSubview:subview];
+}
+
+- (void)mergeProperties:(__kindof RNSVGNode *)target
+{
+ for (RNSVGNode *node in self.subviews) {
+ [node mergeProperties:target];
+ }
+}
@end
diff --git a/ios/Elements/RNSVGSvgView.h b/ios/Elements/RNSVGSvgView.h
index da0cf80a..3caccff6 100644
--- a/ios/Elements/RNSVGSvgView.h
+++ b/ios/Elements/RNSVGSvgView.h
@@ -10,6 +10,8 @@
#import "RNSVGContainer.h"
+@class RNSVGNode;
+
@interface RNSVGSvgView : UIView
@property (nonatomic, assign) BOOL responsible;
@@ -17,10 +19,16 @@
/**
* define content as clipPath template.
*/
-- (void)defineClipPath:(CGPathRef)clipPath clipPathRef:(NSString *)clipPathId;
+- (void)defineClipPath:(CGPathRef)clipPath clipPathRef:(NSString *)clipPathRef;
- (void)removeClipPath:(NSString *)clipPathRef;
- (CGPathRef)getDefinedClipPath:(NSString *)clipPathRef;
+- (void)defineTemplate:(RNSVGNode *)template templateRef:(NSString *)templateRef;
+
+- (void)removeTemplate:(NSString *)tempalteRef;
+
+- (RNSVGNode *)getDefinedTemplate:(NSString *)tempalteRef;
+
@end
diff --git a/ios/Elements/RNSVGSvgView.m b/ios/Elements/RNSVGSvgView.m
index 6a0c0825..bb63d89d 100644
--- a/ios/Elements/RNSVGSvgView.m
+++ b/ios/Elements/RNSVGSvgView.m
@@ -13,7 +13,8 @@
@implementation RNSVGSvgView
{
- NSMutableDictionary *clipPaths;
+ NSMutableDictionary *clipPaths;
+ NSMutableDictionary *templates;
}
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
@@ -42,8 +43,9 @@
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
-
+
for (RNSVGNode *node in self.subviews) {
+ [node saveDefination:context];
[node renderTo:context];
if (node.responsible && !self.responsible) {
@@ -64,7 +66,7 @@
- (void)defineClipPath:(CGPathRef)clipPath clipPathRef:(NSString *)clipPathRef
{
- if (clipPaths == NULL) {
+ if (!clipPaths) {
clipPaths = [[NSMutableDictionary alloc] init];
}
[clipPaths setValue:[NSValue valueWithPointer:clipPath] forKey:clipPathRef];
@@ -72,14 +74,34 @@
- (void)removeClipPath:(NSString *)clipPathRef
{
- if (clipPaths != NULL) {
+ if (clipPaths) {
[clipPaths removeObjectForKey:clipPathRef];
}
}
- (CGPathRef)getDefinedClipPath:(NSString *)clipPathRef
{
- return [[clipPaths valueForKey:clipPathRef] pointerValue];
+ return clipPaths ? [[clipPaths valueForKey:clipPathRef] pointerValue] : nil;
+}
+
+- (void)defineTemplate:(RNSVGNode *)template templateRef:(NSString *)templateRef
+{
+ if (!templates) {
+ templates = [[NSMutableDictionary alloc] init];
+ }
+ [templates setObject:template forKey:templateRef];
+}
+
+- (void)removeTemplate:(NSString *)tempalteRef
+{
+ if (templates) {
+ [templates removeObjectForKey:tempalteRef];
+ }
+}
+
+- (RNSVGNode *)getDefinedTemplate:(NSString *)tempalteRef
+{
+ return templates ? [templates objectForKey:tempalteRef] : nil;
}
@end
diff --git a/ios/Elements/RNSVGUse.h b/ios/Elements/RNSVGUse.h
new file mode 100644
index 00000000..54a4578f
--- /dev/null
+++ b/ios/Elements/RNSVGUse.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 "RNSVGRenderable.h"
+
+/**
+ * RNSVG defination are implemented as abstract UIViews for all elements inside Defs.
+ */
+
+@interface RNSVGUse : RNSVGRenderable
+
+@property (nonatomic, strong) NSString *href;
+
+@end
diff --git a/ios/Elements/RNSVGUse.m b/ios/Elements/RNSVGUse.m
new file mode 100644
index 00000000..c5528677
--- /dev/null
+++ b/ios/Elements/RNSVGUse.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 "RNSVGUse.h"
+#import "RCTLog.h"
+
+@implementation RNSVGUse
+
+- (void)renderLayerTo:(CGContextRef)context
+{
+ RNSVGNode* template = [[self getSvgView] getDefinedTemplate:self.href];
+ if (template) {
+ [template mergeProperties:self];
+ [template renderTo:context];
+ } else if (self.href) {
+ // TODO: calling yellow box here
+ RCTLogWarn(@"`Use` element expected a pre-defined svg template as `href` prop, template named: %@ is not defined.", self.href);
+ }
+}
+
+@end
+
diff --git a/ios/RNSVG.xcodeproj/project.pbxproj b/ios/RNSVG.xcodeproj/project.pbxproj
index f56650f3..a6151799 100644
--- a/ios/RNSVG.xcodeproj/project.pbxproj
+++ b/ios/RNSVG.xcodeproj/project.pbxproj
@@ -13,6 +13,10 @@
0CF68B0D1AF0549300FF9E5C /* RNSVGPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF01AF0549300FF9E5C /* RNSVGPattern.m */; };
0CF68B0E1AF0549300FF9E5C /* RNSVGRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF21AF0549300FF9E5C /* RNSVGRadialGradient.m */; };
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF41AF0549300FF9E5C /* RNSVGSolidColor.m */; };
+ 1023B48D1D3DDCCE0051496D /* RNSVGDefinationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1023B48C1D3DDCCE0051496D /* RNSVGDefinationManager.m */; };
+ 1023B4901D3DF4C40051496D /* RNSVGDefination.m in Sources */ = {isa = PBXBuildFile; fileRef = 1023B48F1D3DF4C40051496D /* RNSVGDefination.m */; };
+ 1023B4931D3DF5060051496D /* RNSVGUse.m in Sources */ = {isa = PBXBuildFile; fileRef = 1023B4921D3DF5060051496D /* RNSVGUse.m */; };
+ 1023B4961D3DF57D0051496D /* RNSVGUseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1023B4951D3DF57D0051496D /* RNSVGUseManager.m */; };
1039D2891CE71EB7001E90A8 /* RNSVGGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2821CE71EB7001E90A8 /* RNSVGGroup.m */; };
1039D28A1CE71EB7001E90A8 /* RNSVGImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2841CE71EB7001E90A8 /* RNSVGImage.m */; };
1039D28B1CE71EB7001E90A8 /* RNSVGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2861CE71EB7001E90A8 /* RNSVGPath.m */; };
@@ -68,6 +72,14 @@
0CF68AF21AF0549300FF9E5C /* RNSVGRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGRadialGradient.m; sourceTree = ""; };
0CF68AF31AF0549300FF9E5C /* RNSVGSolidColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSolidColor.h; sourceTree = ""; };
0CF68AF41AF0549300FF9E5C /* RNSVGSolidColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSolidColor.m; sourceTree = ""; };
+ 1023B48B1D3DDCCE0051496D /* RNSVGDefinationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGDefinationManager.h; sourceTree = ""; };
+ 1023B48C1D3DDCCE0051496D /* RNSVGDefinationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGDefinationManager.m; sourceTree = ""; };
+ 1023B48E1D3DF4C40051496D /* RNSVGDefination.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGDefination.h; path = Elements/RNSVGDefination.h; sourceTree = ""; };
+ 1023B48F1D3DF4C40051496D /* RNSVGDefination.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGDefination.m; path = Elements/RNSVGDefination.m; sourceTree = ""; };
+ 1023B4911D3DF5060051496D /* RNSVGUse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGUse.h; path = Elements/RNSVGUse.h; sourceTree = ""; };
+ 1023B4921D3DF5060051496D /* RNSVGUse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGUse.m; path = Elements/RNSVGUse.m; sourceTree = ""; };
+ 1023B4941D3DF57D0051496D /* RNSVGUseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGUseManager.h; sourceTree = ""; };
+ 1023B4951D3DF57D0051496D /* RNSVGUseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGUseManager.m; sourceTree = ""; };
1039D2811CE71EB7001E90A8 /* RNSVGGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGGroup.h; path = Elements/RNSVGGroup.h; sourceTree = ""; };
1039D2821CE71EB7001E90A8 /* RNSVGGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGGroup.m; path = Elements/RNSVGGroup.m; sourceTree = ""; };
1039D2831CE71EB7001E90A8 /* RNSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGImage.h; path = Elements/RNSVGImage.h; sourceTree = ""; };
@@ -185,6 +197,10 @@
0CF68AF81AF0549300FF9E5C /* ViewManagers */ = {
isa = PBXGroup;
children = (
+ 1023B4941D3DF57D0051496D /* RNSVGUseManager.h */,
+ 1023B4951D3DF57D0051496D /* RNSVGUseManager.m */,
+ 1023B48B1D3DDCCE0051496D /* RNSVGDefinationManager.h */,
+ 1023B48C1D3DDCCE0051496D /* RNSVGDefinationManager.m */,
10ED4A9C1CF0656A0078BC02 /* RNSVGClipPathManager.h */,
10ED4A9D1CF0656A0078BC02 /* RNSVGClipPathManager.m */,
10BA0D1C1CE74E3100887C2B /* RNSVGCircleManager.h */,
@@ -245,6 +261,10 @@
1039D2801CE71DCF001E90A8 /* Elements */ = {
isa = PBXGroup;
children = (
+ 1023B4911D3DF5060051496D /* RNSVGUse.h */,
+ 1023B4921D3DF5060051496D /* RNSVGUse.m */,
+ 1023B48E1D3DF4C40051496D /* RNSVGDefination.h */,
+ 1023B48F1D3DF4C40051496D /* RNSVGDefination.m */,
10ED4A991CF065260078BC02 /* RNSVGClipPath.h */,
10ED4A9A1CF065260078BC02 /* RNSVGClipPath.m */,
1039D2811CE71EB7001E90A8 /* RNSVGGroup.h */,
@@ -336,6 +356,7 @@
10BA0D491CE74E3D00887C2B /* RNSVGEllipse.m in Sources */,
1039D28B1CE71EB7001E90A8 /* RNSVGPath.m in Sources */,
0CF68B0D1AF0549300FF9E5C /* RNSVGPattern.m in Sources */,
+ 1023B4931D3DF5060051496D /* RNSVGUse.m in Sources */,
0CF68B0E1AF0549300FF9E5C /* RNSVGRadialGradient.m in Sources */,
1039D2951CE71EC2001E90A8 /* RNSVGText.m in Sources */,
10BA0D3B1CE74E3100887C2B /* RNSVGRectManager.m in Sources */,
@@ -352,6 +373,7 @@
0CF68B0C1AF0549300FF9E5C /* RNSVGLinearGradient.m in Sources */,
10BA0D371CE74E3100887C2B /* RNSVGImageManager.m in Sources */,
10BA0D391CE74E3100887C2B /* RNSVGNodeManager.m in Sources */,
+ 1023B4901D3DF4C40051496D /* RNSVGDefination.m in Sources */,
10BA0D381CE74E3100887C2B /* RNSVGLineManager.m in Sources */,
10BA0D481CE74E3D00887C2B /* RNSVGCircle.m in Sources */,
10BA0D351CE74E3100887C2B /* RNSVGEllipseManager.m in Sources */,
@@ -360,6 +382,8 @@
10BA0D361CE74E3100887C2B /* RNSVGGroupManager.m in Sources */,
10BA0D4A1CE74E3D00887C2B /* RNSVGLine.m in Sources */,
1039D28C1CE71EB7001E90A8 /* RNSVGSvgView.m in Sources */,
+ 1023B4961D3DF57D0051496D /* RNSVGUseManager.m in Sources */,
+ 1023B48D1D3DDCCE0051496D /* RNSVGDefinationManager.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/ios/RNSVGNode.h b/ios/RNSVGNode.h
index 072d720a..57004656 100644
--- a/ios/RNSVGNode.h
+++ b/ios/RNSVGNode.h
@@ -11,21 +11,22 @@
#import "RNSVGSvgView.h"
/**
- * RNSVG nodes are implemented as empty UIViews but this is just an implementation detail to fit
- * into the existing view management. They should also be shadow views and painted on a background
- * thread.
+ * RNSVG nodes are implemented as base UIViews. They should be implementation for all basic
+ *interfaces for all non-defination nodes.
*/
@interface RNSVGNode : UIView
-@property (nonatomic, assign) CGRect rect;
+@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) CGFloat opacity;
@property (nonatomic, assign) RNSVGCGFCRule clipRule;
@property (nonatomic, assign) CGPathRef clipPath; // convert clipPath="M0,0 L0,10 L10,10z" into path
@property (nonatomic, strong) NSString *clipPathRef; // use clipPath="url(#clip)" as ClipPath
@property (nonatomic, assign) BOOL responsible;
+
- (void)invalidate;
+
- (void)renderTo:(CGContextRef)context;
/**
@@ -36,20 +37,41 @@
- (void)renderLayerTo:(CGContextRef)context;
/**
- * clip node by clipPath or clipPathId.
+ * clip node by clipPath or clipPathRef.
*/
- (void)clip:(CGContextRef)context;
+/**
+ * get clip path for current node.
+ */
- (CGPathRef)getClipPath;
/**
* getPath will return the path inside node as a ClipPath.
*/
-- (CGPathRef)getPath: (CGContextRef) context;
+- (CGPathRef)getPath:(CGContextRef) context;
+/**
+ * run hitTest
+ */
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
- (RNSVGSvgView *)getSvgView;
+/**
+ * save element`s defination into svg element.
+ */
+- (void)saveDefination:(CGContextRef)context;
+
+/**
+ * remove element`s defination from svg element.
+ */
+- (void)removeDefination;
+
+/**
+ * merge owned properties into target element`s properties
+ */
+- (void)mergeProperties:(__kindof RNSVGNode *)target;
+
@end
diff --git a/ios/RNSVGNode.m b/ios/RNSVGNode.m
index 0ffe2a09..e83f7ab4 100644
--- a/ios/RNSVGNode.m
+++ b/ios/RNSVGNode.m
@@ -30,6 +30,17 @@
// Do nothing, as subviews are inserted by insertReactSubview:
}
+- (void)invalidate
+{
+ id container = (id)self.superview;
+ [container invalidate];
+}
+
+- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor
+{
+ self.backgroundColor = inheritedBackgroundColor;
+}
+
- (void)setOpacity:(CGFloat)opacity
{
if (opacity == _opacity) {
@@ -52,12 +63,6 @@
super.transform = transform;
}
-- (void)invalidate
-{
- id container = (id)self.superview;
- [container invalidate];
-}
-
- (void)renderTo:(CGContextRef)context
{
float opacity = self.opacity;
@@ -111,7 +116,7 @@
{
CGPathRef clipPath = [self getClipPath];
- if (clipPath != NULL) {
+ if (clipPath) {
CGContextAddPath(context, [self getClipPath]);
if (self.clipRule == kRNSVGCGFCRuleEvenodd) {
CGContextEOClip(context);
@@ -121,33 +126,68 @@
}
}
-
-- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor
-{
- self.backgroundColor = inheritedBackgroundColor;
-}
-
- (void)renderLayerTo:(CGContextRef)context
{
// abstract
}
-- (RNSVGSvgView *)getSvgView
-{
- UIView *parent = self.superview;
- while ([parent class] != [RNSVGSvgView class]) {
- parent = parent.superview;
- }
-
- return (RNSVGSvgView *)parent;
-}
-
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
{
// abstract
return nil;
}
+- (RNSVGSvgView *)getSvgView
+{
+ UIView *parent = self.superview;
+ while (parent && [parent class] != [RNSVGSvgView class]) {
+ parent = parent.superview;
+ }
+
+ return (RNSVGSvgView *)parent;
+}
+
+- (void)willRemoveFromSuperView
+{
+ if (self.subviews) {
+ for (RNSVGNode *node in self.subviews) {
+ [node willRemoveFromSuperView];
+ }
+ }
+ [self removeDefination];
+ [super removeFromSuperview];
+}
+
+/**
+ * reverse removeFromSuperview calling order.
+ * calling it from subviews to superview.
+ */
+- (void)removeFromSuperview
+{
+ [self willRemoveFromSuperView];
+}
+
+- (void)saveDefination:(CGContextRef)context
+{
+ if (self.name) {
+ RNSVGSvgView* svg = [self getSvgView];
+ [svg defineTemplate:self templateRef:self.name];
+ }
+}
+
+- (void)removeDefination
+{
+ if (self.name) {
+ [[self getSvgView] removeTemplate:self.name];
+ }
+}
+
+
+- (void)mergeProperties:(__kindof RNSVGNode *)target
+{
+ self.opacity = target.opacity * self.opacity;
+}
+
- (void)dealloc
{
CGPathRelease(_clipPath);
diff --git a/ios/RNSVGRenderable.m b/ios/RNSVGRenderable.m
index edcc7eb7..ac9abb6e 100644
--- a/ios/RNSVGRenderable.m
+++ b/ios/RNSVGRenderable.m
@@ -101,8 +101,8 @@
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGPathRef clipPath = [self getClipPath];
- if (self.nodeArea != NULL && CGPathContainsPoint(self.nodeArea, nil, point, NO)) {
- if (clipPath == NULL) {
+ if (self.nodeArea && CGPathContainsPoint(self.nodeArea, nil, point, NO)) {
+ if (!clipPath) {
return self;
} else {
return CGPathContainsPoint(clipPath, nil, point, NO) ? self : nil;
@@ -112,6 +112,40 @@
}
}
+- (void)mergeProperties:(__kindof RNSVGNode *)target
+{
+ RNSVGRenderable* renderableTarget = target;
+
+ if (renderableTarget.fill) {
+ self.fill = renderableTarget.fill;
+ }
+ if (renderableTarget.fillRule) {
+ self.fillRule = renderableTarget.fillRule;
+ }
+ if (renderableTarget.stroke) {
+ self.stroke = renderableTarget.stroke;
+ }
+ if (renderableTarget.strokeWidth) {
+ self.strokeWidth = renderableTarget.strokeWidth;
+ }
+ if (renderableTarget.strokeLinecap) {
+ self.strokeLinecap = renderableTarget.strokeLinecap;
+ }
+ if (renderableTarget.strokeLinejoin) {
+ self.strokeLinejoin = renderableTarget.strokeLinejoin;
+ }
+ if (renderableTarget.strokeMiterlimit) {
+ self.strokeMiterlimit = renderableTarget.strokeMiterlimit;
+ }
+ if (renderableTarget.strokeDasharray.count != 0) {
+ self.strokeDasharray = renderableTarget.strokeDasharray;
+ }
+ if (renderableTarget.strokeDashoffset) {
+ self.strokeDashoffset = renderableTarget.strokeDashoffset;
+ }
+ [super mergeProperties:target];
+}
+
- (void)renderLayerTo:(CGContextRef)context
{
// abstract
diff --git a/ios/Text/RNSVGText.m b/ios/Text/RNSVGText.m
index 4940d1ac..ff39d98c 100644
--- a/ios/Text/RNSVGText.m
+++ b/ios/Text/RNSVGText.m
@@ -81,7 +81,7 @@ static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
}
// We should consider snapping this shift to device pixels to improve rendering quality
// when a line has subpixel width.
- CGAffineTransform offset = CGAffineTransformMakeTranslation(-shift, frame.baseLine + frame.lineHeight * i + (self.path == NULL ? 0 : -frame.lineHeight));
+ CGAffineTransform offset = CGAffineTransformMakeTranslation(-shift, frame.baseLine + frame.lineHeight * i + (self.path ? -frame.lineHeight : 0));
CGPathAddPath(path, &offset, [self setLinePath:frame.lines[i]]);
}
@@ -115,11 +115,11 @@ static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
for(CFIndex j = 0; j < runGlyphCount; ++j, ++glyphIndex) {
CGPathRef letter = [cache pathForGlyph:glyphs[j] fromFont:runFont];
CGPoint point = positions[j];
- if (letter != NULL) {
+ if (letter) {
CGAffineTransform transform;
// draw glyphs along path
- if (self.path != NULL) {
+ if (self.path) {
CGPoint slope;
CGRect bounding = CGPathGetBoundingBox(letter);
UIBezierPath* path = [UIBezierPath bezierPathWithCGPath:self.path];
diff --git a/ios/Text/RnSVGGlyphCache.m b/ios/Text/RnSVGGlyphCache.m
index 155e5e03..9b80ba72 100644
--- a/ios/Text/RnSVGGlyphCache.m
+++ b/ios/Text/RnSVGGlyphCache.m
@@ -13,7 +13,7 @@
-(id)init
{
self = [super init];
- if(self != nil)
+ if(self)
{
cache = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
}
@@ -29,7 +29,7 @@
{
// First we lookup the font to get to its glyph dictionary
CFMutableDictionaryRef glyphDict = (CFMutableDictionaryRef)CFDictionaryGetValue(cache, font);
- if(glyphDict == NULL)
+ if(!glyphDict)
{
// And if this font hasn't been seen before, we'll create and set the dictionary for it
glyphDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
@@ -38,11 +38,11 @@
}
// Next we try to get a path for the given glyph from the glyph dictionary
CGPathRef path = (CGPathRef)CFDictionaryGetValue(glyphDict, (const void *)(uintptr_t)glyph);
- if(path == NULL)
+ if(!path)
{
// If the path hasn't been seen before, then we'll create the path from the font & glyph and cache it.
path = CTFontCreatePathForGlyph(font, glyph, NULL);
- if(path == NULL)
+ if(!path)
{
// If a glyph does not have a path, then we need a placeholder to set in the dictionary
path = (CGPathRef)kCFNull;
diff --git a/ios/Utils/RNSVGPercentageConverter.m b/ios/Utils/RNSVGPercentageConverter.m
index 4e8da6b4..3ea777ae 100644
--- a/ios/Utils/RNSVGPercentageConverter.m
+++ b/ios/Utils/RNSVGPercentageConverter.m
@@ -56,7 +56,7 @@
- (BOOL) isPercentage:(NSString *) string
{
- return [percentageRegularExpression firstMatchInString:string options:0 range:NSMakeRange(0, [string length])] != NULL;
+ return [percentageRegularExpression firstMatchInString:string options:0 range:NSMakeRange(0, [string length])] != nil;
}
@end
diff --git a/ios/ViewManagers/RNSVGDefinationManager.h b/ios/ViewManagers/RNSVGDefinationManager.h
new file mode 100644
index 00000000..146439ab
--- /dev/null
+++ b/ios/ViewManagers/RNSVGDefinationManager.h
@@ -0,0 +1,15 @@
+/**
+ * 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 "RCTViewManager.h"
+
+@interface RNSVGDefinationManager : RCTViewManager
+
+@end
+
+#import "RNSVGNode.h"
diff --git a/ios/ViewManagers/RNSVGDefinationManager.m b/ios/ViewManagers/RNSVGDefinationManager.m
new file mode 100644
index 00000000..2787ec0d
--- /dev/null
+++ b/ios/ViewManagers/RNSVGDefinationManager.m
@@ -0,0 +1,31 @@
+/**
+ * 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 "RNSVGDefination.h"
+#import "RNSVGDefinationManager.h"
+
+@implementation RNSVGDefinationManager
+
+RCT_EXPORT_MODULE()
+
+- (RNSVGDefination *)node
+{
+ return [RNSVGDefination new];
+}
+
+- (UIView *)view
+{
+ return [self node];
+}
+
+- (RCTShadowView *)shadowView
+{
+ return nil;
+}
+
+@end
diff --git a/ios/ViewManagers/RNSVGNodeManager.m b/ios/ViewManagers/RNSVGNodeManager.m
index 2514fd0d..e465f224 100644
--- a/ios/ViewManagers/RNSVGNodeManager.m
+++ b/ios/ViewManagers/RNSVGNodeManager.m
@@ -29,8 +29,9 @@ RCT_EXPORT_MODULE()
return nil;
}
+RCT_EXPORT_VIEW_PROPERTY(name, NSString)
RCT_EXPORT_VIEW_PROPERTY(opacity, CGFloat)
-RCT_EXPORT_VIEW_PROPERTY(trans, CGAffineTransform)
+RCT_EXPORT_VIEW_PROPERTY(transform, CGAffineTransform)
RCT_EXPORT_VIEW_PROPERTY(clipPathRef, NSString)
RCT_EXPORT_VIEW_PROPERTY(responsible, BOOL)
diff --git a/ios/ViewManagers/RNSVGShapeManager.h b/ios/ViewManagers/RNSVGUseManager.h
similarity index 82%
rename from ios/ViewManagers/RNSVGShapeManager.h
rename to ios/ViewManagers/RNSVGUseManager.h
index 70455e82..aa6bc346 100644
--- a/ios/ViewManagers/RNSVGShapeManager.h
+++ b/ios/ViewManagers/RNSVGUseManager.h
@@ -8,6 +8,6 @@
#import "RNSVGRenderableManager.h"
-@interface RNSVGShapeManager : RNSVGRenderableManager
+@interface RNSVGUseManager : RNSVGRenderableManager
@end
diff --git a/ios/ViewManagers/RNSVGShapeManager.m b/ios/ViewManagers/RNSVGUseManager.m
similarity index 52%
rename from ios/ViewManagers/RNSVGShapeManager.m
rename to ios/ViewManagers/RNSVGUseManager.m
index 2787b9ad..92b2d6a0 100644
--- a/ios/ViewManagers/RNSVGShapeManager.m
+++ b/ios/ViewManagers/RNSVGUseManager.m
@@ -6,20 +6,19 @@
* LICENSE file in the root directory of this source tree.
*/
-#import "RNSVGShapeManager.h"
+#import "RNSVGUseManager.h"
+#import "RNSVGUse.h"
-#import "RNSVGShape.h"
-#import "RCTConvert+RNSVG.h"
-
-@implementation RNSVGShapeManager
+@implementation RNSVGUseManager
RCT_EXPORT_MODULE()
-- (RNSVGRenderable *)node
+- (RNSVGNode *)node
{
- return [RNSVGShape new];
+ return [RNSVGUse new];
}
-RCT_EXPORT_VIEW_PROPERTY(shape, NSDictionary)
+
+RCT_EXPORT_VIEW_PROPERTY(href, NSString)
@end
diff --git a/lib/attributes.js b/lib/attributes.js
index b58eb9e3..5970b5f8 100644
--- a/lib/attributes.js
+++ b/lib/attributes.js
@@ -3,7 +3,7 @@ import _ from 'lodash';
const merge = _.assign;
function arrayDiffer(a, b) {
- if (a == null || b == null) {
+ if (_.isNil(a) || _.isNil(b) ) {
return true;
}
if (a.length !== b.length) {
@@ -79,6 +79,10 @@ const GroupAttributes = merge(NodeAttributes, {
clipRule: true
});
+const UseAttributes = merge(RenderableAttributes, {
+ href: true
+});
+
const PathAttributes = merge(RenderableAttributes, {
d: {
diff: arrayDiffer
@@ -146,5 +150,6 @@ export {
EllipseAttributes,
ImageAttributes,
LineAttributes,
- RectAttributes
+ RectAttributes,
+ UseAttributes
};
diff --git a/lib/extract/extractProps.js b/lib/extract/extractProps.js
index 6870a755..2353804c 100644
--- a/lib/extract/extractProps.js
+++ b/lib/extract/extractProps.js
@@ -6,16 +6,14 @@ import extractResponder from './extractResponder';
import _ from 'lodash';
export default function(props, options = {stroke: true, transform: true, fill: true, responder: true}) {
- if (props.visible === false) {
- return {
- opacity: 0
- };
- }
-
let extractedProps = {
opacity: +props.opacity || 1
};
+ if (props.id) {
+ extractedProps.name = props.id;
+ }
+
if (props.clipPath) {
_.assign(extractedProps, extractClipping(props));
}
@@ -30,6 +28,10 @@ export default function(props, options = {stroke: true, transform: true, fill: t
if (options.transform) {
extractedProps.transform = extractTransform(props);
+ } else if (props.transform) {
+ // todo: add support for transform prop like this:
+ // {scale: 1.5, translate: '10 10'}
+ extractedProps.transform = props.transform;
}
if (options.responder) {
diff --git a/lib/props.js b/lib/props.js
index a2bd71c3..370f7829 100644
--- a/lib/props.js
+++ b/lib/props.js
@@ -37,6 +37,10 @@ const clipProps = {
clipPath: PropTypes.string
};
+const definationProps = {
+ name: PropTypes.string
+};
+
const strokeProps = {
stroke: PropTypes.string,
strokeWidth: numberProp,
@@ -77,7 +81,8 @@ const pathProps = {
...clipProps,
...transformProps,
...responderProps,
- ...touchableProps
+ ...touchableProps,
+ ...definationProps
};
const circleProps = {