I'm trying to make my own simple round progress bar to understand arrays and functions more.
I googled some questions, but couldn't find what I need.
Everything works fine so far, except for only one thing.
the function fill()
takes the first given skillPercent
and applies it on all array's elements.
how can I make it change each element according to its given skillPercent
.
var d = document.querySelectorAll(".divb");
var i = d.length;
while (i--) {
if (d[i].className.includes("1")) {
skillPercent = 40;
fill(d[i]);
}
if (d[i].className.includes("2")) {
skillPercent = 70;
fill(d[i]);
}
if (d[i].className.includes("3")) {
skillPercent = 90;
fill(d[i]);
}
function fill(item) {
percent = 1;
setInterval(() => {
if (percent == skillPercent) {
clearInterval(item);
} else {
percent = 0.5;
item.style.background = "conic-gradient( #ff5555 " percent "%, #000 0%)";
}
}, 30);
}
}
body {
display: inline-flex;
}
.div {
width: 130px;
height: 130px;
border-radius: 50%;
display: flex;
color: #fff;
justify-content: center;
align-items: center;
margin: 1px;
background: #555;
}
.divb {
width: 150px;
height: 150px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
margin: 1px;
background-color: #000;
/* background: conic-gradient(#00ff00 30deg, #000 0deg); */
}
<div >
<div >skill1</div>
</div>
<div >
<div >skill2</div>
</div>
<div >
<div >skill3</div>
</div>
CodePudding user response:
You need to firstly define your variables properly either with const, var or let.
You can pass the skillPercent variable into the function which therefore makes the skillPercent unique for each div as Konrad Linkowski said
Then assign the interval as a variable so you can clear it later. Finally, I have slighly adjusted your code so that it reloads every frame and not the slightly "hacky" way of using setInterval at frame rates (but I left in comments if you want it that way too).
var d = document.querySelectorAll(".divb");
var i = d.length;
while (i--) {
if (d[i].className.includes("1")) {
const skillPercent = 40;
fill(d[i], skillPercent);
}
if (d[i].className.includes("2")) {
const skillPercent = 70;
fill(d[i], skillPercent);
}
if (d[i].className.includes("3")) {
const skillPercent = 90;
fill(d[i], skillPercent);
}
function fill(item, skillPercent) {
var percent = 1;
// Perhaps you should use request animation instead of setInterval
// Request animation frame
// Whenever requestAnimationFrame is called, the code inside is executed on the next frame loaded.
// It was made so that different refresh rates doesn't impact the code as much.
requestAnimationFrame(nextFrame)
function nextFrame() {
if (percent == skillPercent) {
return // return will mean this function is not called again, thus stopping the animation
} else {
percent = 0.5;
item.style.background = "conic-gradient( #ff5555 " percent "%, #000 0%)";
}
requestAnimationFrame(nextFrame) // Executes again in the next frame
}
// Request animation frame
// Set interval
/*
const myInterval = setInterval(() => {
if (percent == skillPercent) {
clearInterval(myInterval);
} else {
percent = 0.5;
item.style.background = "conic-gradient( #ff5555 " percent "%, #000 0%)";
}
}, 30);*/
// Set interval
}
}
CodePudding user response:
Thanks to Danny Yuan, I found that I only need to do two things:
- Declare percent in the function.
- Pass skillPercent in the function.
that's it.
var d = document.querySelectorAll(".divb");
var i = d.length;
while (i--) {
if (d[i].className.includes("1")) {
skillPercent = 40;
fill(d[i], skillPercent);
}
if (d[i].className.includes("2")) {
skillPercent = 70;
fill(d[i], skillPercent);
}
if (d[i].className.includes("3")) {
skillPercent = 90;
fill(d[i], skillPercent);
}
function fill(item, skillPercent) {
var percent = 1;
setInterval(() => {
if (percent == skillPercent) {
clearInterval();
}
else {
percent ;
item.style.background = "conic-gradient( #ff5555 " percent "%, #000 0%)";
}
}, 10);
}
}
.body {
display: inline-flex;
}
.div {
width: 130px;
height: 130px;
border-radius: 50%;
display: flex;
color: #fff;
justify-content: center;
align-items: center;
margin: 1px;
background: #555;
}
.divb {
width: 150px;
height: 150px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
margin: 1px;
background-color: #000;
}
<body >
<div >
<div >skill1</div>
</div>
<div >
<div >skill2</div>
</div>
<div >
<div >skill3</div>
</div>
</body>
</html>