Skip to main content

Progress Bar

Queue based progress bar using Element.animate()

This is the challenge #5 from Sunny Puri's The DOM Challenge Series.

tip

Element.animate()

The Element interface's animate() method is a shortcut method which creates a new Animation, applies it to the element, then plays the animation. It returns the created Animation object instance.

Syntax

animate(keyframes, options)

Parameters

keyframes

Either an array of keyframe objects, or a keyframe object whose properties are arrays of values to iterate over. See Keyframe Formats for more details.

options

Either an integer representing the animation's duration (in milliseconds), or an Object containing one or more timing properties described in the KeyframeEffect() options parameter and/or the following options:

id Optional

A property unique to animate(): a DOMString with which to reference the animation.

Return value

Returns an Animation.

More about the Element.animate() API here

Lets work on the solution

<body>
<!-- our progress bar -->
<div id="progress"></div>
<!-- button to start the loading -->
<button id="button">Load</button>
<!-- queue to keep track of number of times button is clicked-->
<span id="queue"></span>
</body>
//declaring the variables
const progress = document.querySelector("#progress");
const display = document.querySelector("#queue");
const button = document.querySelector("#button");

//setting number of variables
let animations = 0;


//onClick event
button.addEventListener("click", () => {
animations++; //updating the number of loads
updateAnimations(); //displaying the updated value
if (animations === 1) {
animateOnce(); //run the animation
}
});

function animateOnce() {
progress.animate( //using the animate() API
[{ width: "100%" }], //setting width from 0 to 100%, i.e. passing the keyframes as an array
{
duration: 2000, //running for a duration of 2 seconds
iterations: `1`, //running just once
}).finished.then(() => {
animations--; //once animation is complete, remove it from the queue
updateAnimations(); //display the updated value
if (animations) {
animateOnce(); //animate it till queue is empty, i.e. animations == 0
}
});
}

function updateAnimations() {
display.innerText = animations; //set the value of current animations in the queue
}

FINAL CODE

<body>
<div id="progress"></div>
<button id="button">Load</button>
<span id="queue"></span>
</body>

<script>
const progress = document.querySelector("#progress");
const display = document.querySelector("#queue");
const button = document.querySelector("#button");

let animations = 0;

button.addEventListener("click", () => {
animations++;
updateAnimations();
if (animations === 1) {
animateOnce();
}
});

function animateOnce() {
progress.animate(
[{ width: "100%" }],
{
duration: 2000,
iterations: `1`,
}).finished.then(() => {
animations--;
updateAnimations();
if (animations) {
animateOnce();
}
});
}

function updateAnimations() {
display.innerText = animations;
}
</script>