Building a Circular Progress Bar in JavaScript


A circular progress bar in JavaScript is a visual representation of progress or completion that takes the form of a circular shape. It is commonly used in web development to provide users with an intuitive and visually appealing way to track the progress of a task or process.

The circular progress bar typically consists of an outer circle representing the total progress or completion and an inner arc or circle that dynamically grows or fills up to indicate the current progress. The progress is usually represented as a percentage, ranging from 0% to 100%.

To create a circular progress bar in JavaScript, you can utilize HTML, CSS, and JavaScript. Here's a step-by-step overview of the process:

  1. HTML structure: Create a container element, often a <div>, to hold the circular progress bar.
  2. CSS styling: Apply appropriate CSS styles to the container and the inner elements to create the circular shape, set the size, colors, and animations as desired.
  3. SVG element: Use the Scalable Vector Graphics (SVG) format to draw the circular shape. SVG provides flexibility in creating shapes and animations. You can define an SVG element within the container and configure its attributes, such as radius, stroke width, and colors.
  4. JavaScript logic: Write JavaScript code to dynamically update the progress of the circular bar based on the task or process. This involves manipulating the SVG elements and adjusting their properties, such as the length of the inner arc or the rotation of the circular bar.
  5. Animation: Use JavaScript's animation capabilities, such as requestAnimationFrame or CSS transitions, to animate the progress updates smoothly. This creates a visually pleasing effect as the circular progress bar gradually fills up or advances.

Here is an example code snippet that demonstrates this approach:

Source Code

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="css/style.css" />
  </head>
  <body>
        <div class="container"></div>
    <script src="js/script.js"></script>
  </body>
</html>

js/script.js

const container = document.querySelector(".container");

const courses = [
  { course: "HTML", percent: 99, color: "#f9ca24" },
  { course: "CSS", percent: 65, color: "#78e08f" },
  { course: "JavaScript", percent: 35, color: "#c56cf0" },
  { course: "Bootstrap", percent: 85, color: "#badc58" },
];

courses.forEach((course) => {
  container.innerHTML += `
  <div class="progess-group">
  <div class="circular-progress" >
    <span class="course-value" style="color:${course.color}">0%</span>
  </div>
  <label class="text" style="color:${course.color}">${course.course}</label>
</div>
  `;
});

//style="  background: conic-gradient(${course.color} ${3.6 * course.percent}deg, #fff 0deg);"

const progressGroups = document.querySelectorAll(".progess-group");

progressGroups.forEach((progress, index) => {
  let progressStartValue = 0;
  let progressStartEnd = courses[index].percent;
  let speed = 50;
  let progessTimer = setInterval(() => {
    progressStartValue++;
    if (progressStartValue == progressStartEnd) {
      clearInterval(progessTimer);
    }
    progress.querySelector(".circular-progress").style.background = `
    conic-gradient(${courses[index].color} ${3.6 * progressStartValue}deg, #fff 0deg)`;

    progress.querySelector(".course-value").innerHTML = progressStartValue + "%";
  }, speed);
});
  1. The code starts by selecting an HTML element with the class "container" using document.querySelector(".container") and assigning it to the container variable. This element will serve as the parent container for the progress bars.
  2. An array called courses is defined, which contains objects representing different courses. Each object has properties like course (course name), percent (progress percentage), and color (color for the progress bar).
  3. The forEach method is used on the courses array to iterate over each course object. Inside the iteration, a template string is used to dynamically generate HTML markup for each progress bar. The generated HTML includes a circular progress bar element with a placeholder value of "0%" and a label for the course name. The color for the progress bar and label is set based on the color property of each course object.
  4. The generated HTML markup is appended to the container element using container.innerHTML +=. This adds the progress bars to the DOM.
  5. After creating the progress bars, the code selects all elements with the class "progress-group" using document.querySelectorAll(".progess-group") and assigns them to the progressGroups variable.
  6. The forEach method is used on the progressGroups array to iterate over each progress group. Inside the iteration, several variables are defined: progressStartValue (initial progress value, set to 0), progressStartEnd (the target progress value for the current course), speed (the speed of the animation in milliseconds), and progessTimer (a variable to store the interval timer for the animation).
  7. An interval timer is set using setInterval, which repeatedly executes a callback function at a given speed. In the callback function, progressStartValue is incremented by 1. If the progressStartValue reaches the progressStartEnd value (target progress), the interval is cleared using clearInterval(progessTimer) to stop the animation.
  8. Inside the interval callback function, the circular progress bar's background is updated using the style.background property. It uses a conic gradient to create the appearance of a filled progress bar based on the progressStartValue and the course's color. The 3.6 * progressStartValue calculates the appropriate degree for the gradient based on the percentage. The progress.querySelector(".circular-progress") selects the circular progress bar element for the current course being iterated.
  9. The progress value is also updated by setting the innerHTML of the .course-value element inside the progress group. This updates the displayed percentage value.
  10. Finally, the animation repeats for each progress group in the progressGroups array.

In summary, this code dynamically generates circular progress bars for different courses and animates them to show the progress percentage using a conic gradient and interval timers.

Finally, you can add some CSS styles to enhance the look and feel of the button and container. you can adjust the CSS styles as desired to match the design of your website.

css/style.css

@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;700;900&display=swap");

* {
  font-family: "Poppins", sans-serif;
  margin: 0;
  padding: 0;
}

body {
  height: 100vh;
  width: 100vw;
  display: grid;
  place-items: center;
  background-color: #222;
}
.container {
  display: flex;
  gap: 10px;
}
.progess-group {
  background-color: #535c68;
  width: 300px;
  padding: 50px 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  border-radius: 5px;
  box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;
}

.circular-progress {
  height: 200px;
  width: 200px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  transition: 0.5s;
}

.circular-progress::before {
  content: "";
  position: absolute;
  width: 180px;
  height: 180px;
  border-radius: 50%;
  background-color: #535c68;
}
.course-value {
  position: relative;
  color: #eb4d4b;
  font-size: 35px;
  font-weight: 500;
}
.text {
  margin-top: 18px;
  font-size: 25px;
  font-weight: 500;
  letter-spacing: 1px;
  color: white;
}

By combining HTML, CSS, and JavaScript, you can create an interactive and visually appealing circular progress bar that provides users with a clear indication of progress and completion in various applications, such as file uploads, form submissions, or lengthy operations.


Output

Circular Progress Bar

Live Preview


List of Programs


JS Practical Questions & Answers


JS Practical Project