Как правильно сделать расчет значений линейки от ширины контейнера?
Делаю свой 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>