Smooth javascript progress bar - javascript

I'm trying to make a js progress bar which finishes after 5 seconds and then runs some code.
What I have from w3:
var i = 0;
function move() {
if (i == 0) {
i = 1;
var elem = document.getElementById("myBar");
var width = 1;
var id = setInterval(frame, 10);
function frame() {
if (width >= 100) {
clearInterval(id);
i = 0;
} else {
width++;
elem.style.width = width + "%";
}
}
}
}
move();
#myProgress {
width: 100%;
background-color: grey;
}
#myBar {
width: 1%;
height: 30px;
background-color: green;
}
<div id="myProgress">
<div id="myBar"></div>
</div>
How can I f.e. adjust its time to 5 seconds, with the animation still being smooth?

The animation need not be done in javascript. Use CSS instead for smoother performance and cleaner code.
It's generally a better idea to use CSS animations over JS, especially when they are simple. You should read more here. If you still want to do it in javascript for some reason, you should use this dedicated call for animating stuff requestAnimationFrame.
function move() {
var elem = document.getElementById("myBar");
myBar.style.width = "0%";
setTimeout(() => {
myBar.style.width = "100%";
});
setTimeout(() => {
alert("done");
/* do stuff */
}, 5000);
}
move();
#myProgress {
width: 100%;
background-color: grey;
}
#myBar {
width: 0%;
height: 30px;
background-color: green;
transition: width 5s linear; /* note this line */
}
<div id="myProgress">
<div id="myBar"></div>
</div>

According to docs setInterval delay param is in miliseconds
delayOptional The time, in milliseconds (thousandths of a second), the
timer should delay in between executions of the specified function or
code. See Delay restrictions below for details on the permitted range
of delay values.
var i = 0;
const element = document.getElementById("myBar");
let width = 1;
let chunk = 100 / 5;
function move() {
if (i == 0) {
let handle = setInterval(frame, 1000);
function frame() {
if (width >= 100) {
clearInterval(handle);
} else {
width = width + chunk;
element.style.width = `${width}%`;
}
}
}
}
move();
#myProgress {
width: 100%;
background-color: grey;
}
#myBar {
width: 0%;
transition: all .3s ease-in;
height: 30px;
background-color: green;
}
<div id="myProgress">
<div id="myBar"></div>
</div>

var i = 0;
function move() {
if (i == 0) {
i = 1;
var elem = document.getElementById("myBar");
var width = 1;
var id = setInterval(frame, 5000/100);
function frame() {
if (width >= 100) {
clearInterval(id);
i = 0;
} else {
width++;
elem.style.width = width + "%";
}
}
}
}
move();
#myProgress {
width: 100%;
background-color: grey;
}
#myBar {
width: 1%;
height: 30px;
background-color: green;
}
<div id="myProgress">
<div id="myBar"></div>
</div>
basicly time you want divided by count of how many loops it take to fill whole bar

For higher quality animations is better to use requestAnimationFrame.
let start;
let element = document.getElementById("myBar");
let count = 0;
function step(timestamp) {
if (start === undefined)
start = timestamp;
const elapsed = timestamp - start;
element.style.width = (100 / 2000) * elapsed + "%";
if (elapsed < 2000) { // Stop the animation after 2 seconds
window.requestAnimationFrame(step);
}else {
}
}
window.requestAnimationFrame(step);
#myProgress {
width: 100%;
background-color: grey;
}
#myBar {
width: 1%;
height: 30px;
background-color: green;
}
<div id="myProgress">
<div id="myBar"></div>
</div>

You need to change var id = setInterval(frame, 10); 1000 = 1 second
var i = 0;
function move() {
if (i == 0) {
i = 1;
var elem = document.getElementById("myBar");
var width = 1;
var id = setInterval(frame, (5*1000)/100);
function frame() {
if (width >= 100) {
clearInterval(id);
i = 0;
} else {
width++;
elem.style.width = width + "%";
}
}
}
}
move();
#myProgress {
width: 100%;
background-color: grey;
}
#myBar {
width: 1%;
height: 30px;
background-color: green;
}
<div id="myProgress">
<div id="myBar"></div>
</div>

Related

JavaScript Progress Bar in Loop [duplicate]

