Как правильно сделать расчет значений линейки от ширины контейнера?

Делаю свой rangeSlider, проблема с вычислением линейки значений. В createBetweenScale() создаются разделители.

В calcValuesWith() расчет через какой шаг буду создаваться разделители(выводится в консоли).

В текущем варианте есть проблема с производительностью при больших значения. Т.к. сперва циклом рассчитывается вся длина значений от max до min.

Подскажите плз способ получше.

P.S. при запуске немного подождите, оно работает. Чтобы было нагляднее - поставил большие значения.

const defaultConfig = {
  min: -1000000,
  max: 1000000,
  step: 5
};

class Scale {
  wrapperElement;
  scale;

  getSize(element) {
    return element.offsetWidth;
  }

  get getSeparatorCounts() {
    return Math.ceil((defaultConfig.max - defaultConfig.min) / defaultConfig.step);
  }

  setPxValue(elem, value) {
    elem.style.left = `${Math.floor(value)}px`;
  }

  get getPixelSize() {
    return (defaultConfig.max - defaultConfig.min) / this.getSize(this.wrapperElement);
  }

  get getStepSize() {
    return defaultConfig.step / this.getPixelSize;
  }

  createScale(rangeSliderSelector) {
    this.wrapperElement = document.querySelector(rangeSliderSelector);
    this.scale = document.createElement('div');
    this.scale.classList.add('scale');

    this.createBetweenScale();
    this.createLastScale();
  }

  calcValuesWith(){
    const PADDING = 2
    const FONTSIZE = 8
    const [arrayPixelValue, arrayValue] = this.getValues();
    let width = 0
    const el = document.createElement('span')
    for (let i = 0; i < this.getSeparatorCounts; i++) {
      el.innerHTML = (arrayValue[i])
      width += (arrayValue[i].toString().length)
    }
    const fullInnerSize = width*FONTSIZE*PADDING
    const indexStep = Math.ceil((fullInnerSize * 100 / this.getSize(this.wrapperElement)) / 100)
    return indexStep
  }


  getValues() {
    const sliderSize = this.getSize(this.wrapperElement);
    let currentStep = 0;
    let currentValue = defaultConfig.min;

    const arrayPixelValue = [0];
    const arrayValue = [defaultConfig.min];

    while (currentStep <= sliderSize) {
      currentStep += this.getStepSize;
      currentValue += defaultConfig.step;
      if (currentStep < sliderSize) {
        arrayPixelValue.push(currentStep);
        arrayValue.push(currentValue);
      } else {
        arrayPixelValue.push(sliderSize);
        arrayValue.push(defaultConfig.max);
      }
    }
    return [arrayPixelValue, arrayValue];
  }

  createBetweenScale() {
    const [arrayPixelValue, arrayValue] = this.getValues();
    for (let i = 0; i < this.getSeparatorCounts; i += this.calcValuesWith()) {
      console.log(i);
      /* creating el */
      const btwScale = document.createElement('span');
      btwScale.classList.add('scale__separator', 'scale__separator--beetwen');

      /* adding value */
      btwScale.innerHTML = (arrayValue[i]).toString();
      this.setPxValue(btwScale, arrayPixelValue[i]);

      /* appending */
      this.scale.append(btwScale);
      this.wrapperElement.append(this.scale);
    }
  }

  createLastScale() {
    const lastScale = document.createElement('span');
    lastScale.innerHTML = defaultConfig.max.toString();
    lastScale.classList.add('scale__separator', 'scale__separator--last');
    this.setPxValue(lastScale, this.getSize(this.wrapperElement));
    this.scale.append(lastScale);
    this.wrapperElement.append(this.scale);
  }

}

const scale = new Scale()
scale.createScale('.range-slider')
.range-slider {
  width: 400px;
  height: 30px;
  background: rgba(0, 0, 0, 0.365);
}

.range-slider__wrapper {
  position: relative;
  height: 100%;
}

.scale {
  width: inherit;
  display: block;
  position: absolute;
  user-select: none;
  padding-top: 20px;
}

.scale__separator {
  position: absolute;
}

.scale__separator::before {
  position: absolute;
  top: -16px;
  display: block;
  width: 2px;
  height: 8px;
  background: #000000cf;
  border-radius: 2px;
  content: "";
}

.scale__separator--first::before{
    height: 14px;
  }


.scale__separator--last::before{
    height: 14px;
  }
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>
<body>
  <div class="range-slider"></div>
</body>
</html>


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