add Use element and add example for it

add Use element and add example for it
This commit is contained in:
Horcrux
2016-01-23 19:25:12 +08:00
parent af0995022d
commit 11c211a9a9
12 changed files with 166 additions and 29 deletions

View File

@@ -9,6 +9,7 @@ import * as Path from './examples/Path';
import * as Text from './examples/Text'; import * as Text from './examples/Text';
import * as G from './examples/G'; import * as G from './examples/G';
import * as Stroking from './examples/Stroking'; import * as Stroking from './examples/Stroking';
import * as Use from './examples/Use';
export { export {
Svg, Svg,
@@ -21,5 +22,6 @@ export {
Path, Path,
Text, Text,
Stroking, Stroking,
G G,
Use
}; };

64
Example/examples/Use.js Normal file
View File

@@ -0,0 +1,64 @@
import React, {
Component
} from 'react-native';
import Svg, {
Defs,
Use,
G,
Rect,
Circle
} from 'react-native-art-svg';
class UseExample extends Component{
static title = 'Reuse svg code';
render() {
return <Svg
height="100"
width="300"
>
<Defs>
<G id="shape">
<G>
<Circle cx="50" cy="50" r="50" />
<Rect x="50" y="50" width="50" height="50" />
<Circle cx="50" cy="50" r="5" fill="blue" />
</G>
</G>
</Defs>
<Use href="#shape" x="20" y="0"/>
<Use href="#shape" x="170"y="0" />
</Svg>;
};
}
class UseShapes extends Component{
static title = 'Using Shapes Outside of a Defs Element';
render() {
return <Svg
height="110"
width="200"
>
<G id="shape">
<Rect x="0" y="0" width="50" height="50" />
</G>
<Use href="#shape" x="75" y="50" fill="#0f0"/>
<Use href="#shape" x="150" y="50" stroke="#0f0" fill="none"/>
</Svg>;
};
}
const icon = <Svg
height="20"
width="20"
>
</Svg>;
const samples = [UseExample, UseShapes];
export {
icon,
samples
}

View File

@@ -107,7 +107,7 @@ const styles = StyleSheet.create({
}); });
const names = ['Svg', 'Stroking', 'Path', 'Line', 'Rect', 'Polygon', 'Polyline', 'Circle', 'Ellipse', 'G', 'Text']; const names = ['Svg', 'Stroking', 'Path', 'Line', 'Rect', 'Polygon', 'Polyline', 'Circle', 'Ellipse', 'G', 'Text', 'Use'];
class ArtSvgExample extends Component { class ArtSvgExample extends Component {
constructor() { constructor() {

View File

@@ -1,6 +1,7 @@
### react-native-art-svg ### react-native-art-svg
TODO: TODO:
1. fill-rule:evenodd 1. fill-rule:evenodd
2. gradients 2. gradients
@@ -9,20 +10,14 @@ TODO:
elements: elements:
1.defs 1.defs
2.tref ! 2.tref !
3.tspan ! 3.tspan !
4.clipPath (wait for official todo) 4.clipPath (wait for official todo)
5.glyph ? missing-glyph?
6.glyph ? missing-glyph? 6.linearGradient
7.radialGradient
7.linearGradient
8.marker? 8.marker?
9.pattern 9.pattern
10.radialGradient 10.textPath
11.stop 11.stop
12.symbol 12.symbol
13.use
14.textPath

View File

@@ -22,8 +22,8 @@ class Circle extends Component{
{...this.props} {...this.props}
{...strokeFilter(this.props)} {...strokeFilter(this.props)}
r={null} r={null}
rx={this.props.r} rx={+this.props.r}
ry={this.props.r} ry={+this.props.r}
/> />
} }
} }

View File

@@ -9,6 +9,8 @@ let {
Group Group
} = ART; } = ART;
import Defs from './Defs';
const transformProps = { const transformProps = {
scale: null, scale: null,
scaleX: null, scaleX: null,
@@ -29,19 +31,23 @@ class G extends Component{
constructor() { constructor() {
super(...arguments); super(...arguments);
this.children = Children.map(this.props.children, child => cloneElement(child, { this.children = Children.map(this.props.children, child => cloneElement(child, {
id: null,
...this.props, ...this.props,
...transformProps, ...transformProps,
children: child.children, ...child.props,
...child.props id: null
})); }));
}; };
render() { render() {
return <Group let element = <Group
{...this.props} {...this.props}
{...transformFilter(this.props)} {...transformFilter(this.props)}
id={null}
>{this.children}</Group>; >{this.children}</Group>;
if (this.props.id) {
Defs.set(this.props.id + ':' + this.props.svgId, <G {...this.props} id={null} />);
}
return element;
} }
} }

View File

@@ -1,12 +1,14 @@
import React, { import React, {
ART, ART,
Component, Component,
PropTypes PropTypes,
cloneElement
} from 'react-native'; } from 'react-native';
let { let {
Shape Shape
} = ART; } = ART;
import Defs from './Defs';
import fillFilter from '../lib/fillFilter'; import fillFilter from '../lib/fillFilter';
import strokeFilter from '../lib/strokeFilter'; import strokeFilter from '../lib/strokeFilter';
@@ -25,12 +27,16 @@ class Path extends Component{
}; };
render() { render() {
let {props} = this; let {props} = this;
let element = <Shape
return <Shape
{...props} {...props}
{...strokeFilter(props)} {...strokeFilter(props)}
fill={fillFilter(props)} fill={fillFilter(props)}
id={null}
/>; />;
if (this.props.id) {
Defs.set(this.props.id + ':' + this.props.svgId, <Path {...this.props} id={null} />);
}
return element;
} }
} }

