1

I can't figure out how to do this, is it really possible to twist the beggining of a progress bar with css, html, javascript or jquery without using images?

What I mean:

ProgressBarDesign1

ProgressBarDesign2

What I got so far (just a normal progress bar..):

#xp-bar{
  top: 60%;
  left: 5%;
  height:10px;
  width:90%;
  background:#035;
  border-radius: 5px;
  /*margin:0px 0px 0px 15px;*/
  display:inline-block;
  vertical-align:middle;
  position: absolute; }
#xp-bar-fill{
  height:100%;
  width:50.1%;
  background-color:#d50000;
  font-size:12px;
  line-height:10px;
  text-align:right; }
.progress-bar-striped {
  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-size: 40px 40px; }
.progress-bar-striped.active {
  -webkit-animation: progress-bar-stripes 2s linear infinite;
  -o-animation: progress-bar-stripes 2s linear infinite;
  animation: progress-bar-stripes 2s linear infinite;
}
@-webkit-keyframes progress-bar-stripes {
  from { background-position: 40px 0; } to { background-position: 0 0; } }
@keyframes progress-bar-stripes {
  from { background-position: 40px 0; } to { background-position: 0 0; } }
<div id='xp-bar'>
  <div id='xp-bar-fill' class="progress-bar-striped active">
  </div>
</div>

I just want to twist the beggining of that progress bar to be like the designs, I know how to do this with images but I wanted to know if it is really possible without them. Might be interested to a plugin if there's any

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Bosco
  • 37
  • 1
  • 10
  • That's not possible with a single element. You could create a circle using `border-radius: 50%` and then align it with a separate straight element, along with some creative clipping to only show part of it. However it's a lot of work and I would imaging making it work cross-browser would be a nightmare, then there's actually making it work like a single progress bar across multiple elements. – Rory McCrossan Dec 04 '19 at 20:53
  • Have you tried an svg with a linear gradient? That way you can set the percentage of the colour within the svg and also animate it: https://stackoverflow.com/questions/51718987/fill-custom-svg-image-using-percentage-value – Nathaniel Flick Dec 04 '19 at 20:55
  • It should be noted that there is a native HTML element for this called [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress) that should be used instead of a `
    ` whenever possible. It doesn't help with your curl though.
    – Sean Dec 04 '19 at 20:58
  • Okay then, was hoping this could be done, like put some rotation on it on some way.. but will need to do the circle then another progress bar and bend it together like you say, I don't know how to work them like a single one but will try it, maybe will finally do it with images, that will be easier thanks anyway Rory! – Bosco Dec 04 '19 at 20:59
  • @NathanielFlick yeas that will work mate but I was hoping doing this without using any images! – Bosco Dec 04 '19 at 21:00
  • Noted @Sean thank you – Bosco Dec 04 '19 at 21:02
  • @Bosco Fair enough, though an svg can potentially be smaller than an image of the same size and appearance. ;) – Nathaniel Flick Dec 04 '19 at 21:05
  • 1
    That is actually awesome @NathanielFlick !! will do that, much appreciated! – Bosco Dec 04 '19 at 21:09

1 Answers1

0

Like Rory McCrossan said, I've tried to do the two elements behaving like one and this is the result so far:

function doit(){
 $("#xp-increase-fx").css("display","inline-block");
 $("#xp-bar-fill").css("box-shadow",/*"0px 0px 15px #06f,*/ "-5px 0px 10px #fff inset");
 $("#xp-circle-fill").css("box-shadow",/*"0px 0px 15px #06f,*/ "-5px 0px 10px #fff inset");
 
 setTimeout(function(){
  $("#xp-bar-fill").css("-webkit-transition","all 2s ease");
  $("#xp-bar-fill").css("width","80%");
  $("#xp-circle-fill").css("-webkit-transition","all 0.34s ease").css("width","100%");
 },100);
 
 setTimeout(function(){
  $("#xp-increase-fx").fadeOut(500);
  $("#xp-bar-fill").css({"-webkit-transition":"all 0.5s ease","box-shadow":""});
  $("#xp-circle-fill").css({"-webkit-transition":"all 1s ease","box-shadow":""});
 },2000);
 
 setTimeout(function(){
  $("#xp-bar-fill").css("width", "0.1%");
  setTimeout(function(){ $("#xp-circle-fill").css("width", "0.1%"); },200);
 },3000);
  }
