Skip to content

Instantly share code, notes, and snippets.

@newbornfrontender
Created April 22, 2020 13:56
Show Gist options
  • Save newbornfrontender/9754fb93217daabc0a9e535978899a9b to your computer and use it in GitHub Desktop.
Save newbornfrontender/9754fb93217daabc0a9e535978899a9b to your computer and use it in GitHub Desktop.
Countdown
import { FC, useState, useEffect } from 'react';
import { Count, Timer } from './styled';
interface IProps {
initialTime: number;
}
const Countdown: FC<IProps> = ({ initialTime }) => {
const [strokeDasharray, setStrokeDasharray] = useState('283');
const [timer, setTimer] = useState(initialTime);
let timePassed = 0;
let timeLeft = initialTime;
let timerInterval = null;
const startTimer = () => {
timerInterval = setInterval(() => {
timePassed = timePassed += 1;
timeLeft = initialTime - timePassed;
setTimer(formatTime(timeLeft));
setCircleDasharray();
if (timeLeft === 0) onTimesUp();
}, 1000);
};
const onTimesUp = () => {
clearInterval(timerInterval);
};
useEffect(() => {
startTimer();
}, []);
const formatTime = time => {
return time % 60;
};
const calculateTimeFraction = () => {
const rawTimeFraction = timeLeft / initialTime;
return rawTimeFraction - (1 / 60) * (1 - rawTimeFraction);
};
const setCircleDasharray = () => {
const circleDasharray = `${(calculateTimeFraction() * 283).toFixed(0)} 283`;
setStrokeDasharray(circleDasharray);
};
return (
<Count>
<svg
className="svg"
viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg"
>
<g className="circle">
<circle className="path-elapsed" cx="50" cy="50" r="45" />
<path
strokeDasharray={strokeDasharray}
className="path-remaining"
d="
M 50, 50
m -45, 0
a 45,45 0 1,0 90,0
a 45,45 0 1,0 -90,0
"
/>
</g>
</svg>
<Timer>{timer}</Timer>
</Count>
);
};
export default Countdown;
import styled from 'styled-components';
export const Count = styled.div`
position: relative;
width: 30rem;
height: 30rem;
.svg {
transform: scaleX(-1);
}
.circle {
fill: none;
stroke: none;
}
.path-elapsed {
stroke-width: 0.7rem;
stroke: grey;
}
.path-remaining {
stroke-width: 0.7rem;
stroke-linecap: round;
transform: rotate(90deg);
transform-origin: center;
transition: 1s linear all;
fill-rule: nonzero;
stroke: currentColor;
color: green;
}
`;
export const Timer = styled.span`
position: absolute;
width: 30rem;
height: 30rem;
top: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 4.8rem;
`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment