最近在项目中要用到[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