1// tslint:disable max-classes-per-file
2import React from 'react';
3import { Image, StyleSheet, View } from 'react-native';
4import * as Svg from 'react-native-svg';
5
6import Example from './Example';
7
8const { Circle, Rect, Path, Line, G } = Svg;
9
10const styles = StyleSheet.create({
11  container: {
12    flex: 1,
13    height: 100,
14    width: 200,
15  },
16  svg: {
17    flex: 1,
18    alignSelf: 'stretch',
19  },
20});
21
22class SvgExample extends React.Component {
23  static title = 'SVG';
24  render() {
25    return (
26      <Svg.Svg height="100" width="100">
27        <Circle cx="50" cy="50" r="45" stroke="blue" strokeWidth="2.5" fill="green" />
28        <Rect x="15" y="15" width="70" height="70" stroke="red" strokeWidth="2" fill="yellow" />
29      </Svg.Svg>
30    );
31  }
32}
33
34class SvgOpacity extends React.Component {
35  static title = 'SVG with `opacity` prop';
36  render() {
37    return (
38      // @ts-ignore
39      <Svg.Svg height="100" width="100" opacity="0.2">
40        <Circle cx="50" cy="50" r="45" stroke="blue" strokeWidth="2.5" fill="green" />
41        <Rect x="15" y="15" width="70" height="70" stroke="red" strokeWidth="2" fill="yellow" />
42      </Svg.Svg>
43    );
44  }
45}
46
47class SvgViewbox extends React.Component {
48  static title = 'SVG with `viewBox="40 20 100 40" and preserveAspectRatio="none"`';
49  render() {
50    return (
51      <Svg.Svg height="100" width="100" viewBox="40 20 100 40" preserveAspectRatio="none">
52        <G>
53          <Rect x="0" y="0" width="100" height="100" fill="red" />
54          <Circle cx="50" cy="50" r="30" fill="yellow" />
55          <Circle cx="40" cy="40" r="4" fill="black" />
56          <Circle cx="60" cy="40" r="4" fill="black" />
57          <Path d="M 40 60 A 10 10 0 0 0 60 60" stroke="black" />
58        </G>
59      </Svg.Svg>
60    );
61  }
62}
63
64class NullComponent extends React.Component {
65  render() {
66    return null;
67  }
68}
69
70class SvgLayout extends React.Component {
71  static title = 'SVG with flex layout';
72  render() {
73    return (
74      <View style={styles.container}>
75        <Svg.Svg style={styles.svg}>
76          <G>
77            <NullComponent />
78          </G>
79          <NullComponent />
80          <Rect
81            width="80%"
82            height="80%"
83            x="10%"
84            y="10%"
85            fill="purple"
86            stroke="yellow"
87            strokeWidth="4"
88          />
89          <Line x1="10%" y1="10%" x2="90%" y2="90%" stroke="yellow" strokeWidth="4" />
90          <Line x1="10%" y1="90%" x2="90%" y2="10%" stroke="yellow" strokeWidth="4" />
91        </Svg.Svg>
92      </View>
93    );
94  }
95}
96
97class SvgNativeMethods extends React.Component {
98  static title = 'Tap the shapes to render the Image below based on the base64-data of the Svg';
99
100  state: { base64?: string } = {};
101
102  root?: any;
103
104  alert = () => {
105    this.root.toDataURL((base64: string) => {
106      this.setState({
107        base64,
108      });
109    });
110  };
111
112  render() {
113    return (
114      <View>
115        <Svg.Svg
116          height="100"
117          width="150"
118          ref={ele => {
119            this.root = ele;
120          }}>
121          <G x="40" onPress={this.alert}>
122            <Circle cx="32" cy="32" r="4.167" fill="blue" />
123            <Path
124              // tslint:disable-next-line max-line-length
125              d="M55.192 27.87l-5.825-1.092a17.98 17.98 0 0 0-1.392-3.37l3.37-4.928c.312-.456.248-1.142-.143-1.532l-4.155-4.156c-.39-.39-1.076-.454-1.532-.143l-4.928 3.37a18.023 18.023 0 0 0-3.473-1.42l-1.086-5.793c-.103-.543-.632-.983-1.185-.983h-5.877c-.553 0-1.082.44-1.185.983l-1.096 5.85a17.96 17.96 0 0 0-3.334 1.393l-4.866-3.33c-.456-.31-1.142-.247-1.532.144l-4.156 4.156c-.39.39-.454 1.076-.143 1.532l3.35 4.896a18.055 18.055 0 0 0-1.37 3.33L8.807 27.87c-.542.103-.982.632-.982 1.185v5.877c0 .553.44 1.082.982 1.185l5.82 1.09a18.013 18.013 0 0 0 1.4 3.4l-3.31 4.842c-.313.455-.25 1.14.142 1.53l4.155 4.157c.39.39 1.076.454 1.532.143l4.84-3.313c1.04.563 2.146 1.02 3.3 1.375l1.096 5.852c.103.542.632.982 1.185.982h5.877c.553 0 1.082-.44 1.185-.982l1.086-5.796c1.2-.354 2.354-.82 3.438-1.4l4.902 3.353c.456.313 1.142.25 1.532-.142l4.155-4.154c.39-.39.454-1.076.143-1.532l-3.335-4.874a18.016 18.016 0 0 0 1.424-3.44l5.82-1.09c.54-.104.98-.633.98-1.186v-5.877c0-.553-.44-1.082-.982-1.185zM32 42.085c-5.568 0-10.083-4.515-10.083-10.086 0-5.568 4.515-10.084 10.083-10.084 5.57 0 10.086 4.516 10.086 10.083 0 5.57-4.517 10.085-10.086 10.085z"
126              fill="blue"
127            />
128          </G>
129        </Svg.Svg>
130        <View style={{ width: 150, height: 100, borderWidth: 1, marginTop: 5 }}>
131          {this.state.base64 && (
132            <Image
133              source={{ uri: `data:image/png;base64,${this.state.base64}` }}
134              style={{ width: 150, height: 100 }}
135            />
136          )}
137        </View>
138      </View>
139    );
140  }
141}
142
143const icon = (
144  <Svg.Svg height="20" width="20">
145    <Circle cx="10" cy="10" r="8" stroke="blue" strokeWidth="1" fill="green" />
146    <Rect x="4" y="4" width="12" height="12" stroke="red" strokeWidth="1" fill="yellow" />
147  </Svg.Svg>
148);
149
150const SVG: Example = {
151  icon,
152  samples: [SvgExample, SvgOpacity, SvgViewbox, SvgLayout, SvgNativeMethods],
153};
154
155export default SVG;
156