From e001285cbe4d36bf690d59fca58535af62dea400 Mon Sep 17 00:00:00 2001 From: Horcrux Date: Mon, 25 Jan 2016 11:39:31 +0800 Subject: [PATCH] Refactor reuse elements Refactor reuse elements --- Example/examples/Text.js | 26 +++++++++- Example/examples/Use.js | 13 +++-- Example/main.js | 3 -- Example/package.json | 4 +- elements/Circle.js | 3 +- elements/Defs.js | 103 +++++++++++++++++++++++++++++---------- elements/Ellipse.js | 9 +--- elements/G.js | 27 +++++----- elements/Line.js | 1 - elements/Path.js | 18 ++++--- elements/Polygon.js | 2 - elements/Polyline.js | 3 +- elements/Rect.js | 5 +- elements/Text.js | 16 +++--- elements/Use.js | 24 ++------- index.js | 15 ++++-- 16 files changed, 171 insertions(+), 101 deletions(-) diff --git a/Example/examples/Text.js b/Example/examples/Text.js index 7d22ce0b..2f70594a 100644 --- a/Example/examples/Text.js +++ b/Example/examples/Text.js @@ -47,13 +47,35 @@ class TextRotate extends Component{ x="126" y="24" fill="#f60" - rotate="16" + rotate="78" scale="1.36" + origin="20, 0" >I love SVG ; } } +class TextStroke extends Component{ + static title = 'Stroke the text'; + render() { + return + STROKED TEXT + ; + } +} + + // TODO: wait for official done class TextPath extends Component{ static title = 'Transform the text'; @@ -90,7 +112,7 @@ const icon = ; -const samples = [TextExample, TextRotate]; +const samples = [TextExample, TextRotate, TextStroke]; export { icon, diff --git a/Example/examples/Use.js b/Example/examples/Use.js index ee324a9d..68f34bd1 100644 --- a/Example/examples/Use.js +++ b/Example/examples/Use.js @@ -7,7 +7,8 @@ import Svg, { Use, G, Rect, - Circle + Circle, + Polyline } from 'react-native-art-svg'; class UseExample extends Component{ @@ -42,8 +43,8 @@ class UseShapes extends Component{ - + ; }; @@ -53,7 +54,13 @@ const icon = - + + ; const samples = [UseExample, UseShapes]; diff --git a/Example/main.js b/Example/main.js index 1f911cac..70a44d11 100644 --- a/Example/main.js +++ b/Example/main.js @@ -23,9 +23,7 @@ import { Line } from 'react-native-art-svg'; import * as examples from './examples'; -import _ from 'lodash'; import Modal from 'react-native-root-modal'; - const hairline = 1 / PixelRatio.get(); const styles = StyleSheet.create({ @@ -106,7 +104,6 @@ const styles = StyleSheet.create({ } }); - const names = ['Svg', 'Stroking', 'Path', 'Line', 'Rect', 'Polygon', 'Polyline', 'Circle', 'Ellipse', 'G', 'Text', 'Use']; class ArtSvgExample extends Component { diff --git a/Example/package.json b/Example/package.json index 48055ed9..373ca2d7 100644 --- a/Example/package.json +++ b/Example/package.json @@ -6,6 +6,8 @@ "start": "react-native start" }, "dependencies": { - "react-native": "^0.18.1" + "react-native": "^0 .18.1", + "react-native-art-svg": "^1.0.1", + "react-native-root-modal": "^1.0.2" } } diff --git a/elements/Circle.js b/elements/Circle.js index 72f27451..59c29623 100644 --- a/elements/Circle.js +++ b/elements/Circle.js @@ -14,13 +14,12 @@ class Circle extends Component{ }; static defaultProps = { cx: 0, - ct: 0 + cy: 0 }; render() { return { + 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) { + let props = { + ...this.props, + href: null + }; + return cloneElement(template, props); + } + } + } + + console.warn(`Invalid href: '${href}' for Use element.\n Please check if '${href}' if defined`); + return ; + } +} + // TODO: more details should be handled(different Svg namespace、(remove, add, update) Defs children) class Defs extends Component{ static displayName = 'Defs'; - static get = uid => { - return map[uid]; - }; + static Item = DefsItem; + static Use = DefsUse; - static set = (uid, element) => { - map[uid] = element; - }; - - componentWillMount = () => { - this.getDefines(this.props.children); - }; - - componentWillReceiveProps = nextProps => { - this.getDefines(nextProps); - }; - - getDefines = children => { - Children.map(children, child => { - let {props: {id}} = child; - if (id) { - console.log(id + ':' + this.props.svgId); - map[id + ':' + this.props.svgId] = cloneElement(child, { - id: null - }); + getChildren = () => { + return Children.map(this.props.children, child => { + if (child.props.id) { + return {child}; } }); }; render() { - return ; + return + {this.getChildren()} + ; } } diff --git a/elements/Ellipse.js b/elements/Ellipse.js index c9d833b4..25f0f051 100644 --- a/elements/Ellipse.js +++ b/elements/Ellipse.js @@ -5,10 +5,7 @@ import React, { } from 'react-native'; import fillFilter from '../lib/fillFilter'; import strokeFilter from '../lib/strokeFilter'; - -let { - Shape -} = ART; +import Path from './Path'; let propType = PropTypes.oneOfType([PropTypes.string, PropTypes.number]); class Ellipse extends Component{ @@ -28,10 +25,8 @@ class Ellipse extends Component{ a ${rx}, ${ry} 0 1, 0 ${-rx * 2}, 0 Z `; - return cloneElement(child, { + getChildren = () => { + return Children.map(this.props.children, child => cloneElement(child, { ...this.props, ...transformProps, ...child.props, @@ -39,15 +36,21 @@ class G extends Component{ }; render() { - let element = {this.children}; if (this.props.id) { - Defs.set(this.props.id + ':' + this.props.svgId, ); + return + + ; + } else { + return {this.getChildren()}; } - return element; } } diff --git a/elements/Line.js b/elements/Line.js index 4348dd0b..4faec2ec 100644 --- a/elements/Line.js +++ b/elements/Line.js @@ -31,7 +31,6 @@ class Line extends Component{ x2={null} y2={null} fill={null} - {...strokeFilter(props)} d={d} />; } diff --git a/elements/Path.js b/elements/Path.js index 38248477..2d3774d1 100644 --- a/elements/Path.js +++ b/elements/Path.js @@ -4,7 +4,6 @@ import React, { PropTypes, cloneElement } from 'react-native'; - let { Shape } = ART; @@ -12,6 +11,7 @@ import Defs from './Defs'; import fillFilter from '../lib/fillFilter'; import strokeFilter from '../lib/strokeFilter'; +import transformFilter from '../lib/transformFilter'; let propType = PropTypes.oneOfType([PropTypes.string, PropTypes.number]); class Path extends Component{ static displayName = 'Path'; @@ -27,16 +27,22 @@ class Path extends Component{ }; render() { let {props} = this; - let element = + + ; + } + return ; - if (this.props.id) { - Defs.set(this.props.id + ':' + this.props.svgId, ); - } - return element; } } diff --git a/elements/Polygon.js b/elements/Polygon.js index 2aa88e7e..5984e75d 100644 --- a/elements/Polygon.js +++ b/elements/Polygon.js @@ -17,8 +17,6 @@ class Polygon extends Component{ let d = 'M' + props.points.trim().replace(/\s+/g, 'L') + 'z'; return ; diff --git a/elements/Polyline.js b/elements/Polyline.js index 1896e2d5..bab6b9d9 100644 --- a/elements/Polyline.js +++ b/elements/Polyline.js @@ -8,6 +8,7 @@ import Path from './Path'; import strokeFilter from '../lib/strokeFilter'; import fillFilter from '../lib/fillFilter'; +import transformFilter from '../lib/transformFilter'; class Polyline extends Component{ static displayName = 'Polyline'; static propTypes = { @@ -22,8 +23,6 @@ class Polyline extends Component{ let d = 'M' + props.points.trim().replace(/\s+/g, 'L'); return ; diff --git a/elements/Rect.js b/elements/Rect.js index f8765c77..237c1565 100644 --- a/elements/Rect.js +++ b/elements/Rect.js @@ -89,10 +89,7 @@ class Rect extends Component{ ry={null} width={null} height={null} - {...strokeFilter(props)} - fill={fillFilter(props)} - {...transformFilter(props)} - x={null} + x={rx || null} y={null} d={d} />; diff --git a/elements/Text.js b/elements/Text.js index 5dd2b57d..eab26c8c 100644 --- a/elements/Text.js +++ b/elements/Text.js @@ -3,7 +3,6 @@ import React, { Component, PropTypes } from 'react-native'; - let { Text:ARTText } = ART; @@ -34,7 +33,16 @@ class Text extends Component{ y = props.dy ? +props.y + (+props.dy) : +props.y; } - let element = + + ; + } + return ; - if (this.props.id) { - Defs.set(this.props.id + ':' + this.props.svgId, ); - } - return element; } } diff --git a/elements/Use.js b/elements/Use.js index 4c0920e9..261fe9a5 100644 --- a/elements/Use.js +++ b/elements/Use.js @@ -1,13 +1,10 @@ import React, { Component, PropTypes, - ART, - cloneElement + ART } from 'react-native'; -let {Group} = ART; + import Defs from './Defs'; -import transformFilter from '../lib/transformFilter'; -let idReg = /^#(.+)/; class Use extends Component{ static displayName = 'Use'; static propType = { @@ -15,22 +12,7 @@ class Use extends Component{ }; render() { - let href = this.props.href; - if (href) { - let matched = href.match(idReg); - if (matched) { - let template = Defs.get(matched[1] + ':' + this.props.svgId); - if (template) { - let props = { - ...this.props, - href: null - }; - return cloneElement(template, props); - } - } - - } - return ; + return ; } } diff --git a/index.js b/index.js index c89847eb..3346cbc9 100644 --- a/index.js +++ b/index.js @@ -7,23 +7,32 @@ import Circle from './elements/Circle'; import Ellipse from './elements/Ellipse'; import Polygon from './elements/Polygon'; import Polyline from './elements/Polyline'; +import Line from './elements/Line'; import Svg from './elements/Svg'; import Path from './elements/Path'; +import G from './elements/G'; +import Text from './elements/Text'; +import Use from './elements/Use'; +import Defs from './elements/Defs'; let { Group -} = ART; - + } = ART; export { Svg, Circle, Ellipse, Group, + G, + Text, Path, Polygon, Polyline, - Rect + Line, + Rect, + Use, + Defs }; export default Svg;