Как правильно сделать прогрессбар под xp and max_xp %?

Уважаемые программисты!) есть Прогрессбар на Bootstrap. Есть переменные this.xp и this.max_xp. Хочу сделать так, чтобы ПрогрессБар работал, как система уровней для игры: от 1 до 100% (от this.xp до this.max_xp).

Например:

this.xp = 1500;
this.max_xp = 9000;// и т.д.

$('#xp').text(this.xp + '%').css({width:this.xp});

введите сюда описание изображения

Как это сделать? Помогите, пожалуйста.


Ответы (1 шт):

Автор решения: OPTIMUS PRIME

Полоска должна занимать 100 * this.xp / this.max_xp + '%' ширины.
$('#xp').text(this.xp + '%').css({ width: 100 * this.xp / this.max_xp + '%' });

Около того:

$('#xp-add').on('click', function() {
  xp_add( 500 + Math.random() * 100 );
  // Любое действие лишь указывает, сколько опыта добавить. Ему не важно знать как.
});

this.xp = 1500;
this.xp_max = 9000;
this.level = 1;

function xp_add(num) {
  if (typeof num != 'number' || isNaN(num)) {
    throw new Error(`Expected a number, instead got: <${typeof num}> ${num}`);
  }
  
  this.xp += num;

  while (this.xp > this.xp_max) {
    this.xp -= this.xp_max;
    level_up();
  }
  
  xp_bar_update();
}

function xp_bar_update() {
  let percent = 100 * this.xp / this.xp_max;
  
  $('.xp-fill').css('width', percent + '%');
  $('.xp-text').text( Math.round(percent) + ' %' );
}

function level_up() { console.log('level-up:', ++this.level) }
.xp-bar {
  position: relative;
  height: 15px;
  background: #420;
}

.xp-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background: #f70;
}

.xp-text {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  
  text-align: center;
  font-size: 13px;
  color: #ffe2aa;
  text-shadow:
    1px 1px 1px #000,
    -1px 1px 1px #000,
    1px -1px 1px #000,
    -1px -1px 1px #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="xp-bar">
  <div class="xp-fill"></div>
  <div class="xp-text">0 %</div>
</div>
<hr>
<button id="xp-add">Click</button>

Предполагается, что функции будут размещены внутри какого-то объекта / класса. В этом примере this == window (так, конечно же, не надо делать).

Использован while вместо if, чтобы обработать несколько левел-апов, если прилетит много опыта, хватающего на несколько уровней. Функция level_up должна дополнительно обрабатывать случай максимального уровня.

Вместо отдельного блока для полоски, можно использовать background-image: linear-gradient и менять его проценты (немного муторно по сравнению с присваиванием width)

P.s. max_xp самовольно подменил на xp_max, потому что:

введите сюда описание изображения

Если соберется большой объект, в нем легче ориентироваться, если всё будет сгруппировано по "xp", а не по "max".

→ Ссылка