This question already has answers here:
Loop my Progress Bar?
(4 answers)
Closed last year.
I would like to show a progress bar while running the following code. I'm calling it a script.
I need a progress bar in a for loop in javascript.
<div id="myProgress">
<div id="myBar"></div>
</div>
<script>
var i = 0;
var elem = document.getElementById("myBar");
var width = 1;
var id = setInterval(frame, 500);
function frame() {
if (width >= 100) {
clearInterval(id);
i = 0;
} else {
width++;
elem.style.width = width + "%";
}
}
</script>
If you want progress bar infinite execute, see this below code
var i = 0
var elem = document.getElementById("myBar")
let width = 1
var id = setInterval(frame, 50)
function frame() {
if (width >= 100) {
clearInterval(id)
i = 0
width = 0
setInterval(frame, 50)
} else {
width++
elem.style.width = width + "%"
}
}
body {
font-family: "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
#myProgress {
border: 1px solid black;
width: 20rem;
}
#myBar {
border: 1px solid black;
background-color: black;
}
<div id="myProgress">
<div id="myBar"></div>
</div>

How to move a square back and forth

I am trying to make a square move back and forth by pressing a button one time with javascript. I can make it move to the right edge but don't know how to make it move back again.
Help appreciated.
function myMove() {
let id = null;
const elem = document.getElementById("animate");
let pos = 0;
clearInterval(id);
id = setInterval(frame, 5);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem.style.left = pos + "px";
}
}
}
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<body>
<p><button onclick="myMove()">Click Me</button></p>
<div id ="container">
<div id ="animate"></div>
</div>
I know you are asking for a javascript-based solution, but it's worth noting that this kind of presentation can be achieved with CSS alone.
So, for the sake of completeness, I am posting a CSS-only solution below.
N.B. There is a key difference between what CSS is capable of and what JS is capable of.
Note that in the CSS-only example below, each time you click the button, you will then have to click outside the button before the button will work again.
CSS-only Working Example:
.move-square-button {
display: block;
margin-bottom: 12px;
cursor: pointer;
}
.container {
width: 400px;
height: 144px;
position: relative;
background-color: yellow;
}
.square {
position: absolute;
top: 0;
left: 0;
width: 50px;
height: 50px;
background-color: red;
transform: translateX(0);
}
.move-square-button:focus {
cursor: not-allowed;
}
.move-square-button:focus + .container .square {
animation: moveSquareRightThenLeft 2s linear;
}
#keyframes moveSquareRightThenLeft {
50% { transform: translateX(calc(400px - 100%)); }
}
<button class="move-square-button" type="button">Click Me</button>
<div class="container">
<div class="square"></div>
</div>
Not the prettiest solution but shoud do the trick. Essentially if the rectangle reaches the right edge the "inverseDirection" variable inverts from false to true and therefore the pos variable decrements instead of increment. The opposite happens in the left edge.
function myMove() {
let id = null;
const elem = document.getElementById("animate");
let pos = 0;
let inverseDirection = false;
clearInterval(id);
id = setInterval(frame, 5);
function frame() {
if (pos === 350 && !inverseDirection) {
inverseDirection = true;
}else if(pos === 0 && inverseDirection){
inverseDirection = false;
}
pos = (inverseDirection) ? pos-1 : pos+1;
elem.style.left = pos + "px";
}
}
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<p><button onclick="myMove()">Click Me</button></p>
<div id ="container">
<div id ="animate"></div>
</div>
whenever you are calling the myMove function it has pos set to 0. you should calculate position on the fly, and based on that logic you will be moving it right or left. assume the length is 350, you can do something like this:
function myMove() {
let id = null;
const elem = document.getElementById("animate");
let pos = elem.offsetLeft;
let dir = "";
if(pos === 0) {
dir = "right";
} else {
dir = "left";
}
clearInterval(id);
id = setInterval(frame, 5);
function frame() {
if (pos == 350 && dir == "right") {
clearInterval(id);
} if (pos == 0 && dir == "left") {
clearInterval(id);
} else if(dir === "right") {
pos++;
elem.style.left = pos + "px";
} else if(dir === "left") {
pos--;
elem.style.left = pos + "px";
}
}
}
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<body>
<p><button onclick="myMove()">Click Me</button></p>
<div id ="container">
<div id ="animate"></div>
</div>
Not sure if this is exactly what you wanted but below code will animate the red block to move back and forth once every time you click the button.
Basically you just maintain a variable that stores the direction of movement. So here you set forward to true if its moving forwards and false if backwards. And based on the direction i.e value of forward, you either increase the value of pos or decrease it.
Now if the block is moving forward and the position is 350, set forward to false.
And finally when the direction is not forward and the position is 0, you clear the interval to end the animation, as the block reached back to initial position.
function myMove() {
let id = null;
const elem = document.getElementById("animate");
let pos = 0;
id = setInterval(frame, 5);
let forward = true;
function frame() {
if(!pos && !forward) {
clearInterval(id);
forward = true;
return;
}
if(pos == 350 && forward) {
forward = false;
}
forward ? pos++ : pos--;
elem.style.left = pos + "px";
}
}
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<body>
<p><button onclick="myMove()">Click Me</button></p>
<div id ="container">
<div id ="animate"></div>
</div>

