最近在項目中要用到[react-native-percentage-circle][1]組件實現進度條和畫圓環。UI界面要實現以下效果
能夠看出要實現兩個圓環嵌套,實現同心圓仍是比較簡單的,react-native-percentage-circle組件支持子元素,因此,在外面圓環裏面嵌套一個同心圓環,而後設置樣式就好了。具體代碼以下:
<PercentageCircle radius={70} percent={100} color={'#ffffff'} bgcolor={"#ffffff"} innerColor={"#ffffff"} borderWidth={8}> <View style={{flex:1,justifyContent:'center',alignItems: 'center',}}> <PercentageCircle radius={60} percent={49} rotate={10} bgcolor={'#ff912f'} color={"#ffac48"} innerColor={"#ffffff"} borderWidth={15}> <Text style={{fontFamily: "MicrosoftYaHei",fontSize: 22,lineHeight: 27,color: "#545453"}}> 1990筆</Text> </PercentageCircle> </View> </PercentageCircle>
然而要實現裏面圓環旋轉就有點難度了,首先目前該組件最新版本v1.0.6並不支持直接旋轉
所以,首先咱們想到可能要用的transform來實現,但實踐發現有各類問題。最後,本人決定是否能夠經過修改源碼實現旋轉效果,對組件的index.js研究發現能夠對組件加上一個props屬性rotate,實現圓環旋轉效果。react
第一步:在PercentageCircle類propTypes中添加一個rotate屬性。
第二步:在constructor中定義一個新的變量rotate。
第三步:對if進行修改,要同時修改constructor函數和componentWillReceiveProps()函數
NOTE:這裏rotate本人未設定值範圍,但建議0-50,若是大於50,失去了意義,能夠經過背景顏色改變,你們在代碼中能夠本身設定rotate的取值範圍。
最後附上本人在git上的Issues的評論,以及index.js代碼git
/** React Native Percentage Circle ** @github https://github.com/JackPu/react-native-percentage-circle ** React Native Version >=0.25 ** to fixed react native version **/ import React, { Component } from 'react'; import { StyleSheet, View, Text, } from 'react-native'; const styles = StyleSheet.create({ circle: { overflow: 'hidden', position: 'relative', justifyContent: 'center', alignItems: 'center', backgroundColor: '#e3e3e3', }, leftWrap: { overflow: 'hidden', position: 'absolute', top: 0, }, rightWrap: { position: 'absolute', }, loader: { position: 'absolute', left: 0, top: 0, borderRadius: 1000, }, innerCircle: { overflow: 'hidden', position: 'relative', justifyContent: 'center', alignItems: 'center', }, text: { fontSize: 11, color: '#888', }, }); class PercentageCircle extends Component { propTypes: { color: React.PropTypes.string, bgcolor: React.PropTypes.string, innerColor: React.PropTypes.string, radius: React.PropTypes.number, percent: React.PropTypes.number, borderWidth: React.Proptypes.number, textStyle: React.Proptypes.array, disabled: React.PropTypes.bool, rotate: React.Proptypes.number, //定義旋轉角度 } constructor(props) { super(props); let percent = this.props.percent; let leftTransformerDegree = '0deg'; let rightTransformerDegree = '0deg'; //初始化值 let rotate = this.props.rotate; if (typeof rotate == 'undefined') { rotate = 0; } if (percent >= 50) { //rightTransformerDegree = '180deg'; //leftTransformerDegree = (percent - 50) * 3.6 + 'deg'; rightTransformerDegree = 180 + rotate * 3.6 + 'deg'; leftTransformerDegree = (percent + rotate - 50) * 3.6 + 'deg'; } else { //rightTransformerDegree = percent * 3.6 + 'deg'; rightTransformerDegree = (percent + rotate - 50) * 3.6 + 'deg'; leftTransformerDegree = rotate * 3.6 + 'deg'; } this.state = { percent: this.props.percent, borderWidth: this.props.borderWidth < 2 || !this.props.borderWidth ? 2 : this.props.borderWidth, leftTransformerDegree: leftTransformerDegree, rightTransformerDegree: rightTransformerDegree, textStyle: this.props.textStyle ? this.props.textStyle : null }; } componentWillReceiveProps(nextProps) { let percent = nextProps.percent; let leftTransformerDegree = '0deg'; let rightTransformerDegree = '0deg'; /* if (percent >= 50) { rightTransformerDegree = '180deg'; leftTransformerDegree = (percent - 50) * 3.6 + 'deg'; } else { rightTransformerDegree = '0deg'; leftTransformerDegree = -(50 - percent) * 3.6 + 'deg'; } */ //初始化值 let rotate = this.props.rotate; if (typeof rotate == 'undefined') { rotate = 0; } if (percent >= 50) { //rightTransformerDegree = '180deg'; //leftTransformerDegree = (percent - 50) * 3.6 + 'deg'; rightTransformerDegree = 180 + rotate * 3.6 + 'deg'; leftTransformerDegree = (percent + rotate - 50) * 3.6 + 'deg'; } else { //rightTransformerDegree = percent * 3.6 + 'deg'; rightTransformerDegree = (percent + rotate - 50) * 3.6 + 'deg'; leftTransformerDegree = rotate * 3.6 + 'deg'; } this.setState({ percent: this.props.percent, borderWidth: this.props.borderWidth < 2 || !this.props.borderWidth ? 2 : this.props.borderWidth, leftTransformerDegree: leftTransformerDegree, rightTransformerDegree: rightTransformerDegree }); } render() { if (this.props.disabled) { return ( <View style={[styles.circle,{ width:this.props.radius*2, height: this.props.radius*2, borderRadius:this.props.radius }]}> <Text style={styles.text}>{this.props.disabledText}</Text> </View> ); } return ( <View style={[styles.circle,{ width:this.props.radius*2, height: this.props.radius*2, borderRadius:this.props.radius, backgroundColor: this.props.bgcolor }]}> <View style={[styles.leftWrap,{ width: this.props.radius, height: this.props.radius * 2, left:0, }]}> <View style={[styles.loader,{ left: this.props.radius, width:this.props.radius, height: this.props.radius*2, borderTopLeftRadius:0, borderBottomLeftRadius:0, backgroundColor:this.props.color, transform:[{translateX:-this.props.radius/2},{rotate:this.state.leftTransformerDegree},{translateX:this.props.radius/2}], }]}></View> </View> <View style={[styles.leftWrap,{ left:this.props.radius, width: this.props.radius, height: this.props.radius * 2, }]}> <View style={[styles.loader,{ left:-this.props.radius, width:this.props.radius, height: this.props.radius*2, borderTopRightRadius:0, borderBottomRightRadius:0, backgroundColor: this.props.percent < 50 ? this.props.bgcolor : this.props.color, transform:[{translateX:this.props.radius/2},{rotate:this.state.rightTransformerDegree},{translateX:-this.props.radius/2}], }]}></View> </View> <View style={[styles.innerCircle,{ width:(this.props.radius - this.state.borderWidth)*2, height:(this.props.radius - this.state.borderWidth)*2, borderRadius:this.props.radius - this.state.borderWidth, backgroundColor: this.props.innerColor, }]}> {this.props.children ? this.props.children : <Text style={[styles.text, this.state.textStyle]}>{this.props.percent}%</Text>} </View> </View> ); } } // set some attributes default value PercentageCircle.defaultProps = { bgcolor: '#e3e3e3', innerColor: '#fff' }; module.exports = PercentageCircle;
s://github.com/JackPu/react-native-percentage-circlegithub