Страницы

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

воскресенье, 8 декабря 2019 г.

Вычисление цвета по уровню пользователя

#javascript #css


Суть такая. Пользователь со временем получает опыт, пользуясь сайтом. Цвет прогресс
бара меняется с уровнем пользователя. Цвет можно задать либо HEX, либо RGB кодом, но
я запутался. Я уверен, что подобное можно выразить какой-либо математической формулой,
но, видимо, я плохо учил математику. 

Уровни идут как очередность чисел: от 1 до бесконечности. Это единственный известный
параметр в формуле. Нужно выразить его так, чтобы цвет менялся от одного цвета к другому
крайне плавно. То есть если прежний цвет был (0, 0, 5), то следующий уровень изменит
его до (0, 0, 6). Но это еще не все. Чтобы избежать черного и белого цветов, я думаю,
правильнее будет сделать переход от синего в зеленый, а оттуда в красный. А если цвета
закончатся, то пойдут по новой.

Значит, начало в (0, 0, 255), затем зеленый (0, 255, 0), потом красный (255, 0, 0).
Но очередная загвоздка в том, что между каждой парой цветов будет так называемый промежуточный
цвет. Например, между синим и зеленым будет (0, 255, 255). После чего синий начнет
падать в 0.

За последние 3 часа я голову хорошо поломал, исписав листик в совершенно нелогичных
догадках о том что нужно сделать. Возможно, кто-то имел дело с подобным и покажет примеры?
Или хотя бы подсказки как это сделать в теории?
    


Ответы

Ответ 1



Что при таких условиях получается с цветами: lvl r g b 0 0 0 255 1 0 1 255 254 0 254 255 255 0 255 255 256 0 255 254 509 0 255 1 510 0 255 0 511 1 255 0 764 254 255 0 765 255 255 0 766 255 254 0 1019 255 1 0 1020 255 0 0 1021 255 0 1 1274 255 0 254 1275 255 0 255 1276 254 0 255 1529 1 0 255 1530 0 0 255 В итоге цикл - 1530 уровней (итераций). Соответственно, для вычисления значений цветов достаточно брать level % 1530. Решение "в лоб": var colorBlock = document.getElementById("color"); var level = 0; setInterval(function() { var levelBase = level % 1530; var red = 0; if (levelBase >= 511 && levelBase <= 765) red = levelBase - 510; else if (levelBase >= 766 && levelBase <= 1275) red = 255; else if (levelBase >= 1276 && levelBase <= 1529) red = 1530 - levelBase; var green = 0; if (levelBase <= 255) green = levelBase; else if (levelBase <= 765) green = 255; else if (levelBase <= 1020) green = 1020 - levelBase; var blue = 0; if (levelBase <= 255 || levelBase >= 1276) blue = 255; else if (levelBase <= 510) blue = 510 - levelBase; else if (levelBase >= 1021 && levelBase <= 1275) blue = levelBase - 1020; colorBlock.style.backgroundColor = "rgb(" + red + "," + green + "," + blue + ")"; colorBlock.innerText = level + " " + red + " " + green + " " + blue; level++; }, 10); #color { width: 200px; height: 200px; }
Можно уменьшить количество строк кода с 34 до 24, вынеся логику определения значения цвета по levelBase в отдельную функцию: var colorBlock = document.getElementById("color"); var level = 0; setInterval(function() { var levelBase = level % 1530; var red = getColorValue(levelBase, [511, 764], [1276, 1530], [765, 1275]); var green = getColorValue(levelBase, [1, 254], [766, 1020], [255, 765]); var blue = getColorValue(levelBase, [1021, 1274], [256, 510], [0, 255], [1275, 1529]); colorBlock.style.backgroundColor = "rgb(" + red + "," + green + "," + blue + ")"; colorBlock.innerText = level + " " + red + " " + green + " " + blue; level++; }, 10); function getColorValue(levelBase, incRange, decRange, maxValueRange, maxValueRange2) { if (levelBase >= incRange[0] && levelBase <= incRange[1]) return levelBase - incRange[0]; if (levelBase >= decRange[0] && levelBase <= decRange[1]) return decRange[1] - levelBase; if (levelBase >= maxValueRange[0] && levelBase <= maxValueRange[1]) return 255; if (maxValueRange2 != null && levelBase >= maxValueRange2[0] && levelBase <= maxValueRange2[1]) return 255; return 0; } #color { width: 200px; height: 200px; }
Искусственное "выравнивание" цветов снижает количество строк с 24 до 19, плюсом укоротив некоторые строки кода: var colorBlock = document.getElementById("color"); var level = 0; setInterval(function() { var red = getColorValue((level + 1020) % 1530); var green = getColorValue(level % 1530); var blue = getColorValue((level + 510) % 1530); colorBlock.style.backgroundColor = "rgb(" + red + "," + green + "," + blue + ")"; colorBlock.innerText = level + " " + red + " " + green + " " + blue; level++; }, 10); function getColorValue(levelBase) { if (levelBase <= 254) return levelBase; if (levelBase <= 765) return 255; return levelBase <= 1020 ? 1020 - levelBase : 0; } #color { width: 200px; height: 200px; }


Ответ 2



Можете воспользоваться hsl - первый параметр отвечает за цвет. Правда, я не знаю, как вы представляете себе бесконечное отображение... Ведь цветов то ограниченное количество. Но можно представить что-то типа такого. function setColorLevels() { for (var i = 0; i < 1000; i++) { var elem = document.createElement('div'); elem.style.backgroundColor = `hsl(${360-i*4-110},100%,50%)`; elem.innerText = `level ${i}`; content.appendChild(elem); } } setColorLevels();

Ответ 3



Можно использовать hsl-цвета let getTemperatureColor = (value) => ['hsl(', value, ',100%,50%)'].join(''); for (let i = 240; i >= 0; i--) { var d = document.createElement('div'); d.style.backgroundColor = getTemperatureColor(i); document.body.appendChild(d); } div { width: 2px; height: 20px; float: left; } Если поддерживаемые браузеры позволяют шаблонные строки, то можно упросить еще сильнее. for (let i = 240; i >= 0; i--) { var d = document.createElement('div'); d.style.backgroundColor = `hsl(${i}, 100%,50%)`; document.body.appendChild(d); } div { width: 2px; height: 20px; float: left; } Вариант с таймером: let getTemperatureColor = (value) => ['hsl(', value, ',100%,50%)'].join(''); let i = 240; setInterval(function() { i--; document.getElementById('status').style.backgroundColor = getTemperatureColor(i); }, 25); div { width: 50px; height: 50px; }


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

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