FOPENP

JS: circular progress bar

0%

I created a circular progress bar with CSS and Javascript. It was not possible to avoid using Javascript because both transition and animation do not animate the conic-gradient.

    1 <!DOCTYPE html>
    2 <html>
    3     <head>
    4         <meta charset="utf-8">
    5         <title>Circular Progress Bar</title>
    6         <style>
    7             .centered {
    8                 display: flex;
    9                 justify-content: center;
   10                 align-items: center;
   11                 position: relative;
   12                 z-index: 1;
   13             }
   14             .progress-overlay {
   15                 position: fixed;
   16                 width: 100vw;
   17                 height: 100vh;
   18                 display: flex;
   19                 justify-content: center;
   20                 align-items: center;
   21             }
   22             .circle {
   23                 position: relative;
   24                 width: 10em;
   25                 height: 10em;
   26                 margin: 0.5em;
   27                 border-radius: 50%;
   28                 background-image: conic-gradient(darkgray 0%, lightgray 0);
   29             }
   30             .circle-int {
   31                 background-color: white;
   32                 display: flex;
   33                 justify-content: center;
   34                 align-items: center;
   35                 width: 7em;
   36                 height: 7em;
   37                 position: relative;
   38                 top: 50%;
   39                 left: 50%;
   40                 transform: translate(-50%, -50%);
   41                 border-radius: 50%;
   42             }
   43             .internal-text {
   44                 position: absolute;
   45                 font-family: sans-serif;
   46                 font-size: 2em;
   47             }
   48         </style>
   49     </head>
   50     <body>
   51         <div class="progress-overlay">
   52             <div class="circle">
   53                 <div class="circle-int">
   54                     <div class="internal-text">0%</div>
   55                 </div>
   56             </div>
   57         </div>
   58         <div class="centered">
   59             <input type="button" value="Click me!" onclick="setTo100();"></input>
   60         </div>
   61         <script>
   62             let circlevalnext = [];
   63             let circlevalprev = [];
   64 
   65             function _updateC(circle, index) {
   66                 if (circlevalprev[index] < circlevalnext[index]) {
   67                     let x = (circlevalnext[index] - circlevalprev[index]) / 20;
   68                     circlevalprev[index] += x;
   69                     if (circlevalprev[index] > (circlevalnext[index] - 1.0))
   70                         circlevalprev[index] = circlevalnext[index];
   71                     circle.style.backgroundImage = "conic-gradient(darkgray " + circlevalprev[index] + "%, lightgray 0)";
   72                     setTimeout(() => { _updateC(circle, index); }, 20);
   73                 }
   74             }
   75 
   76             function updateCircle(circle, index, newval) {
   77                 const text = circle.children[0].children[0];
   78                 text.textContent = newval + "%";
   79                 circlevalprev[index] = circlevalnext[index];
   80                 circlevalnext[index] = newval;
   81                 setTimeout(() => { _updateC(circle, index); }, 20);
   82             }
   83 
   84             function setTo100() {
   85                 const circles = document.getElementsByClassName("circle");
   86                 for (let i = 0; i < circles.length; i++) {
   87                     circlevalnext[i] = 0;
   88                     circlevalprev[i] = 0;
   89                     updateCircle(circles[i], i, 100);
   90                 }
   91             }
   92         </script>
   93     </body>
   94 </html>

As you can see in line n.28, a conic gradient is used to create the circular progress bar.
In javascript, an updateCircle() function takes as input a value (newval) to set the percentage on the progress bar.
The updateCircle() function is called by the setTo100() function which is triggered by the "Click me!" button.
The animation is performed by the _updateC() function, which must not be called directly; it will be called by updateCircle().

The final result is that thanks to the updateCircle(circle, index, 100) function, the progress bar will start from 0% and fill up to 100%.

2024
Jan, 18