Skip to content

Commit

Permalink
feat: add imperative methods to play, pause, and reAnimate
Browse files Browse the repository at this point in the history
feat: add imperative methods to play, pause, and reAnimate
  • Loading branch information
nithinpp69 authored Jul 18, 2022
2 parents e446443 + dd7995b commit 77eb78c
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 108 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
### Build: 🏠 `4.4.0` - react-native-circular-progress-indicator

---
- feat: add imperative methods to play, pause, and reAnimate
### Build: 🏠 `4.3.0` - react-native-circular-progress-indicator

---
- feat: change stroke color based on animation value
-
### Build: 🏠 `4.2.1` - react-native-circular-progress-indicator

---
Expand Down
55 changes: 53 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ This project is inspired from this [Youtube tutorial](https://www.youtube.com/wa
![](examples/demo8.gif)
![](examples/demo9.gif)
![](examples/demo11.gif)
![](examples/demo12.gif)

## Prerequisites

Expand Down Expand Up @@ -326,8 +327,35 @@ import CircularProgress from 'react-native-circular-progress-indicator';
]}
/>
```

![](examples/demo11.gif)
#### Play, Pause, and ReAnimate

```jsx
import CircularProgress, { ProgressRef } from 'react-native-circular-progress-indicator';

const progressRef = useRef<ProgressRef>(null);

// to pause animation
progressRef.current.pause();

// to play animation
progressRef.current.play();

// to re-play animation
progressRef.current.reAnimate();

....

