Completion status of circle loader: 100%

I am currently facing some challenges getting the circle loader to work correctly. Although I can handle basic animations, the code I found on CodePen is a bit more advanced than what I am used to. I am using it as a learning experience to understand how it works.

My goal is to control the extent to which the loader goes around the circumference of the circle. For example, having it stop at 68% or 98%. However, I have been unsuccessful so far in identifying the property or value that determines this.

I have tried adjusting the keyframes in the right loader class and the transform-origin property, but with no success. The code provided below:

#circle-loader-wrap {
  overflow: hidden;
  position: relative;
  margin-top: -10px;
  width: 200px;
  height: 200px;
  box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1) inset;
  background-color: blue;
  border-radius: 200px;
  -ms-transform: rotate(180deg);
  -webkit-transform: rotate(180deg);
  -moz-transform: rotate(180deg);
  transform: rotate(180deg);
}

#circle-loader-wrap:after {
  content: '';
  position: absolute;
  left: 15px;
  top: 15px;
  width: 170px;
  height: 170px;
  border-radius: 50%;
  background-color: green;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}

#circle-loader-wrap div {
  overflow: hidden;
  position: absolute;
  width: 50%;
  height: 100%;
}

#circle-loader-wrap .loader {
  position: absolute;
  left: 100%;
  top: 0;
  width: 100%;
  height: 100%;
  border-radius: 1000px;
  background-color: pink;
}

#circle-loader-wrap .left-wrap {
  left: 0;
}

#circle-loader-wrap .left-wrap .loader {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  transform-origin: 0 50% 0;
  -webkit-transform-origin: 0 50% 0;
  animation: loading-left 20s infinite linear;
  -webkit-animation: loading-left 20s infinite linear;
}

#circle-loader-wrap .right-wrap {
  left: 50%;
}

#circle-loader-wrap .right-wrap .loader {
  left: -100%;
  border-bottom-right-radius: 0;
  border-top-right-radius: 0;
  transform-origin: 100% 50% 0;
  -webkit-transform-origin: 100% 50% 0;
  animation: loading-right 20s infinite linear;
  -webkit-animation: loading-right 20s infinite linear;
}

@keyframes loading-left {
  0% {
    transform: rotate(0deg);
  }
  25% {
    transform: rotate(180deg);
  }
  50% {
    transform: rotate(180deg);
  }
  75% {
    transform: rotate(180deg);
  }
  100% {
    transform: rotate(180deg);
  }
}

@-webkit-keyframes loading-left {
  0% {
    -webkit-transform: rotate(0deg);
  }
  25% {
    -webkit-transform: rotate(180deg);
  }
  50% {
    -webkit-transform: rotate(180deg);
  }
  75% {
    -webkit-transform: rotate(180deg);
  }
  100% {
    -webkit-transform: rotate(180deg);
  }
}

@keyframes loading-right {
  0% {
    transform: rotate(0deg);
  }
  25% {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(180deg);
  }
  75% {
    transform: rotate(180deg);
  }
  100% {
    transform: rotate(180deg);
  }
}

@-webkit-keyframes loading-right {
  0% {
    -webkit-transform: rotate(0deg);
  }
  25% {
    -webkit-transform: rotate(0deg);
  }
  50% {
    -webkit-transform: rotate(180deg);
  }
  75% {
    -webkit-transform: rotate(180deg);
  }
  100% {
    -webkit-transform: rotate(180deg);
  }
}
<div class="container mt-5">
  <div class="row">
    <div class="col-3">
      <div id="circle-loader-wrap">
        <div class="left-wrap">
          <div class="loader"></div>
        </div>
        <div class="right-wrap">
          <div class="loader"></div>
        </div>
      </div>
    </div>
  </div>
</div>

Answer №1

If you're looking to achieve a specific animation effect, check out the snippet below:

To make things clearer, I've included explanations within the code comments that correspond to the CSS rules responsible for the animations.

If there's anything that still seems confusing, feel free to drop a comment.

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

