linebender / druid

A data-first Rust-native UI design toolkit.
https://linebender.org/druid/
Apache License 2.0
9.49k stars 566 forks source link

Color methods #1552

Open arthmis opened 3 years ago

arthmis commented 3 years ago

This is probably not something that can happen soon, but I think it would be nice to have some methods to manipulate the color in the Color enum. It would be nice to increase or decrease the saturation of a color, change its exposure, its lightness or even shift the hue. That way when you define styles in the future or anything, you can specify a base color and change the lightness to represent different states, like hover, active etc.

Let me know if this should be opened in Piet instead.

raphlinus commented 3 years ago

I like the idea of this, but what are the "right" color methods? When manipulating color saturation, what color space should that be done in? There's a bit of CIELAB-based stuff already in Piet, but as I've recently blogged, it's possible to do quite a bit better, with either IPT or Oklab. How should this handle colors going out of gamut after transformation?

It's also not super clear whether this should be in Piet or Druid. For things that represent fundamental truths about color, Piet definitely belongs. Also, if we up our gradient game to be more perceptually uniform, that also belongs in Piet. But if we're talking about helper methods to create color palettes for a specific application (visual indications of state in a UI), that makes sense in Druid.

Expect discussion to be subject to bikeshedding; there aren't obviously right answers to these questions, and it does come down literally to what color to paint the bikeshed.

arthmis commented 3 years ago

Yes all those questions, which some I'm not informed on, are why I thought this was something that would take a lot of time and consideration. What I'm thinking about is more along the lines of creating color palettes for the application.

However, I also thought it would be nice to generate gradients and even do transformations, like increasing and decreasing contrast within a gradient. So, I think this issue might be applicable to both Piet and Druid. For now I want methods like:

// I don't know if luminosity is the appropriate term
fn lightness(luminosity: f64);
fn saturation(saturation: f64);
// I don't know if this fn makes sense
// people who know about color theory will have to inform me
fn hue_shift(amount: f64);

This was the general idea I'm going for. All of this subject to change. Like I said before, this is more about making it easier to work with the color palette within an application. I'm not a ux/color palette designer by any means. I don't know the tools to create color palettes. I only thought about this because, whenever creating background color for a button in CSS, I fortunately can use the color picker in vscode; however, those tools aren't available in rust or druid. It is a very manual process to decide on the hover color for a button, the active color for a button, and, maybe, a selected color for something like a list item. With a color function I could define one color and programmatically define the other color states.

Another use case, though I don't know who needs this, is you can create color animations without having to implement the functions to manipulate color yourself because they're available as part of druid's color API. And can be combined with alpha blending? (Again not something I know a lot about. I don't know if alpha blending is a thing in druid.)

arthmis commented 3 years ago

I looked over your article again and didn't realize you talk about all the issues I've brought up. So looks like I will be researching into these perceptual color spaces.