Last active
May 17, 2016 21:14
-
-
Save elviejokike/73f960532d090c10645befaf3079363f to your computer and use it in GitHub Desktop.
Circle Progress React Native
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { View, PropTypes, Platform } from 'react-native'; | |
import Svg,{ | |
Circle, | |
Path, | |
G | |
} from 'react-native-svg'; | |
export default class CircleProgress extends React.Component { | |
constructor(props) { | |
super(props); | |
} | |
_getArcPath() { | |
let percentage = this.props.percentage; | |
if (percentage <= 0) { | |
return "M0 0"; | |
} | |
let size = this.props.size; | |
let r = size/2; | |
let height = size * (1-percentage); | |
let sweepFlag = percentage > 0.5 ? 1 : 0; | |
// The offset is calculate based on math formula (intersection of a circle with a line) | |
// (1) Circle Equation is : (x-a)^2 + (y-b)^2 = r^2 | |
// (2) Line Equation is: y = height | |
// Where a = r, and b = r, replacing (1) in (2), we get | |
// (3) x = sqrt ( 2*height*r - height^2) | |
// Additionally, we have an offset of r, becasuse in SVG the 0,0 point is located on the top left corner. | |
// therefore, the real value of the x-offset is = r - (3) | |
let offset = r - Math.sqrt( 2*height*r - (height*height) ) | |
// move the right coordinate | |
let arcpath = "M" + offset + " " + height; | |
// create arc | |
arcpath += " A 90 90, 0, "+sweepFlag+", 0,"; | |
// to the end point | |
arcpath += " " + (size - offset) + " " + height + 2; | |
return arcpath; | |
} | |
render() { | |
let realSize = this.props.size + 4; | |
return ( | |
<View style={this.props.style}> | |
<Svg | |
width={realSize} | |
height={realSize}> | |
<G> | |
<Circle cx={this.props.size/2} cy={this.props.size/2} r={this.props.size/2} fill={this.props.backgroundColor}/> | |
<Path d={this._getArcPath()} fill={this.props.fillBackgroundColor} /> | |
</G> | |
</Svg> | |
<View style={{position:"absolute", top: 0, left: 0, alignItems:"center", backgroundColor:"transparent" ,width:this.props.size }}>{ | |
this.props.children | |
}</View> | |
</View> | |
) | |
} | |
} | |
CircleProgress.propTypes = { | |
style: View.propTypes.style, | |
size: PropTypes.number.isRequired, | |
percentage: PropTypes.number.isRequired, | |
backgroundColor: PropTypes.string, | |
fillBackgroundColor: PropTypes.string, | |
strokeColor: PropTypes.string | |
} | |
CircleProgress.defaultProps = { | |
backgroundColor: '#e4e4e4', | |
fillBackgroundColor : "#22c74a", | |
strokeColor: "#FFF", | |
percentage: 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment