Страницы

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

суббота, 7 декабря 2019 г.

Плавная анимация цвета при прокрутке

#javascript #jquery #анимация


Здравствуйте!

Задача состоит в том, что бы при прокрутке страницы плавно менялся цвет фона.
Пояснение: 
Есть два цвета ( к примеру rgb(0, 0, 0) и rgb(255, 255, 255) ). Я в коде указываю
позиции scroll'а 0px и 100px. И теперь, нужно, что бы скрипт, по мере прокрутки, плавно
превращал rgb(0, 0, 0) в rgb(255, 255, 255), т.е. если я прокрутил scroll на позицию
50px цвет у фона был rgb(122, 122, 122).

Я попытался это решить способом процентов, но это же будет работать только с цветами
rgb, а как же hex и другие? И вообще оно странно меняет цвета, если там указаны цветные
варианты (красный, жёлтый, синий...)

Код:



var scroll = function(element, style, positions, value) {
  window.onscroll = function() {
    var scrollTop = window.pageYOffset,
        // Высчитываю процент того, на сколько нужно изменить цвет
        pct = (window.pageYOffset - positions[0]) / positions[1],
        colorsVal = [],
        currentColor = [];
    // Проверяю, не выходит ли scroll за рамки
    if(window.pageYOffset <= positions[1] && window.pageYOffset >= positions[0]){
      // Превращаю значение цветов в массив
      colorsVal[0] = value[0].split(',');
      colorsVal[1] = value[1].split(',');
      for(var i = 0; i < colorsVal[0].length; i++){
        // Проверяю, какое значение цвета больше
        if(colorsVal[0][i] < colorsVal[1][i]){
          // Высчитываю текущее значение цвета
          var val = ((colorsVal[1][i] - colorsVal[0][i]) * pct) + colorsVal[0][i];
          // Устанавливаю текущее значение цвета
          currentColor[i] = Math.round(val);
        }else{
          // Высчитываю текущее значение цвета
          var val = ((colorsVal[0][i] - colorsVal[1][i]) * pct) + colorsVal[1][i];
          // Устанавливаю текущее значение цвета
          currentColor[i] = Math.round(val);
        };
      };
      // Применяю цвет фона к элементу
      element.style[style] = 'rgb(' + currentColor.join(',') + ')';
    };
  };
};

