1

I have a basic webpage which I'm trying to show progress/completion status of one background task by using CSS from this Liquid bubble progress bar.

Further, I have multiple such background tasks and I want to show progress of each in the same html webpage by using another copy of that bubble progress bar. Say like I want to have 5 such bubbles and each showing progress of 5 independent tasks, I guess I have to copy paste the CSS of 1 bubble and change from name x to y for 5 times and use the 5 new names accordingly. Which is not right way to do.

Is there a way where i can replicate it for T times with a new names using javascript or something or any easy methods?

Please could I get some help to make the right javascript code and the right function calls to achieve that. Thanks heaps in advance.

Below is the CSS code from the source.

@import "nib"

@keyframes spin
  from
    transform rotate(0deg)
  to
    transform rotate(360deg)

 placeholder()
  ::-webkit-input-placeholder
    {block}
  :-moz-placeholder
    {block}
  ::-moz-placeholder
    {block}
  :-ms-input-placeholder
    {block}

text-glow()
  text-shadow 0 0 arguments

box-glow()
  box-shadow 0 0 arguments

// Page
page-font = sans-serif
page-background-color = darken(white, 90%)

progress-bubble($color, $amount)
  // Progress Bar
  progress-primary-color = $color
  progress-size = 250px
  progress-border-size = 5px
  progress-inner-border-size = 5px
  progress-inner-size = progress-size - (progress-border-size + progress-inner-border-size)
  progress-inner-border = progress-inner-border-size solid page-background-color

  progress-alpha = 50%
  progress-level-change-speed = 1s
  progress-swish-speed = 10s
  progress-percent-color = darken(progress-primary-color, 40%)

  progress-percent-glow = 10px darken(progress-percent-color, 25%)
  progress-box-glow = 20px darken(progress-percent-color, 25%)
  progress-liquid-glow = 20px darken(progress-percent-color, 5%)

  progress-glare-background = rgba(255, 255, 255, 0.15)
  progress-level = (100% - $amount)
  
  .progress
    +cache('.progress')
      position relative
      border-radius 50%

    +cache('.progress' + progress-size)
      width progress-size
      height progress-size
    
    +cache('.progress' + progress-border-size + " " + progress-primary-color)
      border progress-border-size solid progress-primary-color
    
    +cache('.progress' + progress-box-glow)
      box-glow progress-box-glow
    
    +cache('.progress' + progress-level-change-speed)
      transition all progress-level-change-speed ease
      
    .inner
      +cache('.progress .inner')
        position absolute
        overflow hidden
        z-index 2
        border-radius 50%
        
      +cache('.progress .inner' + progress-inner-size)
        width progress-inner-size
        height progress-inner-size

      +cache('.progress .inner' + progress-inner-border)
        border progress-inner-border
        
      +cache('.progress .inner' + progress-level-change-speed)
        transition all progress-level-change-speed ease

      .water
        +cache('.progress .inner .water')
          position absolute
          z-index 1
          width 200%
          height 200%
          left -50%
          border-radius 40%
          animation-iteration-count infinite
          animation-timing-function linear
          animation-name spin
        
        +cache('.progress .inner .water' + progress-level)
          top progress-level
        
        +cache('.progress .inner .water' + progress-primary-color + " " + progress-alph)
          background alpha(progress-primary-color, progress-alpha)
        
        +cache('.progress .inner .water' + progress-level-change-speed)
          transition all progress-level-change-speed ease
        
        +cache('.progress .inner .water' + progress-swish-speed)
          animation-duration progress-swish-speed
        
        +cache('.progress .inner .water' + progress-liquid-glow)
          box-glow progress-liquid-glow

      .glare
        +cache('.progress .inner .glare')
          position absolute
          top -120%
          left -120%
          z-index 5
          width 200%
          height 200%
          transform rotate(45deg)
          border-radius 50%
        
        +cache('.progress .inner .glare' + progress-glare-background)
          background-color progress-glare-background
        
        +cache('.progress .inner .glare' + progress-level-change-speed)
          transition all progress-level-change-speed ease

      .percent
        +cache('.progress .inner .percent')
          position absolute
          top 0
          left 0
          width 100%
          height 100%
          font-weight bold
          text-align center
          
        +cache('.progress .inner .percent' + progress-inner-size)
          line-height progress-inner-size
          font-size (progress-inner-size / 2.6px)
        
        +cache('.progress .inner .percent' + progress-percent-color)
          color progress-percent-color
        
        +cache('.progress .inner .percent' + progress-percent-glow)
          text-glow progress-percent-glow
        
        +cache('.progress .inner .percent' + progress-level-change-speed)
          transition all progress-level-change-speed ease