View File

@@ -6,6 +6,7 @@ import React, {
import fillFilter from '../lib/fillFilter'; import fillFilter from '../lib/fillFilter';
import strokeFilter from '../lib/strokeFilter'; import strokeFilter from '../lib/strokeFilter';
import transformFilter from '../lib/transformFilter';
import Path from './Path'; import Path from './Path';
let propType = PropTypes.oneOfType([PropTypes.string, PropTypes.number]); let propType = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
@@ -82,17 +83,17 @@ class Rect extends Component{
h ${-width} h ${-width}
Z Z
`; `;
return <Path return <Path
{...props} {...props}
x={rx ? +rx: null}
y={null}
rx={null} rx={null}
ry={null} ry={null}
width={null} width={null}
height={null} height={null}
{...strokeFilter(props)} {...strokeFilter(props)}
fill={fillFilter(props)} fill={fillFilter(props)}
{...transformFilter(props)}
x={null}
y={null}
d={d} d={d}
/>; />;
} }

View File

@@ -1,7 +1,9 @@
import React, { import React, {
ART, ART,
Component, Component,
PropTypes PropTypes,
Children,
cloneElement
} from 'react-native'; } from 'react-native';
import _ from 'lodash'; import _ from 'lodash';
@@ -71,6 +73,8 @@ function extractViewbox({viewbox, width, height, preserveAspectRatio}) {
return false; return false;
} }
let id = 0;
class Svg extends Component{ class Svg extends Component{
static displayName = 'Svg'; static displayName = 'Svg';
static propType = { static propType = {
@@ -82,6 +86,20 @@ class Svg extends Component{
preserveAspectRatio: PropTypes.string // preserveAspectRatio only supports 'none' for now preserveAspectRatio: PropTypes.string // preserveAspectRatio only supports 'none' for now
}; };
constructor() {
super(...arguments);
id++;
this.id = id;
}
getChildren = () => {
return Children.map(this.props.children, child => {
return cloneElement(child, {
svgId: this.id
});
});
};
render() { render() {
let opacity = +this.props.opacity; let opacity = +this.props.opacity;
let viewbox = extractViewbox(this.props); let viewbox = extractViewbox(this.props);
@@ -104,7 +122,7 @@ class Svg extends Component{
scaleX={scaleX} scaleX={scaleX}
scaleY={scaleY} scaleY={scaleY}
> >
{this.props.children} {this.getChildren()}
</Group>} </Group>}
</Surface>; </Surface>;
} }
@@ -118,7 +136,7 @@ class Svg extends Component{
} }
]} ]}
> >
{this.props.children} {this.getChildren()}
</Surface>; </Surface>;
} }
} }

View File

@@ -7,6 +7,7 @@ import React, {
let { let {
Text:ARTText Text:ARTText
} = ART; } = ART;
import Defs from './Defs';
import fillFilter from '../lib/fillFilter'; import fillFilter from '../lib/fillFilter';
import strokeFilter from '../lib/strokeFilter'; import strokeFilter from '../lib/strokeFilter';
@@ -33,7 +34,7 @@ class Text extends Component{
y = props.dy ? +props.y + (+props.dy) : +props.y; y = props.dy ? +props.y + (+props.dy) : +props.y;
} }
return <ARTText let element = <ARTText
{...props} {...props}
{...transformFilter(props)} {...transformFilter(props)}
{...strokeFilter(props)} {...strokeFilter(props)}
@@ -47,7 +48,12 @@ class Text extends Component{
alignment={props.textAnchor || props.alignment} alignment={props.textAnchor || props.alignment}
x={x} x={x}
y={y} y={y}
id={null}
/>; />;
if (this.props.id) {
Defs.set(this.props.id + ':' + this.props.svgId, <Text {...this.props} id={null} />);
}
return element;
} }
} }

37
elements/Use.js Normal file
View File

@@ -0,0 +1,37 @@
import React, {
Component,
PropTypes,
ART,
cloneElement
} 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 = {
href: PropTypes.string
};
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 <Group />;
}
}
export default Use;

View File

@@ -8,6 +8,8 @@ export default function (props) {
rotation: props.rotation || props.rotate || 0, rotation: props.rotation || props.rotate || 0,
scale: props.scale || 1, scale: props.scale || 1,
originX, originX,
originY originY,
x: +props.x || 0,
y: +props.y || 0
} }
} }