Welcome to the RGB2HEX converter that got out of hand.
Here is something that always bothered me when working on designs coming in from
Photoshop and Illustrator: designers, especially those with a print background,
would share designs where colors were blended with some opacity over some background.
I would often need to sample the design to get the end result so I could use it.
And yeah, designer, I can hear you cringe, but hear me out: I am not flattening real
blends. I mean the lazy case, where someone over a white canvas just nudged a swatch's
opacity to lighten it, so the transparency was an accident of the artboard and not the
intent. When the end result is a fixed solid color, why make the poor browser blend it
at runtime when an opaque value does the exact same thing?
Enter: HexBlender 🤓
In the first version I tried to automate the color-sampling process with canvas:
draw the background, draw the rgba color on top, then read the blended pixel back
with getImageData(). It kinda worked, but once transparency gets involved,
the browser has already done some internal alpha math, and reading the pixel back can
introduce tiny differences. The HTML spec says that converting between premultiplied
and non-premultiplied alpha is a lossy operation
for colors that are not fully
opaque. Rude, but fair.
So, as often happens, I tracked back from the original concept and rebuilt the tool
with a direct calculation and no canvas. Sorry buddy, maybe next time.
If you’ve read this far, here is what I went with:
R = round(fgR × a + bgR × (1 - a))
G = round(fgG × a + bgG × (1 - a))
B = round(fgB × a + bgB × (1 - a))
Fun fact: that flattened swatch is really blended by the browser, live, while the hex
beneath it is calculated straight from the formula above and never read back from a
pixel. Don't trust it? Click the swatch. It repaints itself with the calculated solid
color in place of the live blend, and if the math is honest nothing visibly happens:
no flinch, no seam. Click again to flip back. No canvas, no sampling, no lossy round trip.
So, to answer the “what’s going on here?” question from the title: this is probably
the best RGB2HEX converter out there, because you can paste into it, and you do not
need to type RGB values into three separate fields like the competition makes you do.
And also, if you are worthy, it is a blending tool that helps you find the result of
an alpha-transparent color over selected opaque backgrounds.
Yep.