#xp-widget{
  position:absolute;
  top: 20%;
  width: 310px;
  left: 50%;
  transform: translateX(-50%); }
#xp-bar,#xp-circle,#xp-ol-circle{
  left: 16px;
  height:10px;
  width:92%;
  background:#035;
  border-radius: 5px;
  overflow: hidden;
  display:inline-block;
  vertical-align:middle;
  position: absolute; }
#xp-circle{
  top: -18px;
  left: 13px;
  height: 50px;
  width: 50px;
  border-radius: 50%; }
#xp-ol-circle{
  top: -9px;
  left: 21px;
  height: 33px;
  width: 33px;
  border-radius: 50%; }
#xp-bar-fill,#xp-circle-fill{
  height:100%;
  width:0.1%;
  background-color:#d50000;
  font-size:12px;
  line-height:10px;
  text-align:right; }
#xp-circle-fill{ width: 0.1%; border-radius: 50%; }
#xp-increase-fx{
  position:relative;
  display:none;
  height:100%; }
.xp-increase-glow1{
  position:absolute;
  margin:0px 0px 0px -2px;
  left:0px;
  top:0px;
  background:#fff;
  width:5px;
  height:100%;
  border-radius:0px;
  -webkit-filter:blur(2px); }
.xp-increase-glow2{
  position:absolute;
  margin:-5px 0px 0px -2px;
  left:0px;
  top:0px;
  background:#aaf;
  width:5px;
  height:200%;
  border-radius:0px;
  -webkit-filter:blur(10px); }
.xp-increase-glow3{
  position:absolute;
  margin:0px 0px 0px -5px;
  left:0px;
  top:0px;
  background:#fff;
  width:10px;
  height:100%;
  border-radius:5px;
  -webkit-filter:blur(5px); }
.progress-bar-striped {
  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
  background-size: 40px 40px; }
.progress-bar-striped.active {
  -webkit-animation: progress-bar-stripes 2s linear infinite;
  -o-animation: progress-bar-stripes 2s linear infinite;
  animation: progress-bar-stripes 2s linear infinite; }

.mCharLvl {
  top: 8px;
  left: 1px;
  width: 33px;
  position: absolute;
  color: #ffffff;
  text-shadow: -1px 0px black, 1px 0px black, 0px 1px black, 0px -1px black, 1px 1px black, 2px 2px #000000; }

.debugTest { top: 20%; position: absolute; }

@-webkit-keyframes progress-bar-stripes {
  from { background-position: 40px 0; } to { background-position: 0 0; } }
@keyframes progress-bar-stripes {
  from { background-position: 40px 0; } to { background-position: 0 0; } }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="xp-widget">
     <tr>
       <th id='xp-bar'>
      <div id='xp-bar-fill' class="progress-bar-striped active">
        <div id='xp-increase-fx'>
       <div id='xp-increase-fx-flicker'>
         <div class='xp-increase-glow1'></div>
         <div class='xp-increase-glow2'></div>
         <div class='xp-increase-glow3'></div>
       </div>
       <div class='xp-increase-glow2'></div>
        </div>
      </div>
       </th>
       <th id="xp-circle">
      <div id='xp-circle-fill' class="progress-bar-striped active">
        <div id='xp-increase-fx'>
       <div id='xp-increase-fx-flicker'>
         <div class='xp-increase-glow1'></div>
         <div class='xp-increase-glow2'></div>
         <div class='xp-increase-glow3'></div>
       </div>
       <div class='xp-increase-glow2'></div>
        </div>
      </div>
       </th>
       <th id="xp-ol-circle"><span id="mCharLevel" class="mCharLvl">7</span></th>
     </tr>
      </table>
          <button class="debugTest" onclick="doit()">Try Me !</button>

But I will finally try Svg like Nathaniel Flick suggested, useful to be able to use a predefined path and I would say it's the better approach as I want the progress bar following a path that otherwise seems impossible or very tricky to do

Thanks for your suggestions!

Bosco
  • 37
  • 1
  • 10