After successfully implementing a timer using CSS with animation, everything was working as expected. However, I encountered an issue when trying to convert it into JSX inline styles in React. The animation stopped working as smoothly as before due to the dynamic nature of the animation duration.
<div className="wrapper">
<div className="pie spinner" style={{
animationDuration: `${sessionTimeout}s`,
animationTimingFunction: "linear",
animationDelay: `0s`,
animationIterationCount: "infinite",
animationDirection: "normal",
animationFillMode: "none",
animationPlayState: "running",
animationName: "timer__rotate"
}}></div>
<div className="pie filler" style={{
animationDuration: `${sessionTimeout}s`,
animationTimingFunction: `steps(1)`,
animationDelay: `0s`,
animationIterationCount: "infinite",
animationDirection: "reverse",
animationFillMode: "none",
animationPlayState: "running",
animationName: "timer__opacity"}}></div>
<div className="mask" style={{
animationDuration: `${sessionTimeout}s`,
animationTimingFunction: `steps(1)`,
animationDelay: `0s`,
animationIterationCount: "infinite",
animationDirection: "normal",
animationFillMode: "none",
animationPlayState: "running",
animationName: "timer__opacity"}}></div>
<div className="timer">
<div className="remaining_time">
{sessionTimeout}
</div>
<div className="time">
Seconds
</div>
</div>
</div>
CSS
.wrapper {
position: relative;
margin: 40px auto;
background: #fff;
}
.wrapper, .wrapper * {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.wrapper {
width: 125px;
height: 125px;
}
.timer{
position: absolute;
top: 25%;
left: 25%;
z-index: 4;
text-align: center;
}
.timer .remaining_time{
font-size: 1.8rem;
font-weight: bold;
}
.timer .time{
font-family: Roboto;
line-height: 14px;
text-align: center;
font-size: 17px;
margin-bottom: 0px;
color: #000;
}
.wrapper .pie {
width: 50%;
height: 100%;
transform-origin: 100% 50%;
position: absolute;
background: #f3f3f3;
border: 5px solid rgba(2, 155, 237, 1);
}
.wrapper .spinner {
border-radius: 100% 0 0 100% / 50% 0 0 50%;
z-index: 2;
border-right: none;
/* animation: timer__rotate 60s linear infinite; */
}
.wrapper:hover .spinner,
.wrapper:hover .filler,
.wrapper:hover .mask {
animation-play-state: running;
}
.wrapper .filler {
border-radius: 0 100% 100% 0 / 0 50% 50% 0;
left: 50%;
opacity: 0;
z-index: 1;
/* animation: timer__opacity 60s steps(1, end) infinite reverse; */
border-left: none;
}
.wrapper .mask {
width: 50%;
height: 100%;
position: absolute;
background: inherit;
opacity: 1;
z-index: 3;
/* animation: timer__opacity 60s steps(1, end) infinite; */
}
@keyframes timer__rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes timer__opacity {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}