Closed apcamargo closed 2 months ago
It's an interesting idea. It definitely has limited use cases, but I can see it being useful in Jupyter. So Jupyter specifically uses __repr_html__
visualize an object?
I guess you'd run into the issue of what gamut do we format the colors in...you'd need some class option to output in display-p3 if your monitor supports it. I guess sRGB would be the safe default.
I converted the color to OKLCH because, as far as I know, the browser takes care of converting it to a color that the monitor can display.
Regarding _repr_html_
, IPython has a number of methods for rich display: https://ipython.readthedocs.io/en/stable/config/integrating.html#rich-display
Yeah, you could let the browser gamut map out itself. Currently most just clip though which isn't great.
The cmap
library has a good example of rich representations: https://github.com/tlambert03/cmap/blob/c6a74dbcf29bddbebc3cc5f6cabc042863ec6c29/src/cmap/_colormap.py#L611-L652
Thanks for the example. Yeah, it's not a bad idea, and it doesn't hurt us to have it. Let me play around with it.
Something like this might work. We turn off gamut mapping for string output by default at let the browser do whatever it does. You can obviously gamut map it before output if you want, but this will preserve the current color values for text output as well.
It also has a background for when colors are transparent and a border when color is too similar to background on which the color is displayed on.
from coloraide import Color as Base
from IPython.display import display
class Color(Base):
def _repr_html_(self) -> str:
"""
Returns an HTML representation of the color as a colored square,
with the color's string representation displayed underneath.
"""
c = self.convert("oklab").to_string()
return f"""
<div style="text-align: center;">
<div style="width: 52px; height: 52px; background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' fill-opacity='0.1'><rect width='50' height='50' /><rect x='50' y='50' width='50' height='50' /></svg>")
0 0 / 0.5em 0.5em #fefefe; margin: 0 auto;"><div style="width: 50px; height: 50px; background-color: {c}; border: 2px ridge hsl(0, 0%, 85%);"></div></div>
<div>{self.to_string(fit=False)}</div>
</div>
"""
display(Color('color(srgb 1 0 0 / 0.5)'))
display(Color('color(srgb 0 0 1 / 0.75)'))
display(Color('color(srgb 0 1 0 / 1)'))
I just found out about https://github.com/w3c/csswg-drafts/issues/9449. I wasn't really aware of this issue.
I think this looks good! I had forgotten about the transparency grid.
Personally, I'm not a big fan of ridge borders. But that's minor
Open to suggestions, we could do some kind of double border. I was more looking for something where the border stood out on light and dark backgrounds.
Yeah, we'll go with a double border:
Much better! Thanks for working on this so quickly :)
Much better! Thanks for working on this so quickly :)
Yeah, I'm not particularly fond of ridge either, but I also threw it together pretty quickly :).
I just found out about https://github.com/w3c/csswg-drafts/issues/9449. I wasn't really aware of this issue.
Yeah, they are still trying to figure out how browsers will gamut map things. Basically what it boils down is CSS offers a proposal to gamut map and preserve lightness in a perceptual color space, which has many uses, but admittedly, it is not as good for image gamut mapping etc. Preserving chroma can be quite desirable with images. Some browsers want one GMA to rule them all, but supporting preserving chroma with GMA and preserving lightness with GMA are at odds with each other and have different use cases. There are also a lot of opinions on a great number of little details as well. I think Chrome is pushing hard to have some kind of baked in logic for each supported gamut while CSS has a generic (and slow) algorithm. Nobody has been super clear on what the criteria should be, so now it seems all the browsers are waiting to see what Chrome resolves with the CSS WG. Who knows what the final solution will look like.
There a lot of other opinions out there too about a great number of things.
Thanks for the explanation!
When working with colors in a Jupyter notebook (or Quarto), it can be helpful to visualize the colors directly. While there are several ways to do this, having this functionality built into
coloraid
via a_repr_html_
method would be very convenient.Although this feature might fall outside the intended scope of the library, here’s a quick example I wrote:
This is just a quick implementation, and I’m sure there are a number of ways it could be improved.