diff --git a/Example/examples.js b/Example/examples.js
index a90ced1b..5cd2a8a2 100644
--- a/Example/examples.js
+++ b/Example/examples.js
@@ -10,6 +10,7 @@ import * as Text from './examples/Text';
import * as G from './examples/G';
import * as Stroking from './examples/Stroking';
import * as Use from './examples/Use';
+import * as Symbol from './examples/Symbol';
import * as Gradients from './examples/Gradients';
export {
@@ -25,5 +26,6 @@ export {
Stroking,
G,
Use,
+ Symbol,
Gradients
};
diff --git a/Example/examples/Svg.js b/Example/examples/Svg.js
index 6aa5003d..d0720b01 100644
--- a/Example/examples/Svg.js
+++ b/Example/examples/Svg.js
@@ -72,6 +72,7 @@ class SvgViewbox extends Component{
height="100"
width="100"
viewbox="40 20 100 40"
+ preserveAspectRatio="none"
>
diff --git a/Example/examples/Symbol.js b/Example/examples/Symbol.js
new file mode 100644
index 00000000..1faa486d
--- /dev/null
+++ b/Example/examples/Symbol.js
@@ -0,0 +1,79 @@
+import React, {
+ Component
+} from 'react-native';
+
+import Svg, {
+ Symbol,
+ Circle,
+ Use
+} from 'react-native-art-svg';
+
+class SymbolExample extends Component{
+ static title = 'Symbol example';
+ render() {
+ return ;
+ }
+}
+
+const icon = ;
+
+const samples = [SymbolExample];
+
+export {
+ icon,
+ samples
+}
diff --git a/Example/main.js b/Example/main.js
index 4ebf7373..fa581bac 100644
--- a/Example/main.js
+++ b/Example/main.js
@@ -104,7 +104,7 @@ const styles = StyleSheet.create({
}
});
-const names = ['Svg', 'Stroking', 'Path', 'Line', 'Rect', 'Polygon', 'Polyline', 'Circle', 'Ellipse', 'G', 'Text', 'Use', 'Gradients'];
+const names = ['Svg', 'Stroking', 'Path', 'Line', 'Rect', 'Polygon', 'Polyline', 'Circle', 'Ellipse', 'G', 'Text', 'Use', 'Symbol', 'Gradients'];
class ArtSvgExample extends Component {
constructor() {
diff --git a/elements/Svg.js b/elements/Svg.js
index 245fe2dc..8a271d3f 100644
--- a/elements/Svg.js
+++ b/elements/Svg.js
@@ -5,74 +5,14 @@ import React, {
Children,
cloneElement
} from 'react-native';
-
+import extractViewbox from '../lib/extractViewbox';
+import ViewBox from './ViewBox';
import _ from 'lodash';
let {
Surface,
Group
} = ART;
-function extractViewbox({viewbox, width, height, preserveAspectRatio}) {
- if (!viewbox || !width || !height) {
- return false;
- }
-
- if (typeof viewbox === 'string') {
- let parts = viewbox.trim().split(/\s+/);
- let vw = +parts[2];
- let vh = +parts[3];
-
- // width or height can`t be negative
- if (vw < 0 || vh < 0 || parts.length !== 4) {
- return false;
- }
-
- // width or height equals zero disable render
- if (!vw || !vh) {
- return {
- x: 0,
- y: 0,
- scaleX: 0,
- scaleY: 0
- }
- }
-
- let vx = +parts[0] || 0;
- let vy = +parts[1] || 0;
- let preserve = preserveAspectRatio !== 'none';
- let scaleX = 1;
- let scaleY = 1;
- let x = 0;
- let y = 0;
- let sx = width / vw;
- let sy = height / vh;
-
- if (preserve) {
- scaleX = sx;
- scaleY = sy;
- x = -vx * sx;
- y = -vy * sy;
- } else {
- scaleX = scaleY = Math.min(sx, sy);
- x = width / 2 - Math.min(vw, vh) * scaleX / 2 - vx * scaleX;
- y = 0 - vy * scaleX;
-
- if (sx < sy) {
- [x, y] = [y, x];
- }
- }
-
-
- return {
- x,
- y,
- scaleX,
- scaleY
- };
- }
- return false;
-}
-
let id = 0;
class Svg extends Component{
@@ -101,36 +41,33 @@ class Svg extends Component{
};
render() {
- let opacity = +this.props.opacity;
- let viewbox = extractViewbox(this.props);
- if (viewbox) {
- let {scaleX, scaleY} = viewbox;
-
+ let {props} = this;
+ let opacity = +props.opacity;
+ if (props.viewbox) {
return
- {(!scaleX || !scaleY) ? null :
-
{this.getChildren()}
- }
+
;
}
return
+
+ {props.children}
+
+
+ }
+}
+
+export default Symbol;
diff --git a/elements/ViewBox.js b/elements/ViewBox.js
new file mode 100644
index 00000000..b4d2a287
--- /dev/null
+++ b/elements/ViewBox.js
@@ -0,0 +1,47 @@
+import React, {
+ Component,
+ PropTypes,
+ ART
+} from 'react-native';
+
+let {
+ Shape,
+} = ART;
+
+import G from './G';
+import extractViewbox from '../lib/extractViewbox';
+class ViewBox extends Component{
+ static displayName = 'ViewBox';
+ static propType = {
+ transform: PropTypes.bool
+ };
+ static defaultProps = {
+ transform: false
+ };
+
+ render() {
+ let viewbox = extractViewbox(this.props);
+ let scaleX = 1;
+ let scaleY = 1;
+ let x = 0;
+ let y = 0;
+ if (viewbox) {
+ scaleX = viewbox.scaleX;
+ scaleY = viewbox.scaleY;
+ x = viewbox.x;
+ y = viewbox.y;
+ }
+ return
+ {(!scaleX || !scaleY) ? null : this.props.children}
+
+ }
+}
+
+export default ViewBox;
diff --git a/index.js b/index.js
index fa60fbca..2301cfda 100644
--- a/index.js
+++ b/index.js
@@ -13,6 +13,7 @@ import Path from './elements/Path';
import G from './elements/G';
import Text from './elements/Text';
import Use from './elements/Use';
+import Symbol from './elements/Symbol';
import Defs from './elements/Defs';
import LinearGradient from './elements/LinearGradient';
import RadialGradient from './elements/RadialGradient';
@@ -35,6 +36,7 @@ export {
Line,
Rect,
Use,
+ Symbol,
Defs,
LinearGradient,
RadialGradient,
diff --git a/lib/extractViewbox.js b/lib/extractViewbox.js
new file mode 100644
index 00000000..c4edecb7
--- /dev/null
+++ b/lib/extractViewbox.js
@@ -0,0 +1,71 @@
+export default function({viewbox, width, height, preserveAspectRatio, x: dx, y: dy, dScale, dScaleX, dScaleY, shouldTransform}) {
+ if (!viewbox || !width || !height) {
+ return false;
+ }
+
+ if (typeof viewbox === 'string') {
+ let parts = viewbox.trim().split(/\s+/);
+ let vw = +parts[2];
+ let vh = +parts[3];
+
+ // width or height can`t be negative
+ if (vw < 0 || vh < 0 || parts.length !== 4) {
+ return false;
+ }
+
+ // width or height equals zero disable render
+ if (!vw || !vh) {
+ return {
+ x: 0,
+ y: 0,
+ scaleX: 0,
+ scaleY: 0
+ }
+ }
+
+ let vx = +parts[0] || 0;
+ let vy = +parts[1] || 0;
+ let preserve = preserveAspectRatio !== 'none';
+ let scaleX = 1;
+ let scaleY = 1;
+ let x = 0;
+ let y = 0;
+ let sx = width / vw;
+ let sy = height / vh;
+ if (preserve) {
+ scaleX = scaleY = Math.min(sx, sy);
+ x = width / 2 - Math.min(vw, vh) * scaleX / 2 - vx * scaleX;
+ y = 0 - vy * scaleX;
+
+ if (sx < sy) {
+ [x, y] = [y, x];
+ }
+ } else {
+ scaleX = sx;
+ scaleY = sy;
+ x = -vx * sx;
+ y = -vy * sy;
+ }
+
+ if (shouldTransform) {
+ x += (+dx || 0);
+ y += (+dy || 0);
+
+ if (dScale) {
+ scaleX *= (+dScale || 1);
+ scaleY *= (+dScale || 1);
+ } else {
+ scaleX *= (+dScaleX || 1);
+ scaleY *= (+dScaleY || 1);
+ }
+ }
+
+ return {
+ x,
+ y,
+ scaleX,
+ scaleY
+ };
+ }
+ return false;
+}