Здравствуйте!
Задача состоит в том, что бы при прокрутке страницы плавно менялся цвет фона.
Пояснение:
Есть два цвета ( к примеру 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;
}
<div class="obj"></div>
Как можно улучшить эту функцию и сделать более универсальной, что бы можно было указывать значение цвета 'black' и hex цвета? Или у кого есть вариант получше моего?
Заранее спасибо.
Первое, что необходимо сделать — это убрать для удобства цвет из 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;
}
<div class="obj"></div>
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;
}
<div class="obj"></div>
Можешь тот же 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');
}
<input type="text" />
<button>convert</button>
<div class="rgb"></div>
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Добрый день уважаемыеСтолкнулся с не пониманием почему JS возвращает значения RGB каналов хотя в CSS задаю под HSL
Пытаюсь написать модальное окно на React Js, чтоб оно появлялось сразу после загрузки страницыПроверка как в нативном JS через window
[ Здравствуйте,есть вопрос,как можно перенести последний блок в начало,при нехватке места,чтобы в начало попал только тот кусок,который не влез,а...