vydimitrov / react-countdown-circle-timer Goto Github PK
View Code? Open in Web Editor NEWLightweight React/React Native countdown timer component with color and progress animation based on SVG
License: MIT License
Lightweight React/React Native countdown timer component with color and progress animation based on SVG
License: MIT License
I'm trying to control the CountdownCircleTimer
in some more controlled way, as I need the same Timer to have distinct behaviors depending on the current time. E.g. if near some meeting date, the Timer renders with some rules, if not near, the Timer renders with other rules. And inside the proximity of a meeting, the Timer has different behaviors depending on the proximity in time.
This means that I need to be able to change trailColor
, colors
and duration
at specific points in time, all this controlled by a parent component.
I have successfully did that but the problem is that I'm running in issues like this one:
Because the information is in the parent TimerField's state, when that state is changed and it happens that the CountdownCircleTimer
is being rendered, then I get this error. This is more easily reproducible if we pass parent functions that sets state as parameters of renderTime
, then execute them inside renderTime
after doing some test (e.g. testing if the countdown reached some value).
Is that a known issue? Can't I freely manipulate the CountdownCircleTimer
attributes after Timer is started?
It seems the initialRemaining time cannot be set programmatically.
Only when the values are hard coded they seem to pick and display the colored and the greyed out area in the timer circle properly
Suppose if the values had to be set programmatically for instance, it doesn't seem to pick up.
Use Case - if the user refreshed the page before the duration expiry I need to start from where he left
Hi!
It looks cool, I'm trying to use it on RN but doesn't seem to work.
It always gives me Invariat violation
.
Any advice?
Hi Vydimitrov
need help
I would like to use CountdownCircleTime as a time counter, instead of having to implement a setInterval.
So, what I need is that every time a onCompleted, activate a method that updates my page.
So that I can control how many times the page has been updated.
I have a problem when rendering onComplete.
I need to define the variable with useState, as soon as there is a complete loop (onComplete), however, at this moment, react complains saying:
Warning: Cannot update a component ('Home') while rendering a different componet ('CountdownCircleTime'). To locate the bad setState() call insede 'CountDownCircleTime'.
react: 16.12.0,
react-dom: 16.12.0,
react-countdown-circle-timer: 2.1.2
import React, { useEffect, useState } from 'react';
import { CountdownCircleTimer } from 'react-countdown-circle-timer';
function Home() {
const [count, setCount] = useState(1);
const [play, setPlay] = useState(true);
const updateComponentes = () => {
console.log('Refresh my components, count:', count);
};
const stopCount = () => {
// does not execute this method
setPlay(false);
};
useEffect(() => {
if (count < 3) updateComponentes();
else stopCount();
}, [count]);
return (
<CountdownCircleTimer
isPlaying={play}
duration={8}
colors={[
['#2185d0', 0.5],
['#2185d0', 0.5]
]}
onComplete={() => {
setCount(count + 1);
return [true, 1002]; // on the second lap, the component breaks and does not execute that line
}}
size={25}
strokeWidth={4}
/>
);
}
export default Home;
Thank you for your attention
I stumbled upon this project when a client requested a count time timer that looks like this.
The react-countdown-circle-time works great but would be even better if I could show some amount of time already elapsed when the component mounts. Seems this would be a dual request with react-countdown-circle-time and use-elapsed-time. Which would need to support an initial elapsed time config option. While I can work with seconds, it would be great if the component supported a unit of time other than seconds out of the box.
There seems no way to change the wrapper style..this would be a nice feature :) https://github.com/vydimitrov/react-countdown-circle-timer/blob/master/packages/shared/utils/styles.js
The onComplete function is not triggered when we are on a different tab. It gets executed only when we come back.
Hello,
First of all, thank you for this awesome library.
I have an issue and I don't know if it's a bug or I just implemented it wrong.
So my score prop gets updated, but when onComplete
gets triggered, it does not reflect the correct value of the prop.
simplified code:
const MyComp = ({
score
}) => {
console.log(score); // ITS OK, UPDATING
return (
<CountdownCircleTimer
isPlaying
size={60}
duration={10}
strokeWidth={5}
onComplete={() =>{
console.log(score); // SHOWS 0
}}
colors={[[Colors[colorScheme].tint, 0.33], ['#F7B801', 0.33], ['#A30000']]}>
{({ remainingTime, animatedColor }) => (
<Animated.Text
style={{ ...styles.remainingTime, color: animatedColor }}>
{remainingTime}
</Animated.Text>
)}
</CountdownCircleTimer>
)
}
Any advice?
I have an array of integers that I would like the timer to map through and use as the new duration each time it completes a countdown. Currently, I call the onComplete function set the duration variable to the next index of the array, then change the key variable, return shouldRepeat as true. It looks like this:
`export default function Timer(){
const array = [10, 20, 30, 25, 15];
const [key, setKey] = useState(1);
const [index, setIndex]= useState(0);
const [time, setTime] = useState(array[0]);
const handleComplete = () => {
setIndex(index +1);
setTime(array[index]);
setKey(key+1);
return [true, 0];
}
return (
<CountdownTimer
key={key}
duration={time}
colors={[["#004777", 0.33], ["#F7B801", 0.33], ["#A30000"]]}
onComplete={handleComplete}
{({ remainingTime, animatedColor }) => (
<Animated.Text
style={{
color: animatedColor,
fontSize: 90,
fontFamily: "Verdana-Bold",
}}
>
{remainingTime}
</Animated.Text>
)}
);
}`
The issue is that this causes an error:
Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s, a useEffect cleanup function,
in CountdownCircleTimer (at timer.js:82)
Does anyone have any insight into how to fix this?``
I'm trying to implement this timer component in a realtime web application with Firebase. The timer is getting it's props from Firebase and is being controlled via an admin interface where the values are being updated. It is somewhat randomly crashing when the timer completes though and displaying both of these errors...
Uncaught TypeError: Cannot read property 'duration' of undefined
at index.js:1
at CountdownCircleTimer (index.js:1)
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
I can pretty consistently make it crash on completion by changing the duration while it's running to a shorter time than what was originally set.
Conversely, if I set it to longer that the initial duration while it's running, the countdown won't complete. It will get stuck at the difference of the original duration and the new duration. Such as, if it was originally 10 seconds and then I pass it a new duration on the fly of 12, it will get stuck when it reaches 2 seconds.
Is dynamically setting the duration while the timer is running not supported?
Here is my code on the user side (we call them 'participants')...
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { useFirestore } from 'react-redux-firebase'
import moment from 'moment';
import "moment-duration-format";
import { CountdownCircleTimer } from 'react-countdown-circle-timer';
import './participantTimer.scss';
const ParticipantTimer = ({session}) => {
// session object comes from Firebase and can be
// updated on the fly while the timer is running which
// would push a new duration into the timer component
const [durationSeconds, setDurationSeconds] = useState(0);
const timerValue = session.timerValue || 0;
const timerRunning = session.timerRunning || false;
const timerStartedAt = session.timerStartedAt || 0;
const db = useFirestore();
useEffect(() => {
// if the participant joined after the timer was started by the admin,
// make sure they are seeing the same time as everyone else
let duration = timerRunning && timerValue
? timerValue - (db.Timestamp.now().seconds - timerStartedAt)
: timerValue;
if (duration < 0) {
// this could happen if the user refreshes the
// page while the timer is running
duration = 0;
}
setDurationSeconds(duration);
}, [timerValue, timerStartedAt, timerRunning])
const renderTime = value => {
const renderedTimer = value > 60
? moment.duration(value, 'seconds').format('m:ss')
: value;
return (
<div className="timer">
<div className="value">{renderedTimer}</div>
</div>
);
};
return (
<div className="participant-timer">
<CountdownCircleTimer
key={timerStartedAt}
isPlaying={timerRunning}
durationSeconds={durationSeconds}
colors={[['#d9d9d9', 0.0001],["#02A05C", 0.89], ["#02A05C", 0.01], ["#E2351E"]]}
renderTime={renderTime}
onComplete={() => [false, 0]}
size={160}
strokeWidth={15}
/>
</div>
)
}
ParticipantTimer.propTypes = {
session: PropTypes.object.isRequired
}
export default ParticipantTimer
...and here is the code on the admin side where the timer values are being updated. This view also display's the timer for the admin. Ideally the admin and participants all see basically the same thing...
import React, { useState, useEffect } from 'react'
import PropTypes from 'prop-types'
import { useFirestore } from 'react-redux-firebase'
import moment from 'moment';
import "moment-duration-format";
import { CountdownCircleTimer } from 'react-countdown-circle-timer';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import TextField from '@material-ui/core/TextField';
import ActionDialog from '../Dialogs/ActionDialog';
const AdminTimer = ({session}) => {
// session is also coming from firebase here
const [showDialog, setShowDialog] = useState(false);
const [minutes, setMinutes] = useState(0);
const [seconds, setSeconds] = useState(0);
const [durationSeconds, setDurationSeconds] = useState(0);
const timerValue = session.timerValue || 0;
const timerRunning = session.timerRunning || false;
const timerStartedAt = session.timerStartedAt || 0;
const db = useFirestore();
useEffect(() => {
let duration = timerRunning && timerValue
? timerValue - (db.Timestamp.now().seconds - timerStartedAt)
: timerValue;
if (duration < 0) {
duration = 0;
}
setDurationSeconds(duration);
}, [timerValue, timerStartedAt, timerRunning])
const setSessionTimer = async (timerMinutes = 0, timerSeconds = 0) => {
const actualSeconds = +timerMinutes * 60 + +timerSeconds;
await db.doc(`sessions/${session.id}`).update({
timerValue: actualSeconds,
timerRunning,
timerStartedAt: timerRunning ? db.Timestamp.now().seconds : timerStartedAt,
});
setShowDialog(false);
}
const startSessionTimer = async () => {
const fbTime = db.Timestamp.now().seconds;
await db.doc(`sessions/${session.id}`).update({
timerRunning: true,
timerStartedAt: fbTime
});
}
const cancelSessionTimer = async () => {
await db.doc(`sessions/${session.id}`).update({
timerRunning: false,
timerValue: 0,
timerStartedAt: 0,
});
}
const timerEnded = () => {
setTimeout(() => {
db.doc(`sessions/${session.id}`).update({
timerValue: 0,
timerStartedAt: 0,
timerRunning: false,
})
}, 1000);
}
const onComplete = () => {
timerEnded();
return [false, 0];
}
const renderTime = value => {
const renderedTimer = value > 60
? moment.duration(value, 'seconds').format('m:ss')
: value;
return (
<div className="timer">
<div style={{fontSize: '20px'}}>{renderedTimer}</div>
</div>
);
};
return (
<div className="d-flex flex-column">
<Button onClick={() => setShowDialog(true)}>
<CountdownCircleTimer
key={timerStartedAt}
isPlaying={timerRunning}
durationSeconds={durationSeconds}
colors={[['#d9d9d9', 0.0001],["#02A05C", 0.89], ["#02A05C", 0.01], ["#E2351E"]]}
renderTime={renderTime}
onComplete={onComplete}
size={80}
strokeWidth={5}
/>
</Button>
{(!timerRunning) &&
<Button onClick={startSessionTimer} className="align-self-center">
Start
</Button>
}
{timerRunning &&
<Button onClick={cancelSessionTimer} className="align-self-center">
Cancel
</Button>
}
{/* Form Dialog for setting the timer */}
<ActionDialog
onClose={() => setShowDialog(false)}
open={showDialog}
contentClassNames="d-flex justify-content-center"
actionsClassNames="d-flex justify-content-between"
title="Set Session Timer"
maxWidth="xs"
actions={[
{ label: 'Cancel', onClick: () => setShowDialog(false) },
{ label: 'Set Timer', onClick: () => setSessionTimer(minutes, seconds) }
]}>
<div className="d-flex align-items-end">
<TextField
name="name"
type="number"
label="Minutes"
value={minutes}
onChange={event => setMinutes(event.target.value)}
InputProps={{
style: { maxWidth: 44 }
}}
inputProps={{
min: '0'
}}
/>
<Typography className="mx-3">:</Typography>
<TextField
name="seconds"
type="number"
label="Seconds"
inputProps={{ max: '60', min: '0' }}
value={seconds}
onChange={event => setSeconds(event.target.value)}
InputProps={{
style: { maxWidth: 44 }
}}
/>
</div>
</ActionDialog>
</div>
)
}
AdminTimer.propTypes = {
session: PropTypes.object.isRequired
}
export default AdminTimer
Any idea what is happening here? We need to be able to update the duration dynamically on the fly while the timer is running.
I didn't find demo of third animation https://user-images.githubusercontent.com/10707142/65963815-cfbdf380-e45b-11e9-809d-970174e88914.gif
Can you help with this? @vydimitrov Even a tutorial how to achieve this animation is accepted.
This bug affects only React Native countdown timer. The Web/React version on the countdown timer works as expected.
It was found that when setting a new state (using useState
hook for example) in the onComplete
handler, the component was going into infinite loop. The component uses internally useEeffect
to track changes of play state, which also has depenedency of onComplete
. When the component re-renders while in finished state (waiting the onCompelte
to return) the onComplete
handler was called again causing the infinite loop.
Resolution: to solve the bug, I am now tracking the finished state. While the component is in finished state, a.k.a waiting for the onComplete
handler to return, if new updates come they will be ignored until the onComplete
finishes. Here is the commit that fixes the issue 0ea726d
Hi, this isn't an issue (feel free to remove or I can delete), but I couldn't find any other contact info. Your circle timer is excellent and the best I've found for smooth/continuous timer display in React.
I've been trying to come up with an implementation where I can use four of the timers to display a countdown from current date to an end date where the timers will displays remaining days, hours, minutes, and seconds.
I have not yet been able to come up with an implementation that will work and was wondering if you have explored this at all yet or have any suggestions. Thanks.
In my program, if they answer all the questions before the time is up I want it to display how fast they completed it, but I can't seem to grab the remainingTime.
const Timer = ({time, timerEnabled, iterIndex, completed}) => {
const [currentTime, setCurrentTime] = React.useState(time);
const renderTime = ({ remainingTime }) => {
setCurrentTime(remainingTime);
if (remainingTime === 0) {
return <div className="timer">Too late...</div>;
}
return (
<div className="timer">
<div className="text">Remaining</div>
<div className="value">{remainingTime}</div>
<div className="text">seconds</div>
</div>
);
};
return (
<div className="timer-wrapper">
<CountdownCircleTimer
isPlaying={iterIndex > 0}
duration={time}
colors={[["#004777", 0.33], ["#F7B801", 0.33], ["#A30000"]]}
onComplete={timerEnabled ? () => completed(currentTime) : [false, 0]}
>
{renderTime}
</CountdownCircleTimer>
</div>
);
};
hi @vydimitrov! thanks for this amazing library :)
I am wondering if you can make the onComplete
callback async. I am getting this error if I try to use an async function:
Uncaught TypeError: Invalid attempt to destructure non-iterable instance.
I thinks it's because useCountdown.js:59
, so probably will be solved if we modify to:
? async (...rest) => {
// REFACTOR in next major release so onComplete matches expected return value as useElapsedTime
const [shouldRepeat = false, delay = 0] = await onComplete(...rest) || []
return { shouldRepeat, delay: delay / 1000, newStartAt: 0 }
}
thanks again!
Hi Vasil,
Really great library, thank you!
I have been reading all of the source code for this component (web) to try to learn and understand how it works.
If you have time to answer a quick question, I'd very much appreciate it!
How does the animation work? I understand this is probably done by requestAnimationFrame or setInterval, but I can't see this called anywhere in the source. I also can't see much use of state to re-render the components. Any help would be great ๐
Thanks again,
Ric
Thanks for this library!
I was wondering if it is possible to reset the timer, but not through onComplete? I am trying to implement something where the timer freezes when a modal opens on the screen, and the user may click a button to reset the timer. However, I have not been able to figure out how to make the timer restart without waiting for it to count all the way down to 0. For example, the timer is counting down from 20, the user clicks on the screen and opens a modal, timer freezes at 15, and the user clicks restart, which starts the timer back at 20.
Again, thanks so much.
Is there a way we can have different durations for the timer when it is repeated upon completion?
I try to follow the example on the docs but every time I try to render the countdown I get:
Invariant Violation: View config not found for name path. Make sure to start component names with a capital letter.
This error is located at:
in path (created by CountdownCircleTimer)
in svg (created by CountdownCircleTimer)
in div (created by CountdownCircleTimer)
Doesn't it seems weird is trying to render a div on react native? am I missing something here?
TIA.
component code:
const Countdown = ({navigation, route}) => {
return (
<View>
<View>
<CountdownCircleTimer
isPlaying
duration={10}
colors={[['#004777', 0.4], ['#F7B801', 0.4], ['#A30000', 0.2]]}>
{({remainingTime, animatedColor}) => (
<Animated.Text style={{color: animatedColor}}>
{remainingTime}
</Animated.Text>
)}
</CountdownCircleTimer>
</View>
<Text>Siguiente:</Text>
<Text>8 Push ups</Text>
</View>
);
};
package.json
{
"name": "frontend",
"version": "0.0.2",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"@apollo/react-hooks": "^3.1.5",
"@react-native-community/async-storage": "^1.11.0",
"@react-native-community/datetimepicker": "^2.3.2",
"@react-native-community/masked-view": "^0.1.7",
"@react-navigation/native": "^5.1.1",
"@react-navigation/stack": "^5.2.9",
"apollo-cache-inmemory": "^1.6.5",
"apollo-client": "^2.6.8",
"apollo-link-http": "^1.5.17",
"graphql": "^15.0.0",
"graphql-tag": "^2.10.3",
"moment": "^2.24.0",
"react": "16.9.0",
"react-apollo": "^3.1.5",
"react-countdown-circle-timer": "^2.3.7",
"react-native": "0.61.5",
"react-native-elements": "^1.2.7",
"react-native-gesture-handler": "^1.6.0",
"react-native-iap": "^4.4.9",
"react-native-mixpanel": "^1.2.0",
"react-native-reanimated": "^1.7.0",
"react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.3.0",
"react-native-svg": "^12.1.0",
"react-native-svg-transformer": "^0.14.3",
"react-native-vector-icons": "^6.6.0"
},
"devDependencies": {
"@babel/core": "^7.6.2",
"@babel/runtime": "^7.9.2",
"@react-native-community/eslint-config": "^0.0.5",
"babel-jest": "^24.9.0",
"eslint": "^6.5.1",
"jest": "^24.9.0",
"metro-react-native-babel-preset": "^0.56.0",
"react-test-renderer": "16.9.0"
},
"jest": {
"preset": "react-native"
}
}
TypeError
Object(...) is not a function
Can be tested in https://codesandbox.io/s/modern-pine-e8jff, only change the react version to 16.5.2
I have this working properly:
export default function TimerField (props) {
return (
<div className='timer-wrapper'>
<CountdownCircleTimer
onComplete={() => [true, 1000]}
duration={20} <===
(...)
And even this:
const durationInSeconds = 20 <===
export default function TimerField (props) {
return (
<div className='timer-wrapper'>
<CountdownCircleTimer
onComplete={() => [true, 1000]}
duration={durationInSeconds} <===
(...)
But when I try something more better structured like this:
export default function TimerField (props) {
const { durationInSeconds } = props <===
return (
<div className='timer-wrapper'>
<CountdownCircleTimer
onComplete={() => [true, 1000]}
duration={durationInSeconds} <===
(...)
It works for one cycle, then it fails before the second cycle with the following error:
It seems that duration
must be some "global constant" for this to work properly. Why can't it be a prop?
Hi!
"react-native-countdown-circle-timer": "2.3.9",
react-native-countdown-circle-timer/types/CountdownCircleTimer.d.ts contains the line
import { Config } from 'use-elapsed-time'
This presumably refers to the use-elapsed-time package. This package is not included as a dependency in react-native-countdown-circle-timer/package.json, which causes TypeScript to emit the error Cannot find module 'use-elapsed-time' or its corresponding type declarations. ts(2307)
.
I've problem for use your lib, this is message error:
./node_modules/react-native-countdown-circle-timer/lib/index.js
Module not found: Can't resolve 'react-native' in /.../...
How to reproduce:
function App() {
return (
<CountdownCircleTimer
key={1}
isPlaying
duration={10}
colors={[['#004777', 0.33], ['#F7B801', 0.33], ['#A30000']]}
onComplete={() => {
console.log('timer complete');
return [true, 1000];
}}
>
{({ remainingTime }) => remainingTime}
</CountdownCircleTimer>
);
}
Here you can see the code: https://github.com/dmitryweiner/test-countdown-timer
This bug disappears when you build the project with "npm run build".
Hi! First of all great library!
Is it possible to add the timer to the notification bar while the app is running in background?
https://codesandbox.io/s/cranky-ardinghelli-qfxqu?fontsize=14&hidenavigation=1&theme=dark
<CountdownCircleTimer
isPlaying
durationSeconds={60}
startAt={20}
colors={[["#A30000"]]}
renderTime={renderTime}
/>
The countdown starts at 60 seconds.
I have forked your awesome library for use with React Native and have got it working by installing react-native-svg, use-elapsed-time and prop-types.
However I now am not able to use the debugger:
Invariant Violation: Calling synchronous methods on native modules is
not supported in Chrome.Consider providing alternative methods to expose this method in debug
mode, e.g. by exposing constants ahead-of-time.This error is located at:
in CountdownCircleTimer (at AppRoot.js:118)
in AppRoot (at App.js:9)
in Provider (at App.js:8)
in App (at renderApplication.js:40)
in RCTView (at AppContainer.js:101)
in RCTView (at AppContainer.js:119)
I have searched high and low for any clues as to which package could be causing the error and I can only see the issue reported relating to react-native-device-info but this is not causing the problem.
Do you have any ideas what could be causing this?
I'm using React not React-native btw.
When passing a refrence to isPlaying the timer is not effected when the refrence value changes. Is there any way to pause/resume the timer otherwise?
I'm trying to make a responsive React app using your component. From the documentation it looks like I can only enter numbers for the size but I need the component to scale accordingly to the users view width. Anyway I can do this?
I've just installed the library into my project, and Im getting an error.
Im using the Basic Usage snippet:
import { CountdownCircleTimer } from 'react-countdown-circle-timer';
const UrgeWithPleasureComponent = () => (
<CountdownCircleTimer
isPlaying
durationSeconds={10}
colors={[
['#004777', .33],
['#F7B801', .33],
['#A30000']
]}
/>
);
and I get this error when I lunch it.:
View config not found for name path, make sure to start component names with a capital letter
whats the problem here??
I like this plugin very much but it lacks the feature i need the most "dynamic duration and initial time change possibility". Add it and this will be the best react native circle countdown plugin.
Error:(42, 33) TS2694: Namespace '"../node_modules/use-elapsed-time/types/use-elapsed-time"' has no exported member 'Config'.
Version: 1.1.0
onComplete appear that it needs to be defined as a type.
Is there a method to restart the timer? I am trying to restart the timer onComplete.
hi, I wasn't sure if creating a new ticket, so if you prefer we can keep talking on the other one.
I am dealing with an issue: timer starts when the tab is focused because (I suppose) requestAnimationFrame
stops when the window is out of focus.
do you have a workaround for this case? in my project, timer should start when the duration
prop is updated independent if browser is focused or not.
thanks!
Potentially a Chrome issue, in my brief testing I didn't experience this in Firefox.
Reproduction steps: When the timer is counting down if change tabs and come back to the tab after you would expect onComplete to be fired, only then is the callback triggered.
At least since version 2.0 there are 5 new versions, but only few of them are described in CHANGELOG.md
for web, README.md
nor Github https://github.com/vydimitrov/react-countdown-circle-timer/releases
.
Please add in one of these 2 places (or an external website) the diff for each version, thanks !
Is it possible to use timer with counting, based on system time, instead of time when site is loaded?
If so, could you share code snipp to achieve this, please?
I understand that I can set the duration to 20 minutes by e. g. filling it with 20 (minutes) x 60 (seconds). That will make the component to start counting down from 1200 seconds to 0 (or 20 minutes to 0).
But I have here a use case that is: count down 10 minutes, then count up 10 minutes (with different colors being shown). I see this being implemented as a more flexible time span: instead of going down from 1200 seconds to 0, I want to go from -600 seconds to 600 seconds. Is it possible with the current API? I tried to use the InitialRemainingTime but no luck. Maybe instead of duration, we could have just a startTime and an endTime, then the actual duration = 1200 would be equal to startTime = 1200 and endTime = 0. Now if we want to change the direction of the countdown, we just change the values (startTime = 0 and endTime = 1200). And if we want to have the effect I mentioned before, we would have startTime = -600 and endTime = 600. All this withouth changing the countdown behavior.
Actually I will try to mimic this with some function that gets the renderTime and converts it to my interval. But I think that it would be nice to have this feature builtin.
I am trying to use your react module. I m now testing it locally in in online sandbox, but w/o success. See following URL for online sandbox: https://codesandbox.io/embed/divine-dawn-qpnci?fontsize=14&hidenavigation=1&theme=dark
The code from sandbox above produces error:
When I try to run it in my environment with this code:
import React from "react";
import { CountdownCircleTimer } from "react-countdown-circle-timer";
import "./styles.css";
class Countdown extends React.Component {
renderTime = value => {
if (value === 0) {
return <div className="timer">Too lale...</div>;
}
return (
<div className="timer">
<div className="text">Remaining</div>
<div className="value">{value}</div>
<div className="text">seconds</div>
</div>
);
};
renderTime = time => {
const currentTime = React.useRef(time);
const prevTime = React.useRef(null);
const isNewTimeFirstTick = React.useRef(false);
const [_, setOneLastRerender] = React.useState(0);
if (currentTime.current !== time) {
isNewTimeFirstTick.current = true;
prevTime.current = currentTime.current;
currentTime.current = time;
} else {
isNewTimeFirstTick.current = false;
}
// force one last re-render when the time is over to tirgger the last animation
if (time === 0) {
setTimeout(() => {
setOneLastRerender(val => val + 1);
}, 20);
}
const isTimeUp = isNewTimeFirstTick.current;
return (
<div className="time-wrapper">
<div key={time} className={`time ${isTimeUp ? "up" : ""}`}>
{time}
</div>
{prevTime.current !== null && (
<div
key={prevTime.current}
className={`time ${!isTimeUp ? "down" : ""}`}
>
{prevTime.current}
</div>
)}
</div>
);
};
render() {
return (
<div className="countdown-wrapper">
<div className="countdown-item">
<CountdownCircleTimer
isPlaying
renderTime={() => {
this.renderTime();
}}
onComplete={() => {
// do your stuff here
return [true, 1500]; // repeat animation in 1.5 seconds
}}
durationSeconds={60}
initialRemainingTime={15}
colors={[["#A30000"]]}
/>
</div>
</div>
);
}
}
export default Countdown;
Once I remove the offending lines, I see white page when using test sandbox below or no text, if running locally in actual website.
You can test it here:
https://codesandbox.io/embed/divine-dawn-qpnci?fontsize=14&hidenavigation=1&theme=dark
Could you please provide fix or show example how to use your module in Class-based React JS project?
TypeError: this._listeners[_key] is not a function. (In 'this._listeners[_key]({
value: value
})', 'this._listeners[_key]' is undefined)
__callListeners
AnimatedNode.js:139:6
__callListeners
AnimatedWithChildren.js:76:4
_updateValue
AnimatedValue.js:246:4
animation.start$argument_1
AnimatedValue.js:211:8
onUpdate
TimingAnimation.js:144:4
onUpdate
[native code]:0
_callTimer
JSTimers.js:137:14
callTimers
JSTimers.js:387:16
__callFunction
MessageQueue.js:425:19
__guard$argument_0
MessageQueue.js:112:6
__guard
MessageQueue.js:373:10
callFunctionReturnFlushedQueue
MessageQueue.js:111:4
callFunctionReturnFlushedQueue
[native code]:0
Hi, is there any way I can edit the circle of the timer?
I created this example https://codesandbox.io/s/countdown-circle-example-ij0nf
and i don't understand why the countdown control not refresh remainingTime when I click on update button.
Is it my mistake or did I not set something well?
If you setState in the callback provided to the onComplete prop results in "cannot update during an existing state transition" error.
I have experienced brief forever looping when setting state multiple times in this callback.
Version: 1.05 and 1.1.0
Whenever changing the size prop, the number stays very small.
Here is how I have it setup:
<CountdownCircleTimer isPlaying size={250} duration={5} colors={[ ['#D9B6FF', 0.4], ['#ce03fc', 0.4], ['#F758A5', 0.2], ]} onComplete={this.props.onZero}> {({remainingTime, animatedColor}) => ( <Animated.Text style={{color: animatedColor}}> {remainingTime} </Animated.Text> )} </CountdownCircleTimer>
How can i give finished date to countdown?
https://codesandbox.io/s/musing-davinci-mqssz?fontsize=14&hidenavigation=1&theme=dark
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.