<style>
    #circle-loader-wrap {
        overflow: hidden;
        position: relative;
        margin-top: -10px;
        width: 200px;
        height: 200px;
        box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1) inset;
        background-color: blue;
        border-radius: 200px;
        transform: rotate(180deg);
    }

    #circle-loader-wrap:after {
        content: '';
        position: absolute;
        left: 15px;
        top: 15px;
        width: 170px;
        height: 170px;
        border-radius: 50%;
        background-color: green;
        box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
    }

    #circle-loader-wrap div {
        overflow: hidden;
        position: absolute;
        width: 50%;
        height: 100%;
    }

    #circle-loader-wrap .loader {
        position: absolute;
        left: 100%;
        top: 0;
        width: 100%;
        height: 100%;
        border-radius: 1000px;
        background-color: pink;
    }

    #circle-loader-wrap .left-wrap {
        left: 0;
    }

    #circle-loader-wrap .left-wrap .loader {
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
        transform-origin: 0 50% 0;
        animation: loading-left 5s infinite linear;
    }

    #circle-loader-wrap .right-wrap {
        left: 50%;
    }

    #circle-loader-wrap .right-wrap .loader {
        left: -100%;
        border-bottom-right-radius: 0;
        border-top-right-radius: 0;
        transform-origin: 100% 50% 0;
        animation: loading-right 5s infinite linear;
    }

    @keyframes loading-left {
        0% {
            transform: rotate(0deg);
        }
        25%, 100% {
/*          the following is for the second half of the circle */
/*          180deg means one half of the cicle or 50% of the cicle */
/*          So, 1% is gonna be 180/50 = 3.6deg */
/*          If you want 68%, then you have 18% left for the second half of the circle */
/*          To get 18%: 18x3.6 = 64.8deg */
            transform: rotate(64.8deg);
/*          Note: The transformation will happen between 25% and 50% of the total time which is 5 seconds in this case; So, it's gonna take 1.25 seconds. */
/*          In other words, it will take the same amount of time as for the first half of the circle which will make the transformation in the second half appear to be slower because it has the same time to cover a much shorter distance */
/*          Between 50% and 100% nothing happens. */
/*          That's your "pause" in this animation although technically it's not a pause. */
        }
    }

    @keyframes loading-right {
        0%, 25% {
            transform: rotate(0deg);
        }
        50%, 100% {

        }
    }
</style>

<div class="container mt-1">
    <div class="row">
        <div class="col">
            <p>68% in this case:</p>
                <div id="circle-loader-wrap">
                    <div class="left-wrap">
                        <div class="loader"></div>
                    </div>
                    <div class="right-wrap">
                        <div class="loader"></div>
                    </div>
                </div>
                <p>The comments next to the corresponding css rules show how to adjust.</p>
            </div>
        </div>
    </div>
</div>

Just a quick note: I removed the vendor prefixes as they are no longer necessary for these CSS rules.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

HTML5 Dragend event failed to trigger in Firefox

While working on my project, I encountered an issue where the 'dragend' event is not fired in Firefox 22.0 on Ubuntu but works perfectly fine in Chrome. I have written a logic to make changes on drag start and revert them if drop fails, triggered ...

A Guide on Adding Excel-Like Filtering Functionality to AngularJS

I am struggling to implement a simple Excel-like filter for a table using AngularJS (v.1). I have shared my code snippet below and would appreciate any help to show filtered data in the table after checking a checkbox and clicking on the OK button. I have ...

[Vue alert]: Issue in created function: "TypeError: Unable to assign value to undefined property"

I'm currently in the process of developing a VueJS application where I have implemented a child component called Child.vue that receives data from its parent. Child.vue export default{ props:['info'], data: function(){ ...

Choose the heading element based on its class

I am trying to target a specific element by its class and store it in a variable, but I specifically need this element to be a heading element. To clarify: at any given time, there are always exactly 3 elements with this particular class on my page: an < ...

What is the best way to position the div element to the right side of the webpage?

Looking at my HTML code below, I am trying to reposition the 'site-logo' and 'nav-search-wrapper' div elements to the left side of the parent div (top-nav) and have the 'list' div element appear on the right side. However, the ...

