Circular Progress
A button which changes it’s appearance if tapped
import { StyleSheet, View } from 'react-native'import React from 'react'import CircularProgress from '../components/circularProgress'
//or if you're using npm package//import {CircularProgress} from '@cascadeui/circular-progress'
const App = () => { return ( <View> <CircularProgress progress={50} />{/* see props for more customization */} </View> )}
export default AppInstallation
npm install @cascadeui/circular-progress-
Install
react-native-svgTerminal window npm install react-native-svgTerminal window yarn add react-native-svgTerminal window npx expo install react-native-svg -
Copy core component
src/components/circularProgress.tsximport React, { useEffect, useRef } from 'react';import { View, Animated, StyleSheet, Easing } from 'react-native';import Svg, { Circle, G } from 'react-native-svg';const AnimatedCircle = Animated.createAnimatedComponent(Circle);const CircularProgress = ({size = 100,strokeWidth = 10,progress = 0,progressColor = '#2196F3',backgroundColor = '#E0E0E0',duration = 1000, // Animation duration in ms}) => {// Calculate dimensionsconst center = size / 2;const radius = (size - strokeWidth) / 2;const circumference = 2 * Math.PI * radius;// Animation valueconst progressAnimation = useRef(new Animated.Value(0)).current;// Animate when progress changesuseEffect(() => {Animated.timing(progressAnimation, {toValue: progress,duration: duration,easing: Easing.out(Easing.ease),useNativeDriver: true,}).start();}, [progress, duration]);// Calculate the animated stroke dash offsetconst strokeDashoffset = progressAnimation.interpolate({inputRange: [0, 100],outputRange: [circumference, 0],});return (<View style={[styles.container, { width: size, height: size }]}><Svg width={size} height={size}><G rotation="-90" origin={`${center}, ${center}`}>{/* Background Circle */}<Circlecx={center}cy={center}r={radius}stroke={backgroundColor}strokeWidth={strokeWidth}fill="none"/>{/* Animated Progress Circle */}<AnimatedCirclecx={center}cy={center}r={radius}stroke={progressColor}strokeWidth={strokeWidth}fill="none"strokeLinecap="round"strokeDasharray={circumference}strokeDashoffset={strokeDashoffset}/></G></Svg></View>);};const styles = StyleSheet.create({container: {alignItems: 'center',justifyContent: 'center',},});export default CircularProgress;
Props
| Prop | Type | Description |
|---|---|---|
size | number | Size of the component. |
strokeWidth | number | Strok width of the circle. |
progress | number | Progess state (0-100). |
progressColor | string | Color of the progress. |
backgroundColor | string | Color of the background. |
duration | number | Animation duration to complete(ms). |
Circular Progress with numbers
import { StyleSheet, View } from 'react-native'import React from 'react'import CircularProgressNumber from '../components/circularProgressNum'
//or if you're using npm//import {CircularProgressNumber} from '@cascadeui/circular-progress'
const App = () => { return ( <View> <CircularProgressNum progress={50} />{/* see props for more customization */} </View> )}
export default Appnpm install @cascadeui/circular-progressCopy core component src/components/circularProgressNum.tsx
import React, { useEffect, useRef } from 'react'; import { View, Animated, StyleSheet, Easing } from 'react-native'; import Svg, { Circle, G } from 'react-native-svg';
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
const CircularProgressNumber = ({ size = 100, strokeWidth = 10, progress = 0, progressColor = '#2196F3', backgroundColor = '#E0E0E0', duration = 1000, // Animation duration in ms }) => { // Calculate dimensions const center = size / 2; const radius = (size - strokeWidth) / 2; const circumference = 2 * Math.PI * radius;
// Animation value const progressAnimation = useRef(new Animated.Value(0)).current;
// Animate when progress changes useEffect(() => { Animated.timing(progressAnimation, { toValue: progress, duration: duration, easing: Easing.out(Easing.ease), useNativeDriver: true, }).start(); }, [progress, duration]);
// Calculate the animated stroke dash offset const strokeDashoffset = progressAnimation.interpolate({ inputRange: [0, 100], outputRange: [circumference, 0], });
return ( <View style={[styles.container, { width: size, height: size }]}> <Svg width={size} height={size}> <G rotation="-90" origin={`${center}, ${center}`}> {/* Background Circle */} <Circle cx={center} cy={center} r={radius} stroke={backgroundColor} strokeWidth={strokeWidth} fill="none" /> {/* Animated Progress Circle */} <AnimatedCircle cx={center} cy={center} r={radius} stroke={progressColor} strokeWidth={strokeWidth} fill="none" strokeLinecap="round" strokeDasharray={circumference} strokeDashoffset={strokeDashoffset} /> </G> </Svg> </View> ); };
const styles = StyleSheet.create({ container: { alignItems: 'center', justifyContent: 'center', }, });
export default CircularProgressNumber;Props
| Prop | Type | Description |
|---|---|---|
size | number | Size of the component. |
strokeWidth | number | Strok width of the circle. |
progress | number | Progess state (0-100). |
progressColor | string | Color of the progress. |
backgroundColor | string | Color of the background. |
duration | number | Animation duration to complete(ms). |
TextColor | string | Color of the Text. |
TextSize | number | Size of the Text. |
showPercentage | boolean | Show % at the end of the number. |