*
  box-sizing border-box

html, body
  height 100%

body
  background-color page-background-color
  font-family page-font
  font-size 15px
  color darken(white, 20%)

input[type="text"]
  background-color transparent
  margin-top 30px
  border 0
  border-bottom solid 1px lighten(blue, 50%)
  text-align center
  font-size 20px
  color lighten(rgb(50, 118, 237), 15%)
  text-glow 3px lighten(rgb(50, 118, 237), 15%)
  width 45px
  display inline-block
  
input:focus
  outline 0
  border-bottom dashed 1px lighten(red, 50%)

input::selection
  color page-background-color
  background-color lighten(lightblue, 30%)

+placeholder()
  color lighten(rgb(50, 118, 237), 35%)
  text-glow 3px lighten(rgb(50, 118, 237), 35%)

.wrapper
  display flex
  align-items center
  justify-content center
  flex-direction column
  height 100%

.green
  margin-top 15px
  progress-bubble(rgb(83, 252, 83), 75%)

.red
  margin-top 15px
  progress-bubble(rgb(237, 59, 59), 25%)

.orange
  margin-top 15px
  progress-bubble(rgb(240, 124, 62), 50%)

#copyright
  margin-top 25px
  background-color transparent
  font-size 14px
  color darken(white, 30%)
  text-align center
  
  div
    margin-bottom 10px
  
  a
  a:link
    color gray
    text-decoration none
    border-bottom 1px solid gray
    padding-bottom 2px

  a:active
    color darken(white, 30%)
  
  a:hover
    color darken(white, 30%)
    border-bottom 1px solid darken(white, 30%)
    padding-bottom 4px

.instructions
  display inline-block
  margin 5px 0
  font-size 16px

2 Answers 2

2

this should help you to get the idea. what I did is mapped the bubble with input using a custom attribute and then binding the click and change events using the custom attribute groupid

var colorInc = 100 / 3;

$(function() {
  $(".percent-box").each(function() {
    $(this).click(function() {
      $(this).select();
    });
  })


  $(".percent-box").each(function() {
    $(this).keyup(function() {
      var val = $(this).val();
      var groupId = $(this).attr('group'); // get the group id to correctly target the liquid bubble
      if (val <= 100 &&
        val >= 0) {}
      if (val != "" &&
        !isNaN(val) &&
        val <= 100 &&
        val >= 0) {
        //console.log(val);
        var valOrig = val;
        val = 100 - val;
        if (valOrig == 0) {
          $("[group=" + groupId + "] .percent-box").val(0);
          $("[group=" + groupId + "] .progress .percent").text(0 + "%");
        } else $("[group=" + groupId + "] .progress .percent").text(valOrig + "%");

        $("[group=" + groupId + "]  .progress").parent().removeClass();
        $("[group=" + groupId + "] .progress .water").css("top", val + "%");

        if (valOrig < colorInc * 1)
          $("[group=" + groupId + "] .progress").parent().addClass("red");
        else if (valOrig < colorInc * 2)
          $("[group=" + groupId + "]  .progress").parent().addClass("orange");
        else
          $("[group=" + groupId + "]  .progress").parent().addClass("green");
      } else {
        $("[group=" + groupId + "] .progress").parent().removeClass();
        $("[group=" + groupId + "] .progress").parent().addClass("green");
        $("[group=" + groupId + "] .progress .water").css("top", 100 - 67 + "%");
        $("[group=" + groupId + "] .progress .percent").text(67 + "%");
        $("[group=" + groupId + "].percent-box").val($("[group=" + groupId + "].percent-box").attr('placeholder'));
      }
    })
  });
});
* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  background-color: #1a1a1a;
  font-family: sans-serif;
  font-size: 15px;
  color: #ccc;
}

input[type="text"] {
  background-color: transparent;
  margin-top: 30px;
  border: 0;
  border-bottom: solid 1px #8080ff;
  text-align: center;
  font-size: 20px;
  color: #518bf0;
  text-shadow: 0 0 3px #518bf0;
  width: 45px;
  display: inline-block;
}

