3

I need to obtain the color value of a 50% lighter version of an existing color hex. However it has to be 100% opaque, I cannot use opacity, rgba, hexa or hsla.

The scenario:

I draw routes on a map, each one with a different color, based on a hardcoded array of 48 possible hex values.

When one of these routes is being edited it should be shown as "disabled" (50% of the original color).

In the screen design, the reference values were #9775fa for the route color (one of the colors in the array) and #d5c7fd for the disabled color. This second color was obtained by the designer drawing a white layer with 50% opacity on top of the base color.

I tried to obtain this same value via JS, first using a lighten function, then an HSL one and finally lightening manually each of the RGB values of the base color. None of them really worked.

Using lighten, adding 62 of light I got a near value, but not the exact one. Using HSL and lightening manually with 50% didn't work either.

These are the values I've got:

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

So, by the end, the real question is, Is it possible to be achieved?

Here is a "playground" and the full code of my experiments (the second column is the reference "disabled" color.

Thanks a lot!

Renato Rodrigues
  • 165
  • 1
  • 10
  • You can use SASS or LESS to render a colour percentage, say background: lighten(#ff0000, 50%); – Nathaniel Flick Apr 30 '20 at 02:24
  • @NathanielFlick Unfortunately I can't rely on CSS, I need this value to render all sorts of things on the frontend, the route itself (svg), stop markers, popup headers, cards decoration, on so on. – Renato Rodrigues Apr 30 '20 at 13:43

1 Answers1

3

I managed to get more accurate results by mixing the color with white at your given percentage.

I changed lightenByPercentage as follows:

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;

I'm not sure if your percentage was supposed to be how light it is or how dark it is, so if I got it the wrong way around swap p with 1-p here.

enter image description here

Bemmu
  • 17,849
  • 16
  • 76
  • 93
  • I understand that you've added X% of white on top of X% of the original color, while I was calculating only X% of the original color. What I don't understand is why it worked, but no matter what, it worked fine! Many thanks! – Renato Rodrigues Apr 30 '20 at 13:49
  • The only "thing" was a rounding situation in the resulting RGB of my control color. I was expecting 203, 187, 254, and got 204, 187, 253, what translated to #CCBBFD instead of #CBBBFE. I tried replacing Math.ceil by Math.round or Math.floor and got similar results. But it's so small that it doesn't even count. Thanks again! – Renato Rodrigues Apr 30 '20 at 13:56
  • 1
    @RenatoRodrigues I just thought about what it means for the color to be transparent against a white background. It means that it partially shows that color, partially the white background. So some proportion p is white background, and some proportion 1-p is the color. – Bemmu Apr 30 '20 at 17:48