avh4 / elm-color

Standard representation of colors, encouraging sharing between packages. (This replaces elm-lang/core#Color from Elm 0.18.)
BSD 3-Clause "New" or "Revised" License
23 stars 6 forks source link

Discussion: who wants to be involved, and how do we coordinate? #3

Open avh4 opened 6 years ago

avh4 commented 6 years ago

Who wants to be working on an elm-color package (and is this repo the best place for discussions to happen?)

avh4 commented 6 years ago

@Libbum I saw you started a colors repo. I'm trying to coordinate what's going on for colors--could you share what you've been doing with it so far and what amount of work you were expecting to do?

avh4 commented 6 years ago

cc folks with color packages: @2mol, @danielnarey, @mdgriffith, @eskimoblood, @Janiczek, @kuon, @the-sett, @rupertlssmith, @dawehner

I'm curious what what interest you're involved in having in getting colors standardized for Elm 0.19 (also see #2 for the first discussion of making a standardized package). (No need to repeat if you already replied on slack!)

danielnarey commented 6 years ago

Thanks for including me. I'm happy to give my point of view and see what the needs are for collaboration.

To stay on track, I'll respond to your thoughts in issue #2 (@avh4):

there should be a standard data type for Color that should be preferred by all packages that use colors as input or output

Yes.

the Color data type should not expose its constructors to ensure that "Color" remains an abstract interface

I part ways with others in the Elm community on the recommendation for using opaque types and otherwise hiding data structures. For people who are learning, it makes Color seem like something mysterious. What would be the harm if Color were just a simple record?

the package should provide simple functions for converting from/to standard formats (like 0-255 RGB, and hex strings)

Yes. It needs to support RGB, HSL, and hexadecimal representations, with optional alpha.

I agree with Rupert (discourse) that it's probably best to represent internally as RGB to avoid unnecessary conversions

Yes, because browser implementations convert other CSS color representations to RGBA anyway.

I think the API should hint at the distinction between relative and absolute color spaces (e.g., RGB vs sRGB) to help web developers avoid confusion, but also should not require understanding of that distinction to use the API

Can you give an example of what you mean? How is this distinction useful in a browser interface?

I think the above are important to do quickly and make available and could be an initial release.

Agree. @the-sett/elm-color seems like a good starting point to me. To add to it, my elm-color-math package includes functions for converting to and from hex strings, as does @eskimoblood/elm-color-extra. The elm-color-math implementation is pure Elm, whereas elm-color-extra uses regular expressions (this is just an observation, I don't know that it matters how it is implemented).

Beyond that, I think there are good questions about how best to handle other things like default colors, palettes, color manipulation, and alternate colorspaces. My thoughts at the moment:

Color manipulation would be good to standardize and put in the module, but it probably takes a bit of design and doesn't need to be in the initial version of this package.

Agree. Would be helpful to articulate specific goals here.

Palettes should probably be separate packages, but could be encouraged to name the modules Color.Palette. for consistency

Agree. But also consider possibility of common utilities for constructing/using palettes.

Unusual colorspaces, like CIELAB, CIECAM02, CIEXYZ, Munsell, etc should probably start as separate packages, and probably stay that way unless they turn out to be very generally useful

Agree. There may be interesting use case for these that I (and others) don't know about – it would be helpful to document them.

Libbum commented 6 years ago

Hi guys. I'm happy to help out, but my motivation is mainly to get some of the packages I've been using up to v0.19 spec. So I don't really have a grand vision at all. I'll be out on a small island for the next week with probably no Internet, so for the moment I won't be of much assistance.

To that end, @avh4 if you're happy to take lead, that's fine with me. My repo is simply an empty placeholder and I've not had the time for any offline work at all yet.

As for some of the open questions in terms of design, my two cents:

I'll have some more input once I get back.

kuon commented 6 years ago

I already discussed a few things with @avh4 on Slack, but I'll just add that I also think the Color type must be a record of the following format:

type alias Color = { red: Float, green: Float, blue: Float, alpha: Float } with normalized values (0->1)

danielnarey commented 6 years ago

After some thinking, I agree with @kuon, because normalized RGB values can be converted to percentages for rendering. I'm accustomed to using 0-255 integers to represent RGB values, but I just confirmed that the CSS3 spec supports percentages. With that in mind, we may as well use Float values to make colors (theoretically) continuous and to simplify the math when doing transformations and conversions.

avh4 commented 6 years ago

(just a note that tomorrow I'll be synthesizing and summarizing all the feedback received so far, and plan to then write up a draft of a proposed API to ask for more specific feedback -- my goal is to get something published (not necessarily under this repo name) that everyone is bought into before the end of the week)

eskimoblood commented 6 years ago

Just out of curiosity, what is the point of passing RGB as float. I mean there are no more then 256 * 256 * 265 RGB colors. And isn't there a risk that the user convert its Int RGB values into floats create a color with it and the library returns different values when it tries to convert this values back to a RGB string because of rounding issues?

kuon commented 6 years ago

@eskimoblood

There are three reasons:

About your rounding issue point, with normalized value the precision is good enough between 0->1 to represent 256steps without rounding error.

To be sure, I checked it with a simple test:

var allMatch = true;

for (var i = 0; i < 256; i++) {
  var normalized = i / 255.0;
  var deNormalized = normalized * JSON.parse("255.0"); // Avoid compiler optimization

  console.log("##################################");
  console.log(`Input: ${i}`);
  console.log(`Normalized float: ${normalized}`);
  console.log(`De normalized float: ${deNormalized}`);

  if (deNormalized !== i) {
    allMatch = false;
  }
}

console.log(`All match: ${allMatch}`);
2mol commented 6 years ago

To answer the original question, I'm open to being involved, however I have no particular expertise in this field, and I've learned that colour can be a very deep topic. Like @Libbum, my interest is in using it in my own packages, with a hope that I can one day use the same type in things like elm-css, elm-plot etc.

I think this repo is a good place to collect the discussion, this way people like me can follow the decisions without being on slack.

avh4 commented 6 years ago

I think the API should hint at the distinction between relative and absolute color spaces (e.g., RGB vs sRGB) to help web developers avoid confusion, but also should not require understanding of that distinction to use the API

Can you give an example of what you mean? How is this distinction useful in a browser interface?

@danielnarey What I think might be valuable here is to make the dinstinction clear to avoid confusion when communicating with designers. Technically, "RGB" is a color model, not a color space--to actually define a color, the RGB value must be interpretted along with a color space which is typically characterized by a CIEXYZ value for max red, max green, and max blue and a whitepoint.

What that means for web developers is: HTML, CSS, and SVG specs state that sRGB is the colorspace that should be used be default (the CSS color module level 4 draft adds the ability to define and reference alternate RGB colorspaces). Web developers typically don't know that RGB doesn't absolutely define a color unless you know which colorspace you're in, while some (though not all) web designers tend to know there's a difference between sRGB and Adobe RGB.

Personally I've worked on projects where web developers have put in specified RGB values only to wonder why the color doesn't match the original designs. But maybe that problem doesn't tend to happen as much anymore since sRGB is more prevalent? I'm not sure. My thought here was that if we name and document things to make it clear that sRGB exists and is what this module is expected when you specify RGB, maybe it could help avoid miscommunication about RGB.

avh4 commented 6 years ago

And isn't there a risk that the user convert its Int RGB values into floats create a color with it and the library returns different values when it tries to convert this values back to a RGB string because of rounding issues?

@eskimoblood I think floats are the way to go for reasons (though if someone has concerns about the time or space performance of floats, I'd be interested to hear about their use case) others have mentioned, though I do agree about your concern about rounding, and was thinking of having a guarantee for the package (along with a test suite to back it up) to say that for all conversion functions, converting something to a Color value and back would be accurate for all integers, and within 0.000001 for all floats.

kuon commented 6 years ago

I agree with the color space thing.

We can either use RGB loosely in the API and document "RGB is sRGB", with a public record type. Or we can make the Color type opaque with accessors like: fromSRGB: {red: Float...} -> Color        toSRGB: Color -> {red: Float....}. (if you come up with nice camel case names for those, I give you a virtual cookie :D ) We can also, in addition to the opaque color type, have some public type alias SRGBComponents = {red: Float...} to make the API a bit cleaner.

As long as the public API can in/out records of the form I mention in https://github.com/avh4/elm-color/issues/3#issuecomment-418136341 I think we are good in term of user experience.

I think it would make sense to input and output CSS colors as well, I have a pure elm CSS color parser that I wrote for 0.18, it's closed source, but I should be able I'll update it for 0.19 and "open source it under the license of the future elm-color package". It supports all CSS color formats (I think). Here are the tests:

suite : Test
suite =
    describe "Color Tests"
        [ rgbTest "#442233" 68 34 51
        , rgbTest "#0608bc" 6 8 188
        , rgbTest "#FaC" 255 170 204
        , rgbTest "442233" 68 34 51
        , rgbTest "0608bc" 6 8 188
        , rgbTest "FaC" 255 170 204
        , rgbaTest "#44223343" 68 34 51 67
        , rgbaTest "#0608bc12" 6 8 188 18
        , rgbaTest "#FaC4" 255 170 204 68
        , rgbaTest "44223343" 68 34 51 67
        , rgbaTest "0608bc12" 6 8 188 18
        , rgbaTest "FaC4" 255 170 204 68
        , rgbTest "rgb(23, 24, 12)" 23 24 12
        , rgbTest "rgb(50%, 15%, 56%)" 127.5 38.25 142.8
        , rgbaTest "rgba(23, 24, 12, 0.3)" 23 24 12 76.5
        , rgbaTest "rgba(50%, 15%, 56%, 80%)" 127.5 38.25 142.8 204
        , rgbTest "hsl(60, 23, 70)" 196 196 161
        , rgbTest "hsl(60%, 23%, 70%)" 161 175 196
        , rgbaTest "hsla(60, 23, 70, 0.4)" 196 196 161 102
        , rgbaTest "hsla(60%, 23%, 70%, 70%)" 161 175 196 178.5
        ]
avh4 commented 6 years ago

Thanks for all the comments so far! I've tried to synthesize everything thus far, and wrote out a more detailed API proposal: https://github.com/avh4/elm-color/issues/4 Please look it over and comment (there are also some specific questions I've posed).

Also, feel free to continue discussions in this thread if there's more to say here; I'll be monitoring all the threads and incorporating them into the plan.

danielnarey commented 6 years ago

@avh4 re: color spaces

I understand this in a basic way from having to be aware of ICC profiles with images and graphics. It makes sense to clarify in the documentation that sRGB is the common denominator for rendering colors in the browser.

While we should do our best as designers/developers to get it right, color fidelity on the user side can't be guaranteed because a lot is left up to the browser and display configuration. A few months ago, I switched to the new version of Firefox after using Chrome and related browsers for years, and I found that colors I was using in my own projects looked noticeably darker and duller. After a bit of searching, I came across this explanation (which appears to still be accurate even though it was last updated in 2014), and I was able to change the Firefox color management settings so that colors would render about the same as in Chrome and Safari. While ultimately Firefox is giving more control of color management, it's an unfortunate (and poorly documented) difference in default behavior across browsers.

kuon commented 6 years ago

On September 5, 2018 5:02:39 PM GMT+02:00, Daniel Narey notifications@github.com wrote:

@avh4 re: color spaces

I understand this in a basic way from having to be aware of ICC profiles with images and graphics. It makes sense to clarify in the documentation that sRGB is the common denominator for rendering colors in the browser.

While we should do our best as designers/developers to get it right, color fidelity on the user side can't be guaranteed because a lot is left up to the browser and display configuration. A few months ago, I switched to the new version of Firefox after using Chrome and related browsers for years, and I found that colors I was using in my own projects looked noticeably darker and duller. After a bit of searching, I came across this explanation (which appears to still be accurate even though it was last updated in 2014), and I was able to change the Firefox color management settings so that colors would render about the same as in Chrome and Safari. While ultimately Firefox is giving more control of color management, it's an unfortunate (and poorly documented) difference in default behavior across browsers.

-- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/avh4/elm-color/issues/3#issuecomment-418764224

I agree but I still think we should do it right, elm might be used for another target someday, and it doesn't hurt to take sRGB into account.

-- Nicolas Goy

ianmackenzie commented 4 years ago

I'm happy to be part of discussions - I don't plan on publishing an actual color package myself, but I will be publishing a couple packages that depend on colors pretty heavily (the close-to-release ianmackenzie/elm-3d-scene and the longer-term ianmackenzie/elm-2d-drawing). I'm currently using tesk9/palette in elm-3d-scene for its handy palettes and type-level distinction between opaque and transparent colors, but avh4/elm-color does seem like the better choice for interop/compatibility.