0

I'm trying to make an animated semi-circle skill bar, based only CSS and JS (no jQuery or other frameworks).

Here is a really bad MS Paint drawing example:

enter image description here

The blue part of the skill bar needs to animate on page load, and the percentage animation counts up from 0.

Both the percentage number and the amount of blue skill bar need be set inside the HTML. And the whole thing needs to be responsive.

I started creating the design as normal skill bar, but for the life of me I can't figure out how to curve it into a semi-circle.

let start // set on the first step to the timestamp provided
const el = document.getElementById('count') // get the element
const final = parseInt(el.textContent, 10) // parse out the final number
const duration = 2000 // duration in ms
const step = ts => {
  if (!start) {
    start = ts
  }
  // get the time passed as a percentage of total duration
  let progress = (ts - start) / duration

  el.textContent = Math.floor(progress * final) // set the text
  if (progress < 1) {
    // if we are not 100% complete, request another animation frame
    requestAnimationFrame(step)
  }
}

// start the animation
requestAnimationFrame(step)
.outerbar {
  width: 100%;
  height: 20px;
  background-color: #eee;
  border-radius: 100px;
}

.bar {
  background: #1565C0;
  border-radius: 100px;
  height: 100%;
  transition: width 1s linear;
  float: left;
  min-width: 30px;
}

.text-label {
  font-size: 14px;
  text-align: center;
}

.percent-label {
  float: right;
  margin-right: 5px;
  font-size: 12px;
  line-height: 1.7em;
}


/* Animate the blue skill bar on page load */
@-webkit-keyframes bar {
  0% {
    width: 0;
  }
}

@-moz-keyframes bar {
  0% {
    width: 0;
  }
}

@keyframes bar {
  0% {
    width: 0;
  }
}

.bar {
  -webkit-animation: bar 2s ease-in-out;
  -moz-animation: bar 2s ease-in-out;
  animation: bar 2s ease-in-out;
}
<div class="outerbar">
  <div class="bar" style="width: 40%;">
    <div class="percent-label"><span id="count">40</span>%</div>
  </div>
</div>
<div class="text-label">Total Score</div>
Gautam Naik
  • 8,990
  • 3
  • 27
  • 42
TinyTiger
  • 1,801
  • 7
  • 47
  • 92
  • This already exists (without the nifty curve) as `` element. I wonder if there's a way to manipulate that element rather than curving a div. – Anthony May 09 '18 at 05:25
  • 1
    Barring that, I would highly encourage using an embedded svg (which you can style with css and manipulate with JavaScript) rather than inventing a pure CSS/html solution that is doing a bunch of work that an svg can do directly (and was designed to do). Especially if you want to easily update it later on. But I'm not a fan of using border radius for drawing shapes. – Anthony May 09 '18 at 05:31
  • I’m not too familiar with SVGs, they look scarily complex and difficult to edit. Changing the bar width, for example, would probably throw the whole thing out. – TinyTiger May 09 '18 at 05:44
  • You would just draw an arc and change the arc and change the end point as you want it to grow. Everything else should be pretty responsive since it's a vector graphic. But you should also mess around with `progress`. I don't know how to get it to bend or change the style much (yet), but I plugged in your javascript here: https://jsfiddle.net/ded8s4hu/1/ – Anthony May 09 '18 at 05:55
  • More good stuff, still not quite there with the curve, but suggests potential. https://css-tricks.com/html5-progress-element/ – Anthony May 09 '18 at 06:26
  • And if you just want an svg solution that already exists: https://daverupert.com/2018/03/animated-svg-radial-progress-bars/ – Anthony May 09 '18 at 06:33
  • Thanks for the tips. I'm going through it all to try and which direction to take. – TinyTiger May 09 '18 at 07:00
  • One more: https://stackoverflow.com/questions/30230018/how-to-style-an-html5-progress-element-as-circle-pie-with-pure-css – Anthony May 09 '18 at 07:01
  • The svg solution you gave (https://daverupert.com/2018/03/animated-svg-radial-progress-bars/) looks pretty close to what I need. I'm just trying to figure out how to turn it into a semi-circle, round the corners, and put some text in there. – TinyTiger May 09 '18 at 07:23

0 Answers0