I am learning javascript and react and here I am stuck in the challange that where I have to set time according to SVG image’s length (something like progress bar).
For an ease and basic example, I am calculating total time of 24 hours in 1440 minutes and I have given passed time let passedMins = 1220
Now I need to fill the green line in svg circle according to the time elapse. Like every minute green line should add up more
JavaScript
x
30
30
1
import React, {
2
useState,
3
useEffect
4
} from 'react';
5
6
function Clock(props) {
7
8
useEffect(() => {
9
const circle = document.querySelector('circle');
10
const circleLength = Math.floor(circle.getTotalLength());
11
const perMinArea = circleLength / 1440;
12
let passedMins = 1220;
13
const fillArea = passedMins * perMinArea;
14
circle.style.strokeDasharray = circleLength - fillArea;
15
// circle.style.strokeDashoffset = circleLength -fillArea;
16
17
}, [props.time])
18
19
return (
20
<div className = "clock-space" >
21
<div className = "clock" >{props.time}</div>
22
<svg width = "130" height = "130" className = "circle" viewBox = "0 0 130 130" fill = "none" xmlns = "http://www.w3.org/2000/svg">
23
<circle cx="65" cy="65" r="61.5" stroke="lightgreen" strokeWidth="7"/>
24
</svg>
25
</div >
26
);
27
}
28
29
export default Clock;
30
It looks like this:
It shows 3 lines where I want only one. Any suggestion to fix it?
Advertisement
Answer
You need to also pass the length of the circle to the circle.style.strokeDasharray
. To do this, you need to get the length for the “minutes left” in terms of the circle’s total length. Please see example below.
JavaScript
1
18
18
1
const circle = document.querySelector('circle');
2
const timeLeftLabel = document.getElementById('time-left');
3
const circleLength = Math.floor(circle.getTotalLength());
4
const maxMinutes = 1440;
5
let passedMins = 1220;
6
let minsLeft = maxMinutes - passedMins;
7
8
// get percentage of minutes left
9
let minsLeftPercentage = minsLeft / maxMinutes;
10
11
// x % of length where x = minsLeftPercentage
12
let leftLength = minsLeftPercentage * circleLength;
13
14
//combine leftLength and circleLength into comma-separated string
15
circle.style.strokeDasharray = leftLength + ',' + circleLength;
16
17
//just simple implementation for the {props.time}
18
timeLeftLabel.innerText = minsLeft + ' minutes left';
JavaScript
1
6
1
<div className="clock-space">
2
<div className="clock" id="time-left"></div>
3
<svg width="130" height="130" className="circle" viewBox="0 0 130 130" fill="none" xmlns="http://www.w3.org/2000/svg">
4
<circle cx="65" cy="65" r="61.5" stroke="lightgreen" strokeWidth="7"/>
5
</svg>
6
</div>