react-native-slideable-calendar
Version:
86 lines (79 loc) • 2.96 kB
JavaScript
import React, { Component } from 'react';
import { View, Animated } from 'react-native';
import Svg, { Circle } from 'react-native-svg';
export default class ProgressBarCircular extends Component {
circleRef;
constructor(props) {
super(props);
this.state = {
percentage: new Animated.Value(0),
};
}
static defaultProps = {
sqSize: 200,
percentage: 0,
strokeWidth: 10,
};
componentDidMount() {
this.state.percentage.addListener((percentage) => {
const radius = (this.props.sqSize - this.props.strokeWidth) / 2;
const dashArray = radius * Math.PI * 2;
const strokeDashoffset = dashArray - dashArray * percentage.value / 100;
if (this.circleRef) {
this.circleRef.setNativeProps({ strokeDashoffset });
}
});
this.animate();
}
animate() {
const { percentage } = this.props;
Animated.timing(this.state.percentage, {
toValue: percentage,
useNativeDriver: true,
}).start();
}
render() {
const sqSize = this.props.sqSize;
const radius = (this.props.sqSize - this.props.strokeWidth) / 2;
const viewBox = `0 0 ${sqSize} ${sqSize}`;
const dashArray = radius * Math.PI * 2;
const dashOffset = dashArray - dashArray * this.props.percentage / 100;
return (
<View style={{
width: this.props.sqSize,
height: this.props.sqSize,
justifyContent: 'center',
alignItems: 'center',
}}>
<View style={{ position: 'absolute' }}>{this.props.children}</View>
<Svg
width={this.props.sqSize}
height={this.props.sqSize}
viewBox={viewBox}>
<Circle
fill={'none'}
stroke={'#EEF2FA'}
cx={this.props.sqSize / 2}
cy={this.props.sqSize / 2}
r={radius}
strokeWidth={`${this.props.strokeWidth}px`}
/>
<Circle
ref={(ref) => this.circleRef = ref}
fill={'none'}
stroke={'#6666FF'}
cx={this.props.sqSize / 2}
cy={this.props.sqSize / 2}
r={radius}
strokeWidth={`${this.props.strokeWidth}px`}
transform={`rotate(-90 ${this.props.sqSize / 2} ${this.props.sqSize / 2})`}
strokeDasharray={dashArray}
strokeDashoffset={dashOffset}
strokeLinecap={'round'}
strokeLinejoin={'round'}
/>
</Svg>
</View>
);
}
}