skip to Main Content

I am struggling with the calculation that is responsible for the fill color between the 2 dots in the range price-slider.

Part of the html for the range slider is:

 <div class="values">
    <span id="range1">0</span>
    <span> &dash; </span>
    <span id="range2">100</span>
 </div>
 <div class="container">
    <div class="slider-track"></div>
    <input type="range" min="0" max="80" value="50" id="slider-1" oninput="slideOne()">
    <input type="range" min="0" max="80" value="70" id="slider-2" oninput="slideTwo()">
  </div>

The js:

window.onload = function () {
  slideOne();
  slideTwo();
};

let sliderOne = document.getElementById("slider-1");
let sliderTwo = document.getElementById("slider-2");
let displayValOne = document.getElementById("range1");
let displayValTwo = document.getElementById("range2");
let minGap = 5;
let sliderTrack = document.querySelector(".slider-track");
let sliderMaxValue = document.getElementById("slider-1").max;

function slideOne() {
  if (parseInt(sliderTwo.value) - parseInt(sliderOne.value) <= minGap) {
    sliderOne.value = parseInt(sliderTwo.value) - minGap;
  }
  displayValOne.textContent = sliderOne.value;
  fillColor();
}
function slideTwo() {
  if (parseInt(sliderTwo.value) - parseInt(sliderOne.value) <= minGap) {
    sliderTwo.value = parseInt(sliderOne.value) + minGap;
  }
  displayValTwo.textContent = sliderTwo.value;
  fillColor();
}
function fillColor() {
   percent1 = (sliderOne.value / sliderMaxValue) * 100;
   percent2 = (sliderTwo.value / sliderMaxValue) * 100;
   sliderTrack.style.background = `linear-gradient(to right, #dadae5 ${percent1}% , #3264fe ${percent1}% , #3264fe ${percent2}%, #dadae5 ${percent2}%)`;
}

When the input values in the html have value "0" (min="0"), everything works fine with the fill-color inbetween the dots. But when is set both input to min="40" per example,
the percent1 and percent2 variables in the js need to be recalculated. Otherwise the fillcolor between the dots in not correct anymore.

So: what what is the correct calculation for percent1 and percent2 in the js in case min="20" or min="40" in the html input?

Example 1 with min="0": Fiddle 1

Example 2 with min="40": Fiddle 2

2

Answers


  1. If I understand correctly, you’re wanting to interopolate between two values? It sounds like you’re describing "linear interpolation".

    newValue = valueA + (valueB - valueA) * t

    Where ‘t’ ranges from 0 to 1.

    So if your lowest value is 40 and the max value is 100 then at 50% (0.5) you’ll get 70.

    Login or Signup to reply.
  2. Calculations, as already mentioned, should use a range of possible values (max - min) instead of just using the maximum (max - 0).

    On top of that, both sliders must have the same minimum value. Otherwise, the overall appearance and behavior will be inconsistent.

    window.onload = function() {
      slideOne();
      slideTwo();
    };
    
    const sliderOne = document.getElementById("slider-1");
    const sliderTwo = document.getElementById("slider-2");
    const displayValOne = document.getElementById("range1");
    const displayValTwo = document.getElementById("range2");
    const minGap = 5;
    const sliderTrack = document.querySelector(".slider-track");
    const sliderMaxValue = sliderOne.max;
    const sliderMinValue = sliderOne.min;
    const sliderValueRange = (sliderMaxValue - sliderMinValue);
    
    function slideOne() {
      if (parseInt(sliderTwo.value) - parseInt(sliderOne.value) <= minGap) {
        sliderOne.value = parseInt(sliderTwo.value) - minGap;
      }
      displayValOne.textContent = sliderOne.value;
      fillColor();
    }
    
    function slideTwo() {
      if (parseInt(sliderTwo.value) - parseInt(sliderOne.value) <= minGap) {
        sliderTwo.value = parseInt(sliderOne.value) + minGap;
      }
      displayValTwo.textContent = sliderTwo.value;
      fillColor();
    }
    
    function fillColor() {
      const percent1 = (sliderOne.value - sliderMinValue) / sliderValueRange * 100;
      const percent2 = (sliderTwo.value - sliderMinValue) / sliderValueRange * 100;
      sliderTrack.style.background = `linear-gradient(to right, #dadae5 ${percent1}% , #3264fe ${percent1}% , #3264fe ${percent2}%, #dadae5 ${percent2}%)`;
    }
    .container {
      position: relative;
      width: 100%;
      height: 100px;
      margin-top: 30px;
    }
    
    input[type="range"] {
      -webkit-appearance: none;
      -moz-appearance: none;
      appearance: none;
      width: 100%;
      outline: none;
      position: absolute;
      margin: auto;
      top: 0;
      bottom: 0;
      background-color: transparent;
      pointer-events: none;
    }
    
    .slider-track {
      width: 100%;
      height: 5px;
      position: absolute;
      margin: auto;
      top: 0;
      bottom: 0;
      border-radius: 5px;
    }
    
    input[type="range"]::-webkit-slider-runnable-track {
      -webkit-appearance: none;
      height: 5px;
    }
    
    input[type="range"]::-moz-range-track {
      -moz-appearance: none;
      height: 5px;
    }
    
    input[type="range"]::-ms-track {
      appearance: none;
      height: 5px;
    }
    
    input[type="range"]::-webkit-slider-thumb {
      -webkit-appearance: none;
      height: 1.7em;
      width: 1.7em;
      background-color: #3264fe;
      cursor: pointer;
      margin-top: -9px;
      pointer-events: auto;
      border-radius: 50%;
    }
    
    input[type="range"]::-moz-range-thumb {
      -webkit-appearance: none;
      height: 1.7em;
      width: 1.7em;
      cursor: pointer;
      border-radius: 50%;
      background-color: #3264fe;
      pointer-events: auto;
      border: none;
    }
    
    input[type="range"]::-ms-thumb {
      appearance: none;
      height: 1.7em;
      width: 1.7em;
      cursor: pointer;
      border-radius: 50%;
      background-color: #3264fe;
      pointer-events: auto;
    }
    
    input[type="range"]:active::-webkit-slider-thumb {
      background-color: #ffffff;
      border: 1px solid #3264fe;
    }
    
    .values {
      background-color: #3264fe;
      width: 32%;
      position: relative;
      margin: auto;
      padding: 10px 0;
      border-radius: 5px;
      text-align: center;
      font-weight: 500;
      font-size: 25px;
      color: #ffffff;
    }
    
    .values:before {
      content: "";
      position: absolute;
      height: 0;
      width: 0;
      border-top: 15px solid #3264fe;
      border-left: 15px solid transparent;
      border-right: 15px solid transparent;
      margin: auto;
      bottom: -14px;
      left: 0;
      right: 0;
    }
    <div class="values">
      <span id="range1">0</span>
      <span> &dash; </span>
      <span id="range2">100</span>
    </div>
    <div class="container">
      <div class="slider-track"></div>
      <input type="range" min="40" max="80" value="50" id="slider-1" oninput="slideOne()">
      <input type="range" min="40" max="80" value="70" id="slider-2" oninput="slideTwo()">
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search