Arc progress bar

2019-06-25 19:23发布

问题:

I need to make a circular progress bar (image below), loading start from left bottom side up to right bottom side. Light-blue (#E8F6FD) color is empty state and strong-blue (#1CADEB) is progress.

I have tried some approaches, but cannot find the best one for this implementation:

  1. First of all I tried using a div element with border-radius: 50%; and border-bottom-color: transparent;, jsfiddle. In this approach I got a shape exactly like in image but the problem is how can I fill border with progress?
  2. The second try was using canvas, and this approach is nice expect the reason that loader appears on the screen only after all JS loaded, I would like prevent this behavior and show loader immediately when page is loaded, jsfiddle

So my question is there any another approaches that can achive an arc loader or any suggestion for listed problems.

回答1:

You can use an inline SVG with arc commands to make the arc shape. The animation can be handled with CSS by transitioning the stroke-dasharray property.

Here is an example, hover the arc to launch the loading animation :

svg {
  display: block;
  width: 40%;
  margin: 0 auto;
}
.loader {
  stroke-dasharray: 0 18 18;
  transition: stroke-dasharray 2s linear;
}
svg:hover .loader {
  stroke-dasharray: 18 0 18;
}
<svg viewbox="0 0.5 10 8">
  <path d="M2 8 A 4 4 0 1 1 8 8" fill="none" stroke-width="0.78" stroke="#E8F6FD" />
  <path class="loader" d="M2 8 A 4 4 0 1 1 8 8" fill="none" stroke-width="0.8" stroke="#00ACEE" />
</svg>

Note that you will need to add vendor prefixes to the transition property for browser support (more info on canIuse).



回答2:

SVG solution

Here is a circle animation with SVG and CSS only.
Creating this took some time to get the timings right XD what i did was animate the svg path stroke-dasharray; And rotated that so it creates you semi half circle loading.

body {
  background-color: #222;
}
.load {
  fill: none;
  stroke: #e8f6fd;
  stroke-width: 5;
  stroke-dasharray: 200 300;
  transform: rotate(142deg);
  transform-origin: 50px 50px;
  animation: progress 5s linear reverse;
}
@keyframes progress {
  from {
    stroke-dasharray: 200 300;
  }
  to {
    stroke-dasharray: 0 300;
  }
}
.spesial {
  stroke: #1cadeb;
  stroke-dasharray: 5 300;
  transform: rotate(30deg);
  animation: circpro 5s linear;
}
@keyframes circpro {
  from {
    transform: rotate(-220deg);
  }
  to {
    transform: rotate(30deg);
  }
}
<svg viewBox="0 0 100 100" width="200px">
  <circle class="load" cx="50" cy="50" r="45" />
  <circle class="load spesial" cx="50" cy="50" r="45" />
</svg>