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
import React, { useState, useEffect } from 'react'; function Clock(props) { useEffect(() => { const circle = document.querySelector('circle'); const circleLength = Math.floor(circle.getTotalLength()); const perMinArea = circleLength / 1440; let passedMins = 1220; const fillArea = passedMins * perMinArea; circle.style.strokeDasharray = circleLength - fillArea; // circle.style.strokeDashoffset = circleLength -fillArea; }, [props.time]) return ( <div className = "clock-space" > <div className = "clock" >{props.time}</div> <svg width = "130" height = "130" className = "circle" viewBox = "0 0 130 130" fill = "none" xmlns = "http://www.w3.org/2000/svg"> <circle cx="65" cy="65" r="61.5" stroke="lightgreen" strokeWidth="7"/> </svg> </div > ); } export default Clock;
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.
const circle = document.querySelector('circle'); const timeLeftLabel = document.getElementById('time-left'); const circleLength = Math.floor(circle.getTotalLength()); const maxMinutes = 1440; let passedMins = 1220; let minsLeft = maxMinutes - passedMins; // get percentage of minutes left let minsLeftPercentage = minsLeft / maxMinutes; // x % of length where x = minsLeftPercentage let leftLength = minsLeftPercentage * circleLength; //combine leftLength and circleLength into comma-separated string circle.style.strokeDasharray = leftLength + ',' + circleLength; //just simple implementation for the {props.time} timeLeftLabel.innerText = minsLeft + ' minutes left';
<div className="clock-space"> <div className="clock" id="time-left"></div> <svg width="130" height="130" className="circle" viewBox="0 0 130 130" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="65" cy="65" r="61.5" stroke="lightgreen" strokeWidth="7"/> </svg> </div>