Currently, I am in the process of developing a progress circle bar that will function as a timer alongside sliders. Each slide is intended to have its own corresponding progress bar.
While I have managed to create the bars individually, I am facing challenges with synchronizing them effectively.
The issue is clearly illustrated by the following GIF: https://i.sstatic.net/NMvSA.gif
As evident from the demonstration, the synchronization is not functioning as intended. My goal is for each bar to fill 100% of the circle, then transition to the next dot and repeat the cycle seamlessly. However, achieving this seamless synchronization has proven to be quite difficult.
In scenarios where only one dot is present, the functionality appears to work correctly, as shown here: https://i.sstatic.net/lwloH.gif
To provide some insight into my approach, I am utilizing two setTimeout functions. One is responsible for decreasing the 'stroke-dashoffset' property of the 'circle' element through the manipulation of 'percentage', thereby filling the bar. The second setTimeout function is specifically designed to display the circle surrounding the subsequent dot. A variable named 'timer' regulates the timing of these changes and is embedded within the second setTimeout function. While I suspect that the issue may stem from the time interval between the two setTimeout functions, this is merely speculation on my part.
Although I initially attempted to implement hooks, I encountered difficulties when attempting to replicate the functionality on Codepen. Consequently, I resorted to creating a code snippet featuring a class component; however, the performance was even more erratic than expected. The underlying reasons for this discrepancy remain unclear to me, particularly since both implementations adhere to similar principles.
For reference, you can view the class component code snippet on Codepen via the following link: https://codepen.io/WegisSilveira/pen/poyPVWq.
Subsequently, provided below is my code incorporating hooks. The CSS remains consistent with the styling utilized in the aforementioned Codepen sample:
import React, { Fragment } from 'react'
import './ProgressBar.css'
const ProgressBar = props => {
let [sqSize, setSqSize] = React.useState(30)
let [percentage, setPercentage] = React.useState(0)
let [strokeWidth, setStrokeWidth] = React.useState(3)
let [trigger, setTrigger] = React.useState(false)
let [barIndex, setBarIndex] = React.useState(0)
let bars = Array(props.bar).fill(1)
let timer = 3000
const barTriggerHandler = () => {
setTrigger(!trigger)
}
if (trigger) {
setTimeout(() => {
percentage < 99 ? setPercentage(percentage + 1) : setPercentage(0)
}, timer / 100);
setTimeout(() => {
console.log(percentage)
barIndex < bars.length - 1 ? setBarIndex(barIndex + 1) : setBarIndex(0)
}, timer);
}
// SVG centers the stroke width on the radius, subtract out so circle fits in square
const radius = (sqSize - strokeWidth) / 2;
// Enclose cicle in a circumscribing square
const viewBox = `0 0 ${sqSize} ${sqSize}`;
// Arc length at 100% coverage is the circle circumference
const dashArray = radius * Math.PI * 2;
// Scale 100% coverage overlay with the actual percent
const dashOffset = dashArray - dashArray * percentage / 100;
// console.log(dashOffset)
return (
<Fragment>
{ bars.map((bar, i) => {
return <svg
key={i}
width={sqSize}
height={sqSize}
viewBox={viewBox}
onClick={() => barTriggerHandler()}
>
{ i === barIndex ?
<Fragment>
<circle
className="circle-progress"
cx={sqSize / 2}
cy={sqSize / 2}
r={radius}
strokeWidth={`${strokeWidth}px`}
// Start progress marker at 12 O'Clock
transform={`rotate(-90 ${sqSize / 2} ${sqSize / 2})`}
style={{
strokeDasharray: dashArray,
strokeDashoffset: dashOffset
}}
/>
</Fragment>
: null }
<circle
className="circle-center"
cx="50%"
cy="50%"
r="3"
/>
</svg>
}) }
</Fragment>
);
}
export default ProgressBar
Given that the progress circle embellishment relies heavily on the utilization of 'svg' and 'circle' elements, it is plausible that the problem stems from this particular setup. Prior to embarking on this endeavor, I had limited familiarity with these tags, which has inevitably contributed to my current predicament.
If anyone possesses the expertise necessary to assist me in resolving this dilemma, your guidance would be immensely appreciated. At this juncture, this challenge is causing considerable frustration, and any assistance rendered would be invaluable.
P.S. The inspiration for creating this form of progress bar was drawn from the pen available at the following link: https://codepen.io/bbrady/pen/ozrjKE?editors=1010