vydimitrov / react-countdown-circle-timer

Lightweight React/React Native countdown timer component with color and progress animation based on SVG

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Inaccurate progress when used as a progress bar

1280103995 opened this issue · comments

commented
  1. Create a new project via RN CLI
  2. Run yarn add yarn add react-native-countdown-circle-timer react-native-svg
"dependencies": {
    "react": "18.0.0",
    "react-native": "0.69.0",
    "react-native-countdown-circle-timer": "^3.0.9",
    "react-native-svg": "^12.4.3"
  },
Screen_Recording_20220804-180229_demo069.mp4

App.js

import React, {useState} from 'react';
import {useCountdown} from 'react-native-countdown-circle-timer';
import {Button, Text, TextInput, View} from 'react-native';
import {Defs, LinearGradient, Path, Stop, Svg} from 'react-native-svg';

const CountdownCircleTimer = props => {
  const {
    path,
    pathLength,
    stroke,
    strokeDashoffset,
    remainingTime,
    elapsedTime,
    size,
    strokeWidth,
  } = useCountdown({...props, colors: 'url(#your-unique-id)'});

  return (
    <Svg width={size} height={size} style={{marginTop: 30}}>
      <Defs>
        <LinearGradient id="your-unique-id" x1="1" y1="0" x2="0" y2="0">
          <Stop offset="5%" stopColor="gold" />
          <Stop offset="95%" stopColor="red" />
        </LinearGradient>
      </Defs>
      <Path d={path} fill="none" stroke="#d9d9d9" strokeWidth={strokeWidth} />

      {props.duration > 0 && (
        <Path
          d={path}
          fill="none"
          stroke={stroke}
          strokeLinecap="butt"
          strokeWidth={strokeWidth}
          strokeDasharray={pathLength}
          strokeDashoffset={strokeDashoffset}
        />
      )}
    </Svg>
  );
};

export default function App() {
  const [durationText, setDurationText] = useState('');
  const [initialRemainingTimeText, setInitialRemainingTimeText] = useState('');
  const [duration, setDuration] = useState(60);
  const [initialRemainingTime, setInitialRemainingTime] = useState(30);

  const onDurationChange = text => {
    setDurationText(text);
  };

  const onInitialRemainingTime = text => {
    setInitialRemainingTimeText(text);
  };

  return (
    <View style={{flex: 1, alignItems: 'center', marginTop: 100}}>
      <Text style={{marginBottom: 20}}>
        {'Default duration is 60. \nDefault initialRemainingTime is 30'}
      </Text>
      <View style={{flexDirection: 'row'}}>
        <Text style={{marginRight: 20}}>Set duration to</Text>
        <TextInput
          keyboardType={'numeric'}
          style={{width: 100, height: 40, backgroundColor: '#d5d9de'}}
          onChangeText={onDurationChange}
        />
      </View>
      <View style={{flexDirection: 'row', marginVertical: 30}}>
        <Text style={{marginRight: 20}}>Set initialRemainingTime to</Text>
        <TextInput
          keyboardType={'numeric'}
          style={{width: 100, height: 40, backgroundColor: '#d5d9de'}}
          onChangeText={onInitialRemainingTime}
        />
      </View>
      <Button
        title={'Start'}
        onPress={() => {
          setDuration(parseInt(durationText));
          setInitialRemainingTime(parseInt(initialRemainingTimeText));
        }}
      />
      <CountdownCircleTimer
        duration={duration}
        initialRemainingTime={initialRemainingTime}
      />
    </View>
  );
}

Hey @1280103995, you will need to reset the timer when you change and time or when you click the Start button. You will need to pass a key prop to the CountdownCircleTimer component like so:

const [key, setKey] = useState(0)

<CountdownCircleTimer
        key={key}
        duration={duration}
        initialRemainingTime={initialRemainingTime}
      />

// When you click the Start button then you do 
setKey(prevKey => prevKey+1)

This will reset the timer, take the new values and it will work as expected.

commented

Hey @1280103995, you will need to reset the timer when you change and time or when you click the Start button. You will need to pass a key prop to the CountdownCircleTimer component like so:

const [key, setKey] = useState(0)

<CountdownCircleTimer
        key={key}
        duration={duration}
        initialRemainingTime={initialRemainingTime}
      />

// When you click the Start button then you do 
setKey(prevKey => prevKey+1)

This will reset the timer, take the new values and it will work as expected.

Thanks, it works fine now.