Making a progressbar to load from 0 to 100% in 10 seconds with JavaScript

I am trying to make a simple progressbar to load for 10 seconds always when the JavaScript function is called. I don't want to use jQuery or any library. I want it to be on clean JavaScript. The only think I don't understand is how to make the progressbar load from 0 to 100% in 10 seconds. I am providing code with what I have done until now. Any suggestions?
var elem = document.getElementById("slide-progress-bar");
var width = 1;
function progressBar() {
resetProgressBar();
id = setInterval(frame, 100);
function frame() {
if (width >= 100) {
clearInterval(id);
} else {
width++;
elem.style.width = width + '%';
}
}
}
function resetProgressBar() {
width = 1;
elem.style.width = width + '%';
}
.slide-progress-bar {
width: 1118px;
background-color: rgba(155, 155, 255, 0.36);
transition: width 10s linear;
display: inline-block;
vertical-align: middle;
}
.progress-bar {
height: 5px;
background-color: #aff;
width: 1%;
position: relative;
transition: linear;
}
<div class="slide-progress-bar">
<div class="progress-bar" id="progress-bar"></div>
<!--progress-bar-->
</div>
<!--slide-progress-bar-->
I think you just have to change the element that you are increasing in width. Not sure if this is the behaviour you expected:
var elem = document.getElementById("progress-bar");
var width = 1;
var interval;
function progressBar() {
resetProgressBar();
interval = setInterval(frame, 100);
function frame() {
if (width >= 100) {
clearInterval(interval);
} else {
width++;
elem.style.width = width + '%';
}
}
}
function resetProgressBar() {
width = 1;
clearInterval(interval)
elem.style.width = width + '%';
}
.slide-progress-bar {
width: 1118px;
background-color: rgba(155, 155, 255, 0.36);
transition: width 10s linear;
display: inline-block;
vertical-align: middle;
}
.progress-bar {
height: 5px;
background-color: #aff;
width: 1%;
position: relative;
transition: linear;
}
<div class="slide-progress-bar">
<div class="progress-bar" id="progress-bar"></div>
<!--progress-bar-->
</div>
<button onclick="progressBar()">Start</button>
<!--slide-progress-bar-->
as far I understood I think you are looking for this. the progress-bar will be completed 100% after 10s
var elem = document.getElementById("progress-bar");
var width = 1;
function progressBar() {
resetProgressBar();
id = setInterval(frame, 1000);
function frame() {
if (width >= 100) {
clearInterval(id);
} else {
width+=10;
elem.style.width = width + '%';
}
}
}
function resetProgressBar() {
width = 1;
elem.style.width = width + '%';
}
progressBar();
.slide-progress-bar {
width: 1118px;
background-color: rgba(255, 0, 255, 0.36);
transition: width 10s linear;
display: inline-block;
vertical-align: middle;
}
.progress-bar {
height: 5px;
background-color: #fff2ff;
width: 1%;
position: relative;
transition: linear;
}
<div class="slide-progress-bar">
<div class="progress-bar" id="progress-bar"></div>
<!--progress-bar-->
</div>
let me know if it`s not ok
HI please check below solution
var elem = document.getElementById("progress-bar");
var width = 1;
var id = {};
function progressBar() {
id = setInterval(frame, 100);
function frame() {
if (width >= 100) {
clearInterval(id);
} else {
width++;
elem.style.width = width + '%';
}
}
}
progressBar()
.slide-progress-bar {
width: 1118px;
height: 200px;
background-color: rgba(255, 255, 255, 0.9);
transition: width 10s linear;
display: inline-block;
vertical-align: middle;
}
.progress-bar {
height: 20px;
width: 0;
background-color: red;
position: relative;
transition: linear;
}
<div class="slide-progress-bar">
<div class="progress-bar" id="progress-bar"></div>
<!--progress-bar-->
</div>
<!--slide-progress-bar-->
This works for me
I changed the elem to the inner div and removed the width from the CSS
I also changed the speed
Then I actually called the function
var elem = document.getElementById("progress-bar");
var width = 1;
function progressBar() {
resetProgressBar();
id = setInterval(frame, 10);
function frame() {
if (width >= 100) {
clearInterval(id);
} else {
width++;
elem.style.width = width +"%";
}
}
}
function resetProgressBar() {
width = 1;
elem.style.width = width;
}
progressBar()
.slide-progress-bar {
width: 1118px;
background-color: rgba(155, 155, 155, 0.36);
transition: width 10s linear;
display: inline-block;
vertical-align: middle;
}
.progress-bar {
height: 5px;
background-color: #aff;
position: relative;
transition: linear;
}
<div class="slide-progress-bar">
<div class="progress-bar" id="progress-bar"></div>
<!--progress-bar-->
</div>
<!--slide-progress-bar-->

How to increase or decrease a progress bar width within given time with pure JavaScript?

I'm making a typing game, there is a 1-second interval function in my
game already but I need something animated in UI. It will visually
show the user how the time is running out.
In this code, I wanted to increase the progress bar from 0% to 100% in 7 seconds. Though I want decrease actually
How can I do this with pure javascript?
Timing is Important here, The whole decrease/increase process should be done within my given time
function move() {
var elem = document.getElementById("myBar");
var width = 0;
var id = setInterval(frame, 1);
// i want it to be done in 7 seconds
var time = 7000;
function frame() {
if (width >= time) {
clearInterval(id);
} else {
width++;
elem.style.width = (100*width)/time + '%';
elem.innerHTML = Math.round((100*width)/time) + '%';
}
}
}
#myProgress {
width: 100%;
background-color: #ddd;
}
#myBar {
width: 0%;
height: 30px;
background-color: #4CAF50;
text-align: center;
line-height: 30px;
color: white;
}
<!DOCTYPE html>
<html>
<body>
<div id="myProgress">
<div id="myBar">0%</div>
</div>
<br>
<button onclick="move()">Start</button>
</body>
</html>
I would recommend using requestAnimationFrame first. Next, use a timer instead of counting how many times it is called. I made a few minor adjustments (you can call it with a different number to have a different delay).
RAF docs: https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
function move(delay) {
var elem = document.getElementById("myBar");
var end = Date.now() + delay;
var frame = () => {
var timeleft = Math.max(0, end - Date.now());
elem.style.width = (100*timeleft)/delay + '%';
elem.innerHTML = (timeleft/1000).toFixed(1) + 's';
if (timeleft === 0) return;
requestAnimationFrame(frame);
};
requestAnimationFrame(frame);
}
#myProgress {
width: 100%;
background-color: #ddd;
}
#myBar {
width: 100%;
height: 30px;
background-color: #4CAF50;
text-align: center;
line-height: 30px;
color: white;
}
<!DOCTYPE html>
<html>
<body>
<div id="myProgress">
<div id="myBar">7.0s</div>
</div>
<br>
<button onclick="move(7000)">Start</button>
</body>
</html>
Like this?
function move() {
var elem = document.getElementById("myBar");
var width = 0;
var id = setInterval(frame, 1);
// i want it to be done in 7 seconds
var time = 7000;
function frame() {
if (width >= time) {
clearInterval(id);
} else {
width++;
elem.style.width = 100-(100*width)/time + '%';
elem.innerHTML = 100-Math.round((100*width)/time) + '%';
}
}
}
#myProgress {
width: 100%;
background-color: #ddd;
}
#myBar {
width: 100%;
height: 30px;
background-color: #4CAF50;
text-align: center;
line-height: 30px;
color: white;
}
<!DOCTYPE html>
<html>
<body>
<div id="myProgress">
<div id="myBar">100%</div>
</div>
<br>
<button onclick="move()">Start</button>
</body>
</html>

How to run smoothly the progress bar line in html

function move() {
var elem = document.getElementById("myBar");
var width = 1;
var counter = 1;
var id = setInterval(frame, 1000);
function frame() {
if (width >= 60) {
clearInterval(id);
} else {
width += 1;
elem.innerHTML = counter++;
elem.style.width = width + 'px';
}
}
}
#myProgress {
width: 120px;
background-color: #ddd;
}
#myBar {
width: 0px;
height: 10px;
background-color: #4CAF50;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>JavaScript Progress Bar</h1>
<div id="myProgress">
<div id="myBar">0</div>
</div>
<br>
<button onclick="move()">Click Me</button>
In the above snippet there is progressive bar which will fill automatically when the button is clicked and it will fill the bar by adding the style.width by 1. I want that progressive bar to fill smoothly but the milliseconds shall remain unchanged i.e 1000 .
How about tweaking the JavaScript code to achieve the desired result:
function move() {
var elem = document.getElementById("myBar");
var width = 0.5;
// change the milliseconds to 10 or 5 to fill it relatively faster
var id = setInterval(frame, 20);
function frame() {
if (width >= 120) {
clearInterval(id);
} else {
width += 0.5;
elem.style.width = width + 'px';
}
}
}
#myProgress {
width: 120px;
background-color: #ddd;
}
#myBar {
width: 2px;
height: 10px;
background-color: #4CAF50;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>JavaScript Progress Bar</h1>
<div id="myProgress">
<div id="myBar"></div>
</div>
<br>
<button onclick="move()">Click Me</button>
You can use trasition and decrease the interval time
function move() {
var elem = document.getElementById("myBar");
var width = 2;
var id = setInterval(frame, 1);
function frame() {
if (width >= 60) {
clearInterval(id);
} else {
width += 2;
elem.style.width = width + 'px';
}
}
}
#myProgress {
width: 120px;
background-color: #ddd;
}
#myBar {
width: 2px;
height: 10px;
background-color: #4CAF50;
transition: width 2s;
}
<h1>JavaScript Progress Bar</h1>
<div id="myProgress">
<div id="myBar"></div>
</div>
<br>
<button onclick="move()">Click Me</button>
Add transition:width 600ms linear; to
#myBar {
width: 2px;
height: 10px;
background-color: #4CAF50;
transition:width 600ms linear;
}
This will smoothly animate the width of the bar.
Note:Keep the transition timing equal to setInterval timeout to avoid jerky animation
function move() {
var elem = document.getElementById("myBar");
var width = 1;
var counter = 1;
var id = setInterval(frame, 1000);
function frame() {
if (width >= 60) {
clearInterval(id);
} else {
width += 1;
elem.innerHTML = counter++;
elem.style.width = width + 'px';
}
}
}
#myProgress {
width: 120px;
background-color: #ddd;
}
#myBar {
width: 2px;
height: 10px;
background-color: #4CAF50;
transition:width 1000ms linear;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>JavaScript Progress Bar</h1>
<div id="myProgress">
<div id="myBar"></div>
</div>
<br>
<button onclick="move()">Click Me</button>
The transition in CSS makes smooth interpolation between 2 values.
That means when you increment the width by 1px, the browser will increase the width by animating it, This takes place only after the javascript code to increase width is executed.
The smallest unit that you can render is a pixel.What you can do is check for a certain inverval to increase the width. In the sample below I increase the width by 10px so that you can see the transition properly
function move() {
var elem = document.getElementById("myBar");
var width = 0;
var counter = 0;
var id = setInterval(frame, 600);
function frame() {
if (width >= 60) {
clearInterval(id);
} else {
counter++
console.log(counter);
if(counter % 5 == 0)
{
width += 10;
elem.style.width = width + 'px';
}
}
}
}
#myProgress {
width: 120px;
background-color: #ddd;
}
#myBar {
width: 2px;
height: 10px;
background-color: #4CAF50;
-webkit-transition: width 0.5s;
-moz-transition: width 0.5s;
-ms-transition: width 0.5s;
-o-transition: width 0.5s;
transition: width 0.5s;
}
<div id="myProgress">
<div id="myBar"></div>
</div>
<br>
<button onclick="move()">Click Me</button>

Categories