<CircularProgress
ref={progressRef}
value={100}
radius={120}
duration={10000}
/>
```

![](examples/demo12.gif)

## Props

## CircularProgressBase Props
Expand Down Expand Up @@ -381,5 +409,28 @@ CircularProgress component accepts all CircularProgressBase props except the chi
| valuePrefixStyle | custom styling to value prefix. Use this to customize the styling of the value prefix. If not provided, the progress value style/colors will be used. | TextStyle | {} | false |
| valueSuffixStyle | custom styling to value suffix. Use this to customize the styling of the value suffix. If not provided, the progress value style/colors will be used. | TextStyle | {} | false |

## Methods

`pause`
Imperative method to pause the animation.

```javascript
progressRef.current.pause();
```

`play`
Imperative method to play the animation once paused.

```javascript
progressRef.current.play();
```

`reAnimate`
Imperative method to restart the animation.

```javascript
progressRef.current.reAnimate();
```

## License
This project is licenced under the MIT License.
This project is licensed under the MIT License.
Binary file added examples/demo12.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-circular-progress-indicator",
"version": "4.3.0",
"version": "4.4.0",
"description": "React Native customizable circular progress indicator",
"main": "lib/commonjs/index",
"module": "lib/module/index",
Expand Down Expand Up @@ -125,5 +125,8 @@
"<rootDir>/lib/"
],
"transformIgnorePatterns": []
},
"dependencies": {
"react-native-redash": "*"
}
}
111 changes: 63 additions & 48 deletions src/circularProgress/index.tsx
Original file line number Diff line number Diff line change
@@ -1,59 +1,68 @@
import React, {useMemo} from 'react';
import {Text, StyleSheet, View} from 'react-native';
import React, { forwardRef, useImperativeHandle, useMemo } from 'react';
import { Text, StyleSheet, View } from 'react-native';

import ProgressCircle from '../components/progressCircle';
import useAnimatedValue from '../hooks/useAnimatedValue';
import COLORS from '../utils/colors';
import type {CircularProgressProps} from '../types';
import type { CircularProgressProps, ProgressRef } from '../types';
import ProgressValue from '../components/progressValue';

import styles from './styles';

const CircularProgress: React.FC<CircularProgressProps> = ({
value,
initialValue = 0,
circleBackgroundColor = COLORS.TRANSPARENT,
radius = 60,
duration = 500,
delay = 0,
maxValue = 100,
strokeLinecap = 'round',
onAnimationComplete = () => null,
activeStrokeColor = COLORS.GREEN,
activeStrokeSecondaryColor = null,
activeStrokeWidth = 10,
inActiveStrokeColor = COLORS.BLACK_30,
inActiveStrokeWidth = 10,
inActiveStrokeOpacity = 1,
clockwise = true,
rotation = 0,
title = '',
titleStyle = {},
titleColor,
titleFontSize,
progressValueColor,
progressValueStyle = {},
progressValueFontSize,
valuePrefix = '',
valueSuffix = '',
showProgressValue = true,
subtitle = '',
subtitleStyle = {},
subtitleColor,
subtitleFontSize,
progressFormatter = (v: number) => {
'worklet';
// eslint-disable-next-line max-len, prettier/prettier
const CircularProgress = forwardRef<ProgressRef, CircularProgressProps>((props, ref) => {
const {
value,
initialValue = 0,
circleBackgroundColor = COLORS.TRANSPARENT,
radius = 60,
duration = 500,
delay = 0,
maxValue = 100,
strokeLinecap = 'round',
onAnimationComplete = () => null,
activeStrokeColor = COLORS.GREEN,
activeStrokeSecondaryColor = null,
activeStrokeWidth = 10,
inActiveStrokeColor = COLORS.BLACK_30,
inActiveStrokeWidth = 10,
inActiveStrokeOpacity = 1,
clockwise = true,
rotation = 0,
title = '',
titleStyle = {},
titleColor,
titleFontSize,
progressValueColor,
progressValueStyle = {},
progressValueFontSize,
valuePrefix = '',
valueSuffix = '',
showProgressValue = true,
subtitle = '',
subtitleStyle = {},
subtitleColor,
subtitleFontSize,
progressFormatter = (v: number) => {
'worklet';

return Math.round(v);
},
allowFontScaling = true,
dashedStrokeConfig = {count: 0, width: 0},
valuePrefixStyle = {},
valueSuffixStyle = {},
strokeColorConfig = undefined,
}: CircularProgressProps) => {
const {animatedCircleProps, animatedTextProps, progressValue} =
useAnimatedValue({
return Math.round(v);
},
allowFontScaling = true,
dashedStrokeConfig = { count: 0, width: 0 },
valuePrefixStyle = {},
valueSuffixStyle = {},
strokeColorConfig = undefined,
} = props;

const {
animatedCircleProps,
animatedTextProps,
progressValue,
play,
pause,
reAnimate,
} = useAnimatedValue({
initialValue,
radius,
maxValue,
Expand All @@ -68,6 +77,12 @@ const CircularProgress: React.FC<CircularProgressProps> = ({
strokeColorConfig,
});

useImperativeHandle(ref, () => ({
play,
pause,
reAnimate,
}));

const styleProps = useMemo(
() => ({
radius,
Expand Down Expand Up @@ -189,6 +204,6 @@ const CircularProgress: React.FC<CircularProgressProps> = ({
</View>
</View>
);
};
});

export default CircularProgress;
61 changes: 35 additions & 26 deletions src/circularProgressBase/index.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,39 @@
import React, {useMemo} from 'react';
import React, {forwardRef, useImperativeHandle, useMemo} from 'react';
import {StyleSheet, View} from 'react-native';

import ProgressCircle from '../components/progressCircle';
import useAnimatedValue from '../hooks/useAnimatedValue';
import COLORS from '../utils/colors';
import type {CircularProgressBaseProps} from '../types';
import type {CircularProgressBaseProps, ProgressRef} from '../types';

import styles from './styles';

const CircularProgressBase: React.FC<CircularProgressBaseProps> = ({
value,
initialValue = 0,
circleBackgroundColor = COLORS.TRANSPARENT,
radius = 60,
duration = 500,
delay = 0,
maxValue = 100,
strokeLinecap = 'round',
onAnimationComplete = () => null,
activeStrokeColor = COLORS.GREEN,
activeStrokeSecondaryColor = null,
activeStrokeWidth = 10,
inActiveStrokeColor = COLORS.BLACK_30,
inActiveStrokeWidth = 10,
inActiveStrokeOpacity = 1,
clockwise = true,
rotation = 0,
dashedStrokeConfig = {count: 0, width: 0},
strokeColorConfig = undefined,
children,
}: CircularProgressBaseProps) => {
const {animatedCircleProps} = useAnimatedValue({
// eslint-disable-next-line max-len, prettier/prettier
const CircularProgressBase = forwardRef<ProgressRef,CircularProgressBaseProps>((props, ref) => {
const {
value,
initialValue = 0,
circleBackgroundColor = COLORS.TRANSPARENT,
radius = 60,
duration = 500,
delay = 0,
maxValue = 100,
strokeLinecap = 'round',
onAnimationComplete = () => null,
activeStrokeColor = COLORS.GREEN,
activeStrokeSecondaryColor = null,
activeStrokeWidth = 10,
inActiveStrokeColor = COLORS.BLACK_30,
inActiveStrokeWidth = 10,
inActiveStrokeOpacity = 1,
clockwise = true,
rotation = 0,
dashedStrokeConfig = {count: 0, width: 0},
strokeColorConfig = undefined,
children,
} = props;

const {animatedCircleProps, play, pause, reAnimate} = useAnimatedValue({
initialValue,
radius,
maxValue,
Expand All @@ -44,6 +47,12 @@ const CircularProgressBase: React.FC<CircularProgressBaseProps> = ({
strokeColorConfig,
});

useImperativeHandle(ref, () => ({
play,
pause,
reAnimate,
}));

const styleProps = useMemo(
() => ({
radius,
Expand Down Expand Up @@ -78,6 +87,6 @@ const CircularProgressBase: React.FC<CircularProgressBaseProps> = ({
</View>
</View>
);
};
});

export default CircularProgressBase;
Loading

0 comments on commit 77eb78c

Please sign in to comment.