Получите 50% шестнадцатеричного значения цвета без использования прозрачности

Мне нужно получить значение цвета на 50% более светлой версии существующего шестнадцатеричного цвета. Однако он должен быть непрозрачным на 100%, я не могу использовать opacity, rgba, hexa или hsla.

Сценарий:

Я рисую маршруты на карте, каждый из которых имеет свой цвет, на основе жестко заданного массива из 48 возможных шестнадцатеричных значений.

Когда один из этих маршрутов редактируется, он должен отображаться как "отключенный" (50 % исходного цвета).

В дизайне экрана эталонными значениями были #9775fa для цвета маршрута (один из цветов в массиве) и #d5c7fd для отключенного цвета. Этот второй цвет был получен дизайнером путем нанесения белого слоя с непрозрачностью 50% поверх основного цвета.

Я попытался получить то же самое значение с помощью JS, сначала используя функцию осветления, затем функцию HSL и, наконец, осветляя вручную каждое из значений RGB основного цвета. Никто из них толком не работал.

Используя осветление, добавив 62 света, я получил близкое значение, но не точное. Использование HSL и осветление вручную на 50% тоже не сработало.

Это значения, которые у меня есть:

 Base color: #9775fa
 "Disabled color": #d5c7fd
 Lighten by 62: #d5b3ff
 HSL 50%: #e3b0ff
 Ligheting 50% by hand: #e3b0ff

Итак, в конце концов, реальный вопрос заключается в том, можно ли этого достичь?

Вот "игровая площадка" и полный код моих экспериментов ( второй столбец — это эталонный цвет "disabled".

Большое спасибо!


person Renato Rodrigues    schedule 30.04.2020    source источник
comment
Вы можете использовать SASS или LESS для рендеринга процента цвета, скажем, background: lighten(#ff0000, 50%);   -  person Nathaniel Flick    schedule 30.04.2020
comment
@NathanielFlick К сожалению, я не могу полагаться на CSS, мне нужно это значение для рендеринга всевозможных вещей во внешнем интерфейсе, самого маршрута (svg), маркеров остановки, заголовков всплывающих окон, оформления карточек и так далее.   -  person Renato Rodrigues    schedule 30.04.2020


Ответы (1)


Мне удалось получить более точные результаты, смешав цвет с белым в заданном процентном соотношении.

Я изменил lightenByPercentage следующим образом:

let p = percentage / 100;
var r = "0x" + hex[0] + hex[1];
var g = "0x" + hex[2] + hex[3];
var b = "0x" + hex[4] + hex[5];
r = Math.ceil(256 * (1-p) + (r * p));
g = Math.ceil(256 * (1-p) + (g * p));
b = Math.ceil(256 * (1-p) + (b * p));

r = r <= 255 ? r : 255;
g = g <= 255 ? g : 255;
b = b <= 255 ? b : 255;

Я не уверен, должен ли ваш процент быть светлым или темным, поэтому, если я ошибся, поменяйте местами p на 1-p здесь.

введите здесь описание изображения

person Bemmu    schedule 30.04.2020
comment
Насколько я понимаю, вы добавили X% белого поверх X% исходного цвета, в то время как я рассчитывал только X% исходного цвета. Чего я не понимаю, так это почему это сработало, но несмотря ни на что, сработало нормально! Большое спасибо! - person Renato Rodrigues; 30.04.2020
comment
Единственным моментом была ситуация с округлением в результирующем RGB моего контрольного цвета. Я ожидал 203, 187, 254, а получил 204, 187, 253, что переводится как #CCBBFD вместо #CBBBFE. Я попытался заменить Math.ceil на Math.round или Math.floor и получил аналогичные результаты. Но это настолько мало, что даже не считается. Спасибо еще раз! - person Renato Rodrigues; 30.04.2020
comment
@RenatoRodrigues Я только что подумал о том, что означает, что цвет должен быть прозрачным на белом фоне. Это означает, что он частично показывает этот цвет, частично белый фон. Итак, некоторая пропорция p — это белый фон, а некоторая пропорция 1-p — это цвет. - person Bemmu; 30.04.2020