Add Text
This commit is contained in:
Horcrux
2016-01-23 11:09:00 +08:00
parent b871e0087e
commit d40921354b
9 changed files with 285 additions and 15 deletions

View File

@@ -6,6 +6,7 @@ import * as Line from './examples/Line';
import * as Polygon from './examples/Polygon';
import * as Polyline from './examples/Polyline';
import * as Path from './examples/Path';
import * as Text from './examples/Text';
export {
Svg,
@@ -15,5 +16,6 @@ export {
Line,
Polygon,
Polyline,
Path
Path,
Text
};

View File

@@ -83,15 +83,15 @@ class BezierCurve extends Component{
</G>
<G
fontSize="30"
fontFamily="sans-serif"
fill="black"
stroke="none"
textAnchor="middle"
>
<Text x="100" y="350" dx="-30">A</Text>
<Text x="250" y="50" dy="-10">B</Text>
<Text x="400" y="350" dx="30">C</Text>
<Text x="250" y="50" dy="-50">B</Text>
<Text x="400" y="350" dx="10">C</Text>
</G>
</G>
</Svg>;
}

View File

@@ -0,0 +1,47 @@
import React, {
Component
} from 'react-native';
import Svg, {
Line
} from 'react-native-art-svg';
class LineExample extends Component{
static title = 'Line';
render() {
return <Svg
height="100"
width="100"
>
<Line
x1="0"
y1="0"
x2="100"
y2="100"
stroke="red"
strokeWidth="2"
/>
</Svg>;
}
}
const icon = <Svg
height="20"
width="20"
>
<Line
x1="0"
y1="0"
x2="20"
y2="20"
stroke="red"
strokeWidth="1"
/>
</Svg>;
const samples = [LineExample];
export {
icon,
samples
}

View File

@@ -35,6 +35,35 @@ class SvgExample extends Component{
}
}
class SvgViewbox extends Component{
static title = 'SVG with `viewbox` prop';
render() {
return <Svg
height="100"
width="100"
viewbox="30 30 70 70"
>
<Circle
cx="50"
cy="50"
r="45"
stroke="blue"
strokeWidth="2.5"
fill="green"
/>
<Rect
x="15"
y="15"
width="70"
height="70"
stroke="red"
strokeWidth="2"
fill="yellow"
/>
</Svg>;
}
}
class SvgOpacity extends Component{
static title = 'SVG with `opacity` prop';
render() {

96
Example/examples/Text.js Normal file
View File

@@ -0,0 +1,96 @@
import React, {
Component
} from 'react-native';
import Svg, {
Text
} from 'react-native-art-svg';
class TextExample extends Component{
static title = 'Text';
render() {
return <Svg
height="30"
width="100"
>
<Text
x="50"
y="9"
fill="red"
textAnchor="center"
>I love SVG!</Text>
</Svg>;
}
}
class TextRotate extends Component{
static title = 'Transform the text';
render() {
return <Svg
height="60"
width="200"
>
<Text
x="0"
y="15"
fill="red"
rotate="30"
origin="20,40"
>I love SVG</Text>
<Text
x="95"
y="47"
fill="blue"
rotate="-67"
>I love SVG</Text>
<Text
x="126"
y="24"
fill="#f60"
rotate="16"
scale="1.36"
>I love SVG</Text>
</Svg>;
}
}
// TODO: wait for official done
class TextPath extends Component{
static title = 'Transform the text';
render() {
return <Svg
height="60"
width="200"
>
<Text
fill="red"
path={`
M 10 20
C 20 10 30 0 40 10
C 50 20 60 30 70 20
C 80 10 90 10 90 10
`}
>We go up, then we go down, then up again</Text>
</Svg>;
}
}
const icon = <Svg
height="20"
width="20"
>
<Text
x="10"
y="2"
fontSize="14"
fontWeight="bold"
textAnchor="center"
></Text>
</Svg>;
const samples = [TextExample, TextRotate];
export {
icon,
samples
}

View File

@@ -107,7 +107,7 @@ const styles = StyleSheet.create({
});
const names = ['Svg', 'Circle', 'Ellipse', 'G', 'Path', 'Polygon', 'Polyline', 'Line', 'Rect'];
const names = ['Svg', 'Circle', 'Ellipse', 'G', 'Text', 'Path', 'Polygon', 'Polyline', 'Line', 'Rect'];
class ArtSvgExample extends Component {
constructor() {
@@ -157,7 +157,7 @@ class ArtSvgExample extends Component {
Animated.timing(this.state.scale, {
toValue: 0,
easing: Easing.in(Easing.back(2))
}).start(() => this.setState({
}).start(({finished}) => finished && this.setState({
modal: false,
content: null
}));

View File

@@ -7,3 +7,29 @@ TODO:
3. text
4. other elements
5. animations https://github.com/maxwellito/vivus
elements:
1.defs
2.tref !
3.tspan !
4.clipPath (wait for official todo)
5.svg:viewBox (wait for official todo)
6.glyph ? missing-glyph?
7.linearGradient
8.marker?
9.pattern
10.radialGradient
11.stop
12.symbol
13.use
14.textPath

View File

@@ -1,17 +1,52 @@
import React, {
ART,
Component
Component,
PropTypes
} from 'react-native';
import _ from 'lodash';
let {
Surface
Surface,
ClippingRectangle
} = ART;
function extractViewbox({viewbox, width, height}) {
let x = 0;
let y = 0;
if (typeof viewbox === 'string') {
let parts = viewbox.trim().split(/\s+/);
if (parts.length === 4) {
return {
x: parts[0],
y: parts[1],
width: parts[2],
height: parts[3]
}
}
}
return {
x,
y,
width,
height
};
}
class Svg extends Component{
static displayName = 'Svg';
static propType = {
opacity: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
viewbox: PropTypes.string
};
render() {
let opacity = +this.props.opacity;
let {
x,
y,
width,
height
} = extractViewbox(this.props);
return <Surface
{...this.props}
style={[
@@ -20,7 +55,16 @@ class Svg extends Component{
opacity: opacity
}
]}
/>;
>
<ClippingRectangle
x={x}
y={y}
width={width}
height={height}
>
{this.props.children}
</ClippingRectangle>
</Surface>;
}
}

View File

@@ -5,12 +5,13 @@ import React, {
} from 'react-native';
let {
Text:ARTText,
Shape
Text:ARTText
} = ART;
import fillFilter from '../lib/fillFilter';
import strokeFilter from '../lib/strokeFilter';
const fontFamily = '"Helvetica Neue", "Helvetica", Arial';
class Text extends Component{
static displayName = 'Text';
static propTypes = {
@@ -21,15 +22,40 @@ class Text extends Component{
};
render() {
let {props} = this;
return <Shape d="M0, 0 L0, 0Z" />;
let x = 0;
if (props.x) {
x = props.dx ? +props.x + (+props.dx) : +props.x;
}
let y = 0;
if (props.y) {
y = props.dy ? +props.y + (+props.dy) : +props.y;
}
let coords = props.origin ? props.origin.split(',') : [];
let originX = coords.length === 2 ? coords[0] : props.originX;
let originY = coords.length === 2 ? coords[1] :props.originY;
return <ARTText
{...props}
font={{
fontSize: props.fontSize || 12,
fontFamily: props.fontFamily || fontFamily,
fontWeight: props.fontWeight,
fontStyle: props.fontStyle
}}
rotation={props.rotation || props.rotate || 0}
scale={props.scale || 1}
originX={originX}
originY={originY}
strokeCap={props.strokeLinecap || props.strokeCap || 'square'}
strokeJoin={props.strokeLinejoin || props.strokeJoin || 'miter'}
alignment={props.textAnchor || props.alignment}
fill={fillFilter(props)}
stroke={strokeFilter(props)}
x={x}
y={y}
/>;
}
}