(function() {
  var obj = document.querySelector('.obj');
  scroll(obj, 'background-color', [0, 100], ['0,0,0', '255,255,255']);
})();
body {height: 2000px; background-color: #eee}
div {
  position: fixed;
  width: 100px;
  height: 100px;
  background-color: black;
}
Как можно улучшить эту функцию и сделать более универсальной, что бы можно было указывать значение цвета 'black' и hex цвета? Или у кого есть вариант получше моего? Заранее спасибо.


Ответы

Ответ 1



Первое, что необходимо сделать — это убрать для удобства цвет из CSS и задавать его уже непосредственно в функции scroll при её инициализации. Далее я вызвал функцию scroll с параметром positions [0, 1000], чтобы можно было нормально рассмотреть переход и у меня возникала проблема при каждом втором скролле. Проблема была в том, что массив colorsVal заполнялся не числами, а строками, и там, где происходит вычисление val = ((colorsVal[1][i] - colorsVal[0][i]) * pct) +colorsVal[0][i] (проблемное место выделено жирным) ноль прибавляется как строка и получается зашкаливающее значение в rgb. Решением является приведение к типу Number во время формирования массива: colorsVal[0] = value[0].split(',').map(Number), colorsVal[1] = value[1].split(',').map(Number); После этого пример от меньших значений rgb к большим работает. Дальше возникли проблемы с переходом от больших значений к меньшим. Для решения этой проблемы пришлось немного изменить формулу расчета с val = ((colorsVal[0][i] - colorsVal[1][i]) * pct) + colorsVal[1][i]; на val = colorsVal[0][i] - ((colorsVal[0][i] - colorsVal[1][i]) * pct); var scroll = function(element, style, positions, value) { // Превращаю значение цветов в массив var colorsVal = [], val; colorsVal[0] = value[0].split(',').map(Number), colorsVal[1] = value[1].split(',').map(Number); element.style[style] = 'rgb(' + colorsVal[0].join(',') + ')'; window.onscroll = function() { var scrollTop = window.pageYOffset, // Высчитываю процент того, на сколько нужно изменить цвет pct = (window.pageYOffset - positions[0]) / positions[1], currentColor = []; // Проверяю, не выходит ли scroll за рамки if(window.pageYOffset <= positions[1] && window.pageYOffset >= positions[0]){ for(var i = 0; i < colorsVal[0].length; i++) { // Проверяю, какое значение цвета больше if(colorsVal[0][i] < colorsVal[1][i]){ // Высчитываю текущее значение цвета val = ((colorsVal[1][i] - colorsVal[0][i]) * pct) + colorsVal[0][i]; // Устанавливаю текущее значение цвета currentColor[i] = Math.round(val); }else{ // Высчитываю текущее значение цвета val = colorsVal[0][i] - ((colorsVal[0][i] - colorsVal[1][i]) * pct); // Устанавливаю текущее значение цвета currentColor[i] = Math.round(val); }; }; // Применяю цвет фона к элементу element.style[style] = 'rgb(' + currentColor.join(',') + ')'; }; }; }; (function() { var obj = document.querySelector('.obj'); scroll(obj, 'background-color', [0, 1000], ['0,0,0', '255,255,255']); })(); body {height: 2000px; background-color: #eee} div { position: fixed; width: 100px; height: 100px; }
console.clear(); var scroll = function(element, style, positions, value) { // Превращаю значение цветов в массив var colorsVal = [], val; colorsVal[0] = value[0].split(',').map(Number), colorsVal[1] = value[1].split(',').map(Number); element.style[style] = 'rgb(' + colorsVal[0].join(',') + ')'; window.onscroll = function() { var scrollTop = window.pageYOffset, // Высчитываю процент того, на сколько нужно изменить цвет pct = (window.pageYOffset - positions[0]) / positions[1], currentColor = []; // Проверяю, не выходит ли scroll за рамки if(window.pageYOffset <= positions[1] && window.pageYOffset >= positions[0]){ for(var i = 0; i < colorsVal[0].length; i++) { // Проверяю, какое значение цвета больше if(colorsVal[0][i] < colorsVal[1][i]){ // Высчитываю текущее значение цвета val = ((colorsVal[1][i] - colorsVal[0][i]) * pct) + colorsVal[0][i]; // Устанавливаю текущее значение цвета currentColor[i] = Math.round(val); }else{ // Высчитываю текущее значение цвета val = colorsVal[0][i] - ((colorsVal[0][i] - colorsVal[1][i]) * pct); // Устанавливаю текущее значение цвета currentColor[i] = Math.round(val); }; }; // Применяю цвет фона к элементу element.style[style] = 'rgb(' + currentColor.join(',') + ')'; }; }; }; (function() { var obj = document.querySelector('.obj'); scroll(obj, 'background-color', [0, 1000], ['0,245,0', '255,0,0']); })(); body {height: 2000px; background-color: #eee} div { position: fixed; width: 100px; height: 100px; }


Ответ 2



Можешь тот же hex конвертировать в rgb. var hex = document.querySelector('input'), btn = document.querySelector('button'), rgbBlock = document.querySelector('.rgb'), hexval; btn.addEventListener('click', function() { hexval = hex.value; rgbBlock.innerHTML = hexToRgbA(hexval); }); function hexToRgbA(hex) { var c; if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) { c = hex.substring(1).split(''); if (c.length == 3) { c = [c[0], c[0], c[1], c[1], c[2], c[2]]; } c = '0x' + c.join(''); return 'rgba(' + [(c >> 16) & 255, (c >> 8) & 255, c & 255] + ')'; } throw new Error('не Hex'); }


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

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