input:focus {
  outline: 0;
  border-bottom: dashed 1px #ff8080;
}

input::-moz-selection {
  color: #1a1a1a;
  background-color: #c6e4ee;
}

input::selection {
  color: #1a1a1a;
  background-color: #c6e4ee;
}

::-webkit-input-placeholder {
  color: #7aa6f3;
  text-shadow: 0 0 3px #7aa6f3;
}

:-moz-placeholder {
  color: #7aa6f3;
  text-shadow: 0 0 3px #7aa6f3;
}

::-moz-placeholder {
  color: #7aa6f3;
  text-shadow: 0 0 3px #7aa6f3;
}

:-ms-input-placeholder {
  color: #7aa6f3;
  text-shadow: 0 0 3px #7aa6f3;
}

.wrapper {
  display: -webkit-box;
  display: -ms-flexbox;
  display: box;
  display: flex;
  -webkit-box-align: center;
  -o-box-align: center;
  align-items: center;
  -webkit-box-pack: center;
  -o-box-pack: center;
  justify-content: center;
  -webkit-box-orient: vertical;
  -o-box-orient: vertical;
  flex-direction: column;
  height: 100%;
}

.green {
  margin-top: 15px;
}

.green .progress,
.red .progress,
.orange .progress {
  position: relative;
  border-radius: 50%;
}

.green .progress,
.red .progress,
.orange .progress {
  width: 250px;
  height: 250px;
}

.green .progress {
  border: 5px solid #53fc53;
}

.green .progress {
  box-shadow: 0 0 20px #029502;
}

.green .progress,
.red .progress,
.orange .progress {
  -webkit-transition: all 1s ease;
  transition: all 1s ease;
}

.green .progress .inner,
.red .progress .inner,
.orange .progress .inner {
  position: absolute;
  overflow: hidden;
  z-index: 2;
  border-radius: 50%;
}

.green .progress .inner,
.red .progress .inner,
.orange .progress .inner {
  width: 240px;
  height: 240px;
}

.green .progress .inner,
.red .progress .inner,
.orange .progress .inner {
  border: 5px solid #1a1a1a;
}

.green .progress .inner,
.red .progress .inner,
.orange .progress .inner {
  -webkit-transition: all 1s ease;
  transition: all 1s ease;
}

.green .progress .inner .water,
.red .progress .inner .water,
.orange .progress .inner .water {
  position: absolute;
  z-index: 1;
  width: 200%;
  height: 200%;
  left: -50%;
  border-radius: 40%;
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
  -webkit-animation-timing-function: linear;
  animation-timing-function: linear;
  -webkit-animation-name: spin;
  animation-name: spin;
}

.green .progress .inner .water {
  top: 25%;
}

.green .progress .inner .water {
  background: rgba(83, 252, 83, 0.5);
}

.green .progress .inner .water,
.red .progress .inner .water,
.orange .progress .inner .water {
  -webkit-transition: all 1s ease;
  transition: all 1s ease;
}

.green .progress .inner .water,
.red .progress .inner .water,
.orange .progress .inner .water {
  -webkit-animation-duration: 10s;
  animation-duration: 10s;
}

.green .progress .inner .water {
  box-shadow: 0 0 20px #03bc03;
}

.green .progress .inner .glare,
.red .progress .inner .glare,
.orange .progress .inner .glare {
  position: absolute;
  top: -120%;
  left: -120%;
  z-index: 5;
  width: 200%;
  height: 200%;
  -webkit-transform: rotate(45deg);
  transform: rotate(45deg);
  border-radius: 50%;
}

.green .progress .inner .glare,
.red .progress .inner .glare,
.orange .progress .inner .glare {
  background-color: rgba(255, 255, 255, 0.15);
}

.green .progress .inner .glare,
.red .progress .inner .glare,
.orange .progress .inner .glare {
  -webkit-transition: all 1s ease;
  transition: all 1s ease;
}

.green .progress .inner .percent,
.red .progress .inner .percent,
.orange .progress .inner .percent {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  font-weight: bold;
  text-align: center;
}

.green .progress .inner .percent,
.red .progress .inner .percent,
.orange .progress .inner .percent {
  line-height: 240px;
  font-size: 92.3076923076923px;
}

.green .progress .inner .percent {
  color: #03c603;
}

.green .progress .inner .percent {
  text-shadow: 0 0 10px #029502;
}

