Задать заданный c градиент от процентов - PullRequest
0 голосов
/ 03 марта 2020

У меня есть код, который генерирует цвет из значений (от 0 до 200%)

На самом деле спектр - зеленый-желтый-красный.

Я хотел бы изменить градиент на зеленый -Серый-красный: зеленый, если процент <100%, серый, если в поле 100%, красный, если> 100%.

Я не понимаю, как это сделать с помощью математической формулы.

window.onload = function() {
  let colorShower = document.querySelector('.color-shower')
  let colorSlider = document.querySelector('#colorSlider')

  let percentage = (200 -colorSlider.value) /2
  let buildColor = (capHue) => `hsl(${capHue},90%,60%)`
    
  colorShower.style.backgroundColor = buildColor(percentage)
  
  colorSlider.addEventListener('input', e => {
    percentage = (200 -colorSlider.value) /2
    colorShower.style.backgroundColor = buildColor(percentage)
  })
}
.color-shower {
  width: 100%;
  height: 50px;
}

.color-slider {
  width: 100%;
}
<div class = "color-shower"></div>
<input type = "range" min = "1" max = "200" value = "1" class = "color-slider" id = "colorSlider">

Ответы [ 2 ]

1 голос
/ 03 марта 2020

Редактировать: ОК, я обновил свой ответ с помощью динамического c решения. Я создал элементы оболочки <div> вокруг элементов отображения / ввода. Эти оболочки позволяют вам определять атрибуты данных start-hue и end-hue. Они используются в качестве начала / конца градиента для дисплея.

Это легко пропустить (так как вы должны прокрутить весь путь до конца), но с плагином ниже; Вы можете вызвать GradientSlider() после загрузки вашей страницы.

Свойства по умолчанию "stati c" находятся внизу определения функции. Это можно легко переписать в класс ES5 / 6.

GradientSlider.defaultOptions = {
  selector : '.gradient-slider'
};

Ниже представлены различные ползунки. Я позаимствовал трюк Infodev с абсолютным значением, чтобы настроить значение насыщенности при приближении ползунка к 50%.

function GradientSlider(options) {
  let opts = Object.assign({}, GradientSlider.defaultOptions, options);

  construct(opts.selector); // Begin...

  function construct(selector) {
    Array.from(document.querySelectorAll(selector))
      .forEach(gradientSlider => initializeSlider(gradientSlider));
  }

  function initializeSlider(gradientSlider) {
    let hueStart = parseInt(gradientSlider.getAttribute('data-start-hue'), 10);
    let hueEnd = parseInt(gradientSlider.getAttribute('data-end-hue'), 10);
    let display = gradientSlider.querySelector('.gradient-slider-display');
    let slider = gradientSlider.querySelector('.gradient-slider-input');
    slider.addEventListener('input', onSliderChange);

    let percentage = getSliderPercentage(slider);
    let hue = percentage < 50 ? hueStart : hueEnd;
    display.style.backgroundColor = calculateColor(hue, percentage);
  }

  function onSliderChange(e) {
    let gradientSlider = e.target.parentElement;
    let hueStart = parseInt(gradientSlider.getAttribute('data-start-hue'), 10);
    let hueEnd = parseInt(gradientSlider.getAttribute('data-end-hue'), 10);
    let display = gradientSlider.querySelector('.gradient-slider-display');
    let percentage = getSliderPercentage(e.target);
    let hue = percentage < 50 ? hueStart : hueEnd;
    display.style.backgroundColor = calculateColor(hue, percentage)
  }

  function calculateColor(hue, percentage) {
    return `hsl(${hue}, ${Math.abs(50 - percentage)}%, 50%)`;
  }

  function getSliderPercentage(slider) {
    let value = parseInt(slider.value, 10);
    let minValue = parseInt(slider.getAttribute('min'), 10);
    let maxValue = parseInt(slider.getAttribute('max'), 10);
    return scaleBetween(value, 0, 100, minValue, maxValue);
  }

  // Source: https://stackoverflow.com/a/60514474/1762224
  function scaleBetween(n, tMin, tMax, sMin, sMax) {
    return (tMax - tMin) * (n - sMin) / (sMax - sMin) + tMin;
  }
}

GradientSlider.defaultOptions = {
  selector : '.gradient-slider'
};

GradientSlider(); // Call the plugin...
.gradient-slider,
.gradient-slider > .gradient-slider-display,
.gradient-slider > .gradient-slider-input {
  width: 100%;
}
.gradient-slider-display {
  height: 50px;
}
<div class="gradient-slider" data-start-hue="120" data-end-hue="0">
  <div class="gradient-slider-display"></div>
  <input class="gradient-slider-input" type="range" min="1" max="200" value="1" />
</div>

<div class="gradient-slider" data-start-hue="240" data-end-hue="300">
  <div class="gradient-slider-display"></div>
  <input class="gradient-slider-input" type="range" min="50" max="150" value="75" />
</div>

<div class="gradient-slider" data-start-hue="30" data-end-hue="180">
  <div class="gradient-slider-display"></div>
  <input class="gradient-slider-input" type="range" min="0" max="10" value="7" />
</div>
1 голос
/ 03 марта 2020

Я нашел решение, но оно не идеально

Используя эту формулу hsl(${hue}, ${Math.abs(100 - perc)}%, 50%);

window.onload = function() {
  let colorShower = document.querySelector('.color-shower')
  let colorSlider = document.querySelector('#colorSlider')

  let percentage = (200 -colorSlider.value) /2
  let buildColor = (capHue) => `hsl(${capHue}, ${Math.abs(100 - colorSlider.value)}%, 50%)`
    
  colorShower.style.backgroundColor = buildColor(percentage)
  
  colorSlider.addEventListener('input', e => {
    percentage = (200 -colorSlider.value) /2
    colorShower.style.backgroundColor = buildColor(percentage)
  })
}
.color-shower {
  width: 100%;
  height: 50px;
}

.color-slider {
  width: 100%;
}
<div class = "color-shower"></div>
<input type = "range" min = "1" max = "200" value = "1" class = "color-slider" id = "colorSlider">

Но у меня все еще есть немного апельсина.

...