Encountering a syntax error while utilizing a JavaScript variable in a jQuery selector for a lightbox feature

I'm currently working on creating a lightbox feature and have reached the stage where I am implementing next and previous buttons to navigate through images. I am utilizing console.log to check if the correct href is being retrieved when the next butt ...

Transparent background with opaque text

I noticed that my div has a gray background with some opacity. <div className="absolute w-full h-full top-0 left-0 right-0 bottom-0 bg-slate-500 opacity-50 z-10"> <p className="relative top-1/2 px-8 text-center hea ...

Obtaining data from console.log and showcasing it within a div element

Currently, I am facing a challenge where I want to retrieve the title, plot, and poster using the themoviedb API. However, I am lost on how to begin coding this. Whenever I perform a search, the information is displayed in the console log of the browser. ...

The page fades in as soon as it is loaded thanks to the "

I am interested in creating a unique effect where different classes fade in on page load. Check out this webpage for reference. The linked page showcases squares in various shades of grey and color, with the desire to have them fade in at different inter ...

Problem with Internet Explorer version 9 and above and the Flip Card feature

I have a cool feature for one of my clients where clicking on one div causes another div to flip in its place, like a card flipping over. It's kind of like those portfolio image flippers, but instead of images, it flips divs with content inside. How ...

MUI useStyles/createStyles hook dilemma: Inconsistent styling across components, with styles failing to apply to some elements

I have been trying to style my MUI5 react app using the makeStyles and createStyles hooks. The root className is being styled perfectly, but I am facing an issue with styling the logoIcon. Despite multiple attempts to debug the problem, I have not been suc ...

Sending array values from a dynamic input field in Angular 4 and processing them accordingly

I am currently exploring options on how to add and delete multiple input fields. When a user submits two or more fields, I want the results to be displayed in an array. This is my HTML form: <form method="post" [formGroup]="formData"> ...

Ensure that the text within the ng-repeat is wrapped in a span element and each

When using ng repeat in span, I encountered a word breaking into a new line. Here is the actual output: https://i.stack.imgur.com/k4c9k.png To style this, I implemented the following CSS: border: 1px solid #ECE9E6; border-radius: 3px; text- ...

What could be causing the issues with the compatibility of <input type="text" and flex properties?

I'm having an issue where the search box expands in size when I apply display:flex in my CSS. Can someone explain why this happens and offer a solution to return the search box to its normal height? Additionally, I would like the search bar and the se ...

Unique solution: "Using CSS to ensure the overflow document always scrolls to the bottom

Is there a way in CSS to make a div with overflow: scroll always automatically scroll to the bottom along the Y-axis, regardless of its content? For example, like a chat thread that consistently displays the latest message at the bottom. I've encount ...

What is the process for creating a login page that redirects automatically?

For instance: Whenever I enter gmail.com, it automatically takes me to this link: https://accounts.google.com/signin/v2/identifier?service=mail&passive=true&rm=false&continue=https%3A%2F%2Fmail.google.com%2Fmail%2F&ss=1&scc=1&ltmp ...

DataTables.js, the powerful JavaScript library for creating interactive tables, and its compatible counterpart

I'm currently making some changes to a dynamic table that require enabling a vertical scroll bar. As a result, I need to implement this vertical scroll bar mechanism on an existing table. The code in our project utilizes dataTables.js version 1.5.2 ...

How can you make a dropdown button interactive and display a list simultaneously?

I'm facing an issue with lines 45-47 in the second link. If that code is present, the button animates when clicked (which is great) BUT the dropdown items ("About," "Archive," "Contact") do not appear. If I remove lines 45-47, the dropdown items appea ...

Discover the hexadecimal color code generated from an rgba color

Do you know of a service that can determine the final hexadecimal value of an rgba color? For instance, if my body background-color is set to #FF0000 and my header is positioned over it with a background-color of rgba(0,0,0,.7), how can I find out what the ...

How can I make my div change color when the check-box is selected?

I have a dynamic table in my web application that is populated with data from a database. Each row in the table represents multiple time slots for a specific date. I am working on a feature where the background color of a time block can be changed if a che ...