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>
Related
I'm using the following code for a progress bar:
<div class="slide-progress-bar">
<div class="progress-bar" id="progress-bar"></div>
<!--progress-bar-->
</div>
<script>
var elem = document.getElementById("progress-bar");
var width = 1;
function progressBar() {
resetProgressBar();
id = setInterval(frame, 300);
function frame() {
if (width >= 100) {
clearInterval(id);
} else {
width++;
elem.style.width = width +"%";
}
}
}
function resetProgressBar() {
width = 1;
elem.style.width = width;
}
progressBar()
</script>
<style>
.slide-progress-bar {
width: 150px;
background-color:rgba(155, 155, 155, 0.36);
transition: width 10s linear;
display: inline-block;
vertical-align: middle;
margin: auto;
width: 100%;
}
.progress-bar {
height: 5px;
background-color: #ff4546;
position: relative;
transition: linear;
}
</style>
It works fine (when the page loads, progress bar starts and completes 300frames) but when I switch the tab or minimizes the window it stops and when I reopen the tab, it resumes. I don't want this top happen. I want the progress bar to continue loading even when not in focus. Is there way to do so ?, cause I saw such progress bars on may other sites.
Set Interval stops when page is minimize. You can use Date object to check how many time pass since progress bar starts loading.
<div class="slide-progress-bar">
<div class="progress-bar" id="progress-bar"></div>
<!--progress-bar-->
</div>
<script>
var animationTimeInMiliseconds = 30000; //30s
var interval = 300;
var elem = document.getElementById("progress-bar");
var beginningDate = new Date().getTime(); // Time in miliseconds
function progressBar() {
resetProgressBar();
id = setInterval(frame, interval);
function frame() {
var milisecondsFromBegin = new Date().getTime() - beginningDate;
var width = Math.floor(milisecondsFromBegin / animationTimeInMiliseconds * 100);
elem.style.width = width + "%";
if (width >= 100) {
clearInterval(id);
}
}
}
function resetProgressBar() {
elem.style.width = 0;
}
progressBar()
</script>
<style>
.slide-progress-bar {
width: 150px;
background-color:rgba(155, 155, 155, 0.36);
transition: width 10s linear;
display: inline-block;
vertical-align: middle;
margin: auto;
width: 100%;
}
.progress-bar {
height: 5px;
background-color: #ff4546;
position: relative;
transition: linear;
}
</style>
You can use css3 transitions instead of js animations to solve the problems you are facing.
You can read more about it here
Adding an example for your reference.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style>
.slide-progress-bar {
width: 150px;
background-color:rgba(155, 155, 155, 0.36);
transition: width 10s linear;
display: inline-block;
vertical-align: middle;
margin: auto;
width: 100%;
}
.slide-progress-bar .progress-bar {
height: 5px;
background-color: #ff4546;
position: relative;
transition: linear;
animation: progres 4s infinite linear;
}
#keyframes progres{
0%{
width: 0%;
}
25%{
width: 50%;
}
50%{
width: 75%;
}
75%{
width: 85%;
}
100%{
width: 100%;
}
};
</style>
</head>
<body>
<div class="slide-progress-bar">
<div class="progress-bar"></div>
</div>
</body>
</html>
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>
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-->
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>
At the moment it is starting from the left side and adding div's to the right but how can I make it add div's from the left. So that the first card would appear in the middle and add them behind it (to the left side).
I have tried setting float: right, but it does not give the wanted results.
var parentEl = document.getElementById("cards");
var elem = document.getElementById("myBar");
var width;
var id;
var parentEl = document.getElementById("cards");
var elem = document.getElementById("myBar");
var lastCard;
var width;
var id;
function sortCards() {
var cards = document.getElementsByClassName("card"),
cw = parentEl.clientWidth,
sw = parentEl.scrollWidth,
diff = sw - cw,
offset = diff / (cards.length - 1 );
for (var i = 0; i < cards.length; i++) {
i != 0 && (cards[i].style.transform = "translateX(-" + offset * i + "px)");
}
}
//Move card
document.getElementById("moveCard").addEventListener("click", function () {
myMove();
});
//Start the game
document.getElementById("play").addEventListener("click", function() {
move();
});
//Stop the game
document.getElementById("stop").addEventListener("click", function() {
stop();
});
function move() {
width = 1;
id = setInterval(frame, 5);
function frame() {
if (width >= 100) {
elem.style.width = 1 + '%';
clearInterval(id);
addCard();
move();
} else {
width++;
elem.style.width = width + '%';
}
}
}
function myMove() {
var elem = lastCard;
lastCard = lastCard.previousSibling;
var pos = 0;
var id = setInterval(movie, 5);
function movie() {
if (pos == 350) {
clearInterval(id);
elem.remove();
} else {
pos = pos + 5;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
function addCard(){
var div = document.createElement("div");
div.style.position = "relative";
div.style.color = "green";
div.style.left = "auto";
div.classList.add("card");
parentEl.appendChild(div);
lastCard = div;
sortCards();
}
function stop() {
elem.style.width = 1 + '%';
clearInterval(id);
}
sortCards();
.cards {
display: flex;
max-width: 300px;
}
.card {
height: 90px;
border: 1px solid black;
border-radius: 3px;
background-color: rgba(255, 0, 0, 0.4);
flex: 0 0 50px;
background: red;
transition: transform .25s;
}
.cardGreen {
height: 90px;
border: 1px solid black;
border-radius: 3px;
background-color: rgba(255, 0, 0, 0.4);
flex: 0 0 50px;
background: green;
transition: transform .25s;
}
#myProgress {
position: relative;
width: 100%;
height: 10px;
background-color: grey;
}
#myBar {
position: absolute;
width: 1%;
height: 100%;
background-color: green;
}
/* Create three unequal columns that floats next to each other */
.column {
float: left;
/*padding: 10px;*/
height: 300px; /* Should be removed. Only for demonstration */
}
.left, .right {
width: 20%;
}
.middle {
width: 60%;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<header>
<h1>Simple game</h1>
</header>
<div class="row">
<div class="column left" style="background-color:#aaa;">
<div><button class="btn btn-default btn-block" id="play">Start Game</button></div>
<div><button class="btn btn-default btn-block" id="stop">Pause</button></div>
<div><button class="btn btn-default btn-block" id="moveCard">Move Card</button></div>
</div>
<div class="column middle" style="background-color:#bbb;">
<div class='cards middle' id="cards">
<!--<div class='cardGreen'></div>-->
</div>
<div id="myProgress">
<div id="myBar"></div>
</div>
</div>
<div class="column right" style="background-color:#ccc;">
<h2>Tutorial</h2>
<p>Will be here soon :)</p>
</div>
</div>
<script src="gamelogic.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>
Any hints or suggestions will come really in handy.
to add en element in the begining of the parent and not at the end, use prependinstead of append
parentEl.prepend(div);
The ParentNode.prepend method inserts a set of Node objects or DOMString objects >before the first child of the ParentNode.
this won't make the first card appear in the middle though, you're gonna have to rewok your positioning of the cards.
var parentEl = document.getElementById("cards");
var elem = document.getElementById("myBar");
var width;
var id;
var parentEl = document.getElementById("cards");
var elem = document.getElementById("myBar");
var lastCard;
var width;
var id;
function sortCards() {
var cards = document.getElementsByClassName("card"),
cw = parentEl.clientWidth,
sw = parentEl.scrollWidth,
diff = sw - cw,
offset = diff / (cards.length - 1);
for (var i = 0; i < cards.length; i++) {
i != 0 && (cards[i].style.transform = "translateX(-" + offset * i + "px)");
}
}
//Move card
document.getElementById("moveCard").addEventListener("click", function() {
myMove();
});
//Start the game
document.getElementById("play").addEventListener("click", function() {
move();
});
//Stop the game
document.getElementById("stop").addEventListener("click", function() {
stop();
});
function move() {
width = 1;
id = setInterval(frame, 5);
function frame() {
if (width >= 100) {
elem.style.width = 1 + '%';
clearInterval(id);
addCard();
move();
} else {
width++;
elem.style.width = width + '%';
}
}
}
function myMove() {
var elem = lastCard;
lastCard = lastCard.previousSibling;
var pos = 0;
var id = setInterval(movie, 5);
function movie() {
if (pos == 350) {
clearInterval(id);
elem.remove();
} else {
pos = pos + 5;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
var i = 1;
function addCard() {
var div = document.createElement("div");
div.style.left = "auto";
div.innerHTML = i++;
div.style.position = "relative";
div.style.color = "green";
div.classList.add("card");
parentEl.prepend(div);
lastCard = div;
sortCards();
}
function stop() {
elem.style.width = 1 + '%';
clearInterval(id);
}
sortCards();
.cards {
display: flex;
max-width: 300px;
}
.card {
height: 90px;
border: 1px solid black;
border-radius: 3px;
background-color: rgba(255, 0, 0, 0.4);
flex: 0 0 50px;
background: red;
transition: transform .25s;
}
.cardGreen {
height: 90px;
border: 1px solid black;
border-radius: 3px;
background-color: rgba(255, 0, 0, 0.4);
flex: 0 0 50px;
background: green;
transition: transform .25s;
}
#myProgress {
position: relative;
width: 100%;
height: 10px;
background-color: grey;
}
#myBar {
position: absolute;
width: 1%;
height: 100%;
background-color: green;
}
/* Create three unequal columns that floats next to each other */
.column {
float: left;
/*padding: 10px;*/
height: 300px;
/* Should be removed. Only for demonstration */
}
.left,
.right {
width: 20%;
}
.middle {
width: 60%;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.bundle.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<header>
<h1>Simple game</h1>
</header>
<div class="row">
<div class="column left" style="background-color:#aaa;">
<div><button class="btn btn-default btn-block" id="play">Start Game</button></div>
<div><button class="btn btn-default btn-block" id="stop">Pause</button></div>
<div><button class="btn btn-default btn-block" id="moveCard">Move Card</button></div>
</div>
<div class="column middle" style="background-color:#bbb;">
<div class='cards middle' id="cards">
<!--<div class='cardGreen'></div>-->
</div>
<div id="myProgress">
<div id="myBar"></div>
</div>
</div>
<div class="column right" style="background-color:#ccc;">
<h2>Tutorial</h2>
<p>Will be here soon :)</p>
</div>
</div>
EDIT :
to make the first car appear in the middle , make the parent's width 0% and make it grow every time you add a card until you reach 100%, and add margin:auto
var parentEl = document.getElementById("cards");
var elem = document.getElementById("myBar");
var width;
var id;
var parentEl = document.getElementById("cards");
var elem = document.getElementById("myBar");
var lastCard;
var width;
var id;
function sortCards() {
var cards = document.getElementsByClassName("card"),
cw = parentEl.clientWidth,
sw = parentEl.scrollWidth,
diff = sw - cw,
offset = diff / (cards.length - 1);
for (var i = 0; i < cards.length; i++) {
i != 0 && (cards[i].style.transform = "translateX(-" + offset * i + "px)");
}
}
//Move card
document.getElementById("moveCard").addEventListener("click", function() {
myMove();
});
//Start the game
document.getElementById("play").addEventListener("click", function() {
move();
});
//Stop the game
document.getElementById("stop").addEventListener("click", function() {
stop();
});
function move() {
width = 1;
id = setInterval(frame, 5);
function frame() {
if (width >= 100) {
elem.style.width = 1 + '%';
clearInterval(id);
addCard();
move();
} else {
width++;
elem.style.width = width + '%';
}
}
}
function myMove() {
var elem = lastCard;
lastCard = lastCard.previousSibling;
var pos = 0;
var id = setInterval(movie, 5);
function movie() {
if (pos == 350) {
clearInterval(id);
elem.remove();
} else {
pos = pos + 5;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
var i = 1;
function addCard() {
var div = document.createElement("div");
div.style.left = "auto";
div.innerHTML = i++;
div.style.position = "relative";
div.style.color = "green";
div.classList.add("card");
if (parseInt(parentEl.style.width) < 100)
parentEl.style.width = (parseInt(parentEl.style.width) + 10) + '%';
parentEl.prepend(div);
lastCard = div;
sortCards();
}
function stop() {
elem.style.width = 1 + '%';
clearInterval(id);
}
sortCards();
.cards {
display: flex;
max-width: 300px;
}
.card {
height: 90px;
border: 1px solid black;
border-radius: 3px;
background-color: rgba(255, 0, 0, 0.4);
flex: 0 0 50px;
background: red;
transition: transform .25s;
}
.cardGreen {
height: 90px;
border: 1px solid black;
border-radius: 3px;
background-color: rgba(255, 0, 0, 0.4);
flex: 0 0 50px;
background: green;
transition: transform .25s;
}
#myProgress {
position: relative;
width: 100%;
height: 10px;
background-color: grey;
}
#myBar {
position: absolute;
width: 1%;
height: 100%;
background-color: green;
}
/* Create three unequal columns that floats next to each other */
.column {
float: left;
/*padding: 10px;*/
height: 300px;
/* Should be removed. Only for demonstration */
}
.left,
.right {
width: 20%;
}
#cards {
width: 15%;
margin: auto;
}
.middle {
width: 60%;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.bundle.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<header>
<h1>Simple game</h1>
</header>
<div class="row">
<div class="column left" style="background-color:#aaa;">
<div><button class="btn btn-default btn-block" id="play">Start Game</button></div>
<div><button class="btn btn-default btn-block" id="stop">Pause</button></div>
<div><button class="btn btn-default btn-block" id="moveCard">Move Card</button></div>
</div>
<div class="column middle" style="background-color:#bbb;">
<div class='cards middle' id="cards" style="width:0%">
<!--<div class='cardGreen'></div>-->
</div>
<div id="myProgress">
<div id="myBar"></div>
</div>
</div>
<div class="column right" style="background-color:#ccc;">
<h2>Tutorial</h2>
<p>Will be here soon :)</p>
</div>
</div>