.green .progress .inner .percent,
.red .progress .inner .percent,
.orange .progress .inner .percent {
  -webkit-transition: all 1s ease;
  transition: all 1s ease;
}

.red {
  margin-top: 15px;
}

.red .progress {
  border: 5px solid #ed3b3b;
}

.red .progress {
  box-shadow: 0 0 20px #7a0b0b;
}

.red .progress .inner .water {
  top: 75%;
}

.red .progress .inner .water {
  background: rgba(237, 59, 59, 0.5);
}

.red .progress .inner .water {
  box-shadow: 0 0 20px #9b0e0e;
}

.red .progress .inner .percent {
  color: #a30f0f;
}

.red .progress .inner .percent {
  text-shadow: 0 0 10px #7a0b0b;
}

.orange {
  margin-top: 15px;
}

.orange .progress {
  border: 5px solid #f07c3e;
}

.orange .progress {
  box-shadow: 0 0 20px #7e320a;
}

.orange .progress .inner .water {
  top: 50%;
}

.orange .progress .inner .water {
  background: rgba(240, 124, 62, 0.5);
}

.orange .progress .inner .water {
  box-shadow: 0 0 20px #a0400c;
}

.orange .progress .inner .percent {
  color: #a8430d;
}

.orange .progress .inner .percent {
  text-shadow: 0 0 10px #7e320a;
}

#copyright {
  margin-top: 25px;
  background-color: transparent;
  font-size: 14px;
  color: #b3b3b3;
  text-align: center;
}

#copyright div {
  margin-bottom: 10px;
}

#copyright a,
#copyright a:link {
  color: #808080;
  text-decoration: none;
  border-bottom: 1px solid #808080;
  padding-bottom: 2px;
}

#copyright a:active {
  color: #b3b3b3;
}

#copyright a:hover {
  color: #b3b3b3;
  border-bottom: 1px solid #b3b3b3;
  padding-bottom: 4px;
}

.instructions {
  display: inline-block;
  margin: 5px 0;
  font-size: 16px;
}

@-webkit-keyframes spin {
  from {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  to {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}

@keyframes spin {
  from {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  to {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<span class="instructions">The progress bubble below can transition between red, orange, and green depending on the current percentage.</span>
<span class="instructions">Go ahead and try it out by using the text box below.</span>

<div class="green" group="1">
  <div class="progress">
    <div class="inner">
      <div class="percent"><span>67</span>%</div>
      <div class="water"></div>
      <div class="glare"></div>
    </div>
  </div>
</div>

<span>Enter Percentage: <input type="text" group="1" placeholder="67" class = 'percent-box' id="percent-box1">%</span>

<div class="green" group="2">
  <div class="progress">
    <div class="inner">
      <div class="percent"><span>67</span>%</div>
      <div class="water"></div>
      <div class="glare"></div>
    </div>
  </div>
</div>
<span>Enter Percentage: <input type="text" group="2" placeholder="67" class = 'percent-box' id="percent-box2">%</span>
<div class="green" group="3">
  <div class="progress">
    <div class="inner">
      <div class="percent"><span>67</span>%</div>
      <div class="water"></div>
      <div class="glare"></div>
    </div>
  </div>
</div>
<span>Enter Percentage: <input type="text" group="3" placeholder="67" class = 'percent-box' id="percent-box3">%</span>

Sign up to request clarification or add additional context in comments.

Comments

1

One way, which seems to be a common technique, is to create new STYLE tags and append them into the BODY tag.

For example - see Create classes using javascript

With that method, you could build up whatever innerHTML you wanted to construct a complete class, or set of classes, using variables where necessary.

Here's a very simple idea of how that works:

function getRandomNumber(min, max) {
    // returns a random number between min and max, inclusive
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function createBoxes() {
  let bdy = document.body;
  for (let i = 1; i <= 5; i++) {
    let d = document.createElement("div");
    d.className = "div" + i;
    bdy.appendChild(d);
  }
  let s = document.createElement("style");
  s.type = "text/css";
  for (let i = 1; i <= 5; i++) {
    let r = getRandomNumber(0, 255);
    let g = getRandomNumber(0, 255);
    let b = getRandomNumber(0, 255);
    s.innerHTML += "\n.div" + i + "{background-color:rgb(" + r + "," + g + "," + b + "); height:100px; width:100px;}\n";
    bdy.appendChild(s);
  }
}
// for testing purposes only
window.onload = createBoxes;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.