I’m working on a React Native project where I need to display a progress indicator that outlines a non-circular view.
I tried using react-native-svg with the Circle component to create a circular progress indicator, but it didn’t work as I wanted.
I need the progress indicator to fit an elliptical or rounded-rectangular shape.
Here’s a simplified version of my current approach using basic React Native components: https://snack.expo.dev/@audn/progress-border
What I’m trying to make:
What I have so far:
import { TouchableOpacity, Text, View, StyleSheet } from 'react-native';
import moment from 'moment';
import Svg, { Circle } from 'react-native-svg';
const DateComponent = () => {
const date = moment(new Date());
const dayName = date.format('dd').charAt(0);
const dayNumber = date.format('D');
const isFutureDate = date.isAfter(moment(), 'day');
const progress = 0.75;
const radius = 35;
const strokeWidth = 2;
const circumference = 2 * Math.PI * radius;
return (
<TouchableOpacity style={styles.container}>
<View style={styles.wrapper}>
<Svg height="70" width="70" viewBox="0 0 70 70">
<Circle
cx="35"
cy="35"
r={radius}
stroke="gray"
strokeWidth={strokeWidth}
fill="none"
opacity={0.2}
/>
<Circle
cx="35"
cy="35"
r={radius}
stroke="green"
strokeWidth={strokeWidth}
fill="none"
strokeDasharray={`${circumference} ${circumference}`}
strokeDashoffset={(1 - progress) * circumference}
strokeLinecap="round"
transform="rotate(-90, 35, 35)"
/>
</Svg>
<View style={styles.card}>
<Text style={styles.dayText}>{dayName}</Text>
<Text style={[styles.dateText, { color: isFutureDate ? '#757575' : 'black' }]}>
{dayNumber}
</Text>
</View>
</View>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
},
wrapper: {
justifyContent: 'center',
alignItems: 'center',
},
card: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 35,
height: 70,
width: 70,
},
dayText: {
fontSize: 14,
color: '#757575',
},
dateText: {
fontSize: 18,
fontWeight: 'bold',
},
});
export default DateComponent;
2
Answers
I drew a simple
SVG
file and just switched in it to your code… Does this solution seem ok to you?UPDATE
pathLength version
I fleshed something that works for react native skia. If you draw your border using path, you can use the
end
prop to get a progress bar border.Usage:
Hook to simulate progress value changing
I tried to make a snack for demo but it kept giving me an error about using SharedValues. When using expo outside the browser it works