Страницы

Поиск по вопросам

понедельник, 4 марта 2019 г.

Расчет диапазона значений между двумя ползунками

Есть имитация input type="range" на javascript.
function Range(container) { this.container = container; if (!this.container) return; this.inputMin = container.querySelector('[data-type=input-min]'); this.inputMax = container.querySelector('[data-type=input-max]'); this.minValue = parseFloat(container.querySelector('[data-type=min-val]').textContent.replace(/\s/g, '')); this.maxValue = parseFloat(container.querySelector('[data-type=max-val]').textContent.replace(/\s/g, '')); this.inner = container.querySelector('[data-type=range-inner-element]'); this.valuesElem = container.querySelector('[data-type=range-element]'); this.minBtn = container.querySelector('[data-type=min-btn]'); this.maxBtn = container.querySelector('[data-type=max-btn]'); //console.log(this); this.init(); } Range.prototype.drag = function(event) { function move(event) { var left = event.pageX - elemX - boxX; if (elem == this.minBtn) { this.inner.style.left = elem.offsetLeft + elem.offsetWidth / 2 + 'px'; if (left < 0) { left = 0; } if (left > this.maxBtn.offsetLeft - elem.offsetWidth) { left = this.maxBtn.offsetLeft - elem.offsetWidth; } } else if (elem == this.maxBtn) { this.inner.style.right = elem.offsetLeft - elem.offsetWidth / 2 + 'px'; if (left < this.minBtn.offsetLeft + elem.offsetWidth) { left = this.minBtn.offsetLeft + elem.offsetWidth; } if (left > this.valuesElem.offsetWidth - elem.offsetWidth) { left = this.valuesElem.offsetWidth - elem.offsetWidth; } } elem.style.left = left + 'px'; this.inner.style.width = this.maxBtn.offsetLeft - this.minBtn.offsetLeft + 'px'; } function removeMove() { document.removeEventListener('mousemove', move); document.removeEventListener('mouseup', removeMove); } if (event.target == this.minBtn || event.target == this.maxBtn) { var elem = event.target; var elemX = event.pageX - elem.getBoundingClientRect().left; var boxX = this.valuesElem.getBoundingClientRect().left; var coord = event.target.offsetLeft; move = move.bind(this); document.addEventListener('mousemove', move); document.addEventListener('mouseup', removeMove); event.target.ondragstart = function() { return false; }; } } Range.prototype.setValue = function() { this.inputMin.value = this.minValue; this.inputMax.value = this.maxValue; } Range.prototype.init = function() { this.inner.style.left = this.minBtn.offsetLeft + this.minBtn.offsetWidth / 2 + 'px'; this.inner.style.right = this.maxBtn.offsetLeft - this.maxBtn.offsetWidth / 2 + 'px'; this.setValue(); this.valuesElem.addEventListener('mousedown', this.drag.bind(this)); } var range = new Range(document.querySelector('[data-type=range]')); .filters_section_list { width: 300px; list-style: none } .filters_section_item .range { height: 6px; background-color: #AEAEAE; border-radius: 4px; position: relative; } .filters_section_item .range_inner { height: inherit; background-color: #FD2016; } .filters_section_item .range_btn { width: 18px; height: 18px; border-radius: 50%; box-shadow: 0 0 3px rgba(0, 0, 0, 0.6); position: absolute; top: -7px; background-color: #fff; cursor: pointer; } .filters_section_item .range_inner { position: absolute; width: 100%; } .filters_section_item .range_btn[data-type=min-btn] { left: 0; } .filters_section_item .range_btn[data-type=max-btn] { left: 100%; } .filters_section_item .values { overflow: hidden; margin-top: 40px; } .filters_section_item .values .min-value { float: left; width: 35%; text-align: left; padding-bottom: 14px; padding-left: 10px; padding-right: 10px; border-bottom: 1px solid #ACACAC; } .filters_section_item .values .max-value { float: right; width: 35%; text-align: right; padding-bottom: 14px; padding-left: 10px; padding-right: 10px; border-bottom: 1px solid #ACACAC; }

  • 0 1000000

Подскажите алгоритм как рассчитывать теперь диапазон значений между ползунками при их перемещении?


Ответ

function Range(container) { this.container = container; if (!this.container) return; this.inputMin = container.querySelector('[data-type=input-min]'); this.inputMax = container.querySelector('[data-type=input-max]'); this.minValue = parseFloat(container.querySelector('[data-type=min-val]').textContent.replace(/\s/g, '')); this.maxValue = parseFloat(container.querySelector('[data-type=max-val]').textContent.replace(/\s/g, '')); this.inner = container.querySelector('[data-type=range-inner-element]'); this.valuesElem = container.querySelector('[data-type=range-element]'); this.minBtn = container.querySelector('[data-type=min-btn]'); this.maxBtn = container.querySelector('[data-type=max-btn]'); //console.log(this); this.init(); } Range.prototype.drag = function(event) { function move(event) { var left = event.pageX - elemX - boxX; var target; if (elem == this.minBtn) { this.inner.style.left = elem.offsetLeft + elem.offsetWidth / 2 + 'px'; if (left < 0) { left = 0; } if (left > this.maxBtn.offsetLeft - elem.offsetWidth) { left = this.maxBtn.offsetLeft - elem.offsetWidth; } target = this.container.querySelector('[data-type=min-val]'); } else if (elem == this.maxBtn) { this.inner.style.right = elem.offsetLeft - elem.offsetWidth / 2 + 'px'; if (left < this.minBtn.offsetLeft + elem.offsetWidth) { left = this.minBtn.offsetLeft + elem.offsetWidth; } if (left > this.valuesElem.offsetWidth - elem.offsetWidth) { left = this.valuesElem.offsetWidth - elem.offsetWidth; } target = this.container.querySelector('[data-type=max-val]'); } elem.style.left = left + 'px'; this.inner.style.width = this.maxBtn.offsetLeft - this.minBtn.offsetLeft + 'px'; target.innerText = this.minValue + (this.maxValue - this.minValue)*(left/this.valuesElem.offsetWidth); } function removeMove() { document.removeEventListener('mousemove', move); document.removeEventListener('mouseup', removeMove); } if (event.target == this.minBtn || event.target == this.maxBtn) { var elem = event.target; var elemX = event.pageX - elem.getBoundingClientRect().left; var boxX = this.valuesElem.getBoundingClientRect().left; var coord = event.target.offsetLeft; move = move.bind(this); document.addEventListener('mousemove', move); document.addEventListener('mouseup', removeMove); event.target.ondragstart = function() { return false; }; } } Range.prototype.setValue = function() { this.inputMin.value = this.minValue; this.inputMax.value = this.maxValue; } Range.prototype.init = function() { this.inner.style.left = this.minBtn.offsetLeft + this.minBtn.offsetWidth / 2 + 'px'; this.inner.style.right = this.maxBtn.offsetLeft - this.maxBtn.offsetWidth / 2 + 'px'; this.setValue(); this.valuesElem.addEventListener('mousedown', this.drag.bind(this)); } var range = new Range(document.querySelector('[data-type=range]')); .filters_section_list { width: 300px; list-style: none } .filters_section_item .range { height: 6px; background-color: #AEAEAE; border-radius: 4px; position: relative; } .filters_section_item .range_inner { height: inherit; background-color: #FD2016; } .filters_section_item .range_btn { width: 18px; height: 18px; border-radius: 50%; box-shadow: 0 0 3px rgba(0, 0, 0, 0.6); position: absolute; top: -7px; background-color: #fff; cursor: pointer; } .filters_section_item .range_inner { position: absolute; width: 100%; } .filters_section_item .range_btn[data-type=min-btn] { left: 0; } .filters_section_item .range_btn[data-type=max-btn] { left: 100%; } .filters_section_item .values { overflow: hidden; margin-top: 40px; } .filters_section_item .values .min-value { float: left; width: 35%; text-align: left; padding-bottom: 14px; padding-left: 10px; padding-right: 10px; border-bottom: 1px solid #ACACAC; } .filters_section_item .values .max-value { float: right; width: 35%; text-align: right; padding-bottom: 14px; padding-left: 10px; padding-right: 10px; border-bottom: 1px solid #ACACAC; }

  • 0 1000000

UP: Для тех, кто слишком давно учился в школе:
left // расстояние от минимального значения до текущего значения в пикселях. // Всё, что нам нужно сделать - это перевести его из пикселей в шкалу, заданную минимальным и максимальным значением - this.valuesElem.offsetWidth //размер шкалы в пикселях scale = maxValue - minValue; // размер шкалы в еденицах шкалы percent = left/offsetWidth // отношение отрезка значения к размеру шкалы (безразмерное, тк пиксели делим на пиксели - получаем разы) value = minValue + scale*percent; // осталось домножить эти разы на размер шкалы в нужных единицах и прибавить к значению, с которого шкала начинается. // Выкидываем лишние промежуточные переменные, получается - value = this.minValue + (this.maxValue - this.minValue)*(left/this.valuesElem.offsetWidth);

Комментариев нет:

Отправить комментарий