Giter Club home page Giter Club logo

elm-color's People

Contributors

2mol avatar avh4 avatar folkertdev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

elm-color's Issues

Does there need to be a way to get the RGB components as [0,255] ?

Questions:

  • Is there a use case for getting the RGB components as [0,255]? How common is it?
  • If common, should alpha be provided as [0,255], or [0.0,1.0], or both?

Currently, there is toHex, which does the conversion to integers, but only provides the result as a hex string. Is this sufficient for common needs? It is also currently possible to use toRgba and convert the components yourself using (*) 255 >> round.

We could possibly add something like the following:

toRgb255 : Color -> { red : Int, green : Int, blue : Int, alpha : Float }

Discussion: goals of a standard color package

Summary (will be updated throughout the discussion)

Questions to answer:

  • What belongs in the package?
    • Phase 1 (immediately)
      • data type for representing colors
        • alias for RGB record?: No, it's good enough to have functions that provide these records, and keeping internals private gives us implementation flexibility for now.
        • private, opaque type?
      • common conversions
        • which color spaces? / which formats?
          • RGB / RGBA
          • hex string
          • HSL / HSLA
          • other?: Not in v1.0.0
      • a default color palette?
    • Phase 2 (after a bit more design thought)
      • conversion between color spaces?
        • are we representing absolute colors (sRGB, CIEXYZ, etc) or relative colors (RGB, HSL, etc)? or do we need both?
          • HTML, SVG, CSS all specify sRGB, so there's no need to model relative color spaces
      • manipulation of colors?: Will target v1.1.0
    • Phase 3 (not urgent)
      • more multiple palettes?: probably not
  • How should colors be represented?
    • RGBA as integers: is not accurate enough to represent values in other color spaces
    • RGBA as floats
    • handle multiple possible formats internally, and convert as appropriate
    • HSL or CIEXYZ: RGB makes sense since it's what it will be eventually converted to for almost all web dev uses
    • other options?: none suggested
  • other questions...

Use-cases

  • Manipulating colors should be fast enough (avoid unnecessary conversions if possible)
    • How fast is fast enough?
  • It should be easy for users to create colors by any means and use them for any purpose
  • It should be possible (and ideally easy) for package authors to create new packages that interoperate with standard colors

Issues with hue argument in Color.hsla

Currently the hue argument to hsla is of type Float, and expects percentage values from 0.0 to 1.0.

There are a few issues I see here:

  1. Hue is often thought of as an angular measurement (i.e. around the color wheel), so I think specifying 0.0—1.0 will lead to confusion as it has on my team.
  2. There is no way to ensure the 0.0—1.0 range with type-safety, and the behavior is undefined when hue is outside of this range.
  3. In addition to values outside of 0.0—1.0, the Float type can represent NaN and +/- Infinity values, so hsla can fail, yet it always returns a Color.

Possible solutions:
(1) Use an opaque type for the hue input, that could allow the client to specify whether they're thinking of hue in terms of percentage, degrees, or radians, for example.
(2) Apply modular arithmetic to the hue input to allow it to wrap values around its range.
(3) Have hsla return a Result String Color instead of a Color.

API proposal

Goals

  • Define a Color type that is interoperable across Elm packages, meaning:
    • users of Elm packages know that they can create a Color by any means and use it for any purpose
    • authors of packages that consume or produce colors want to use this type so that their package interoperate with other packages that use colors

Guarantees

  • For all supported conversions, fromXX >> toXX guarantees for each component:
    • for Int components, output will match the input in the supported range
    • for Float components, output will be within 0.000001 of the input in the supported range
  • Conversions will be tested against a reference data set to ensure correctness

API

type Color

There has been argument that this should be a type alias Color = { red : Float, green : Float, blue : Float, alpha : Float } -- I think making this a private, opaque type is best at the moment (and probably long-term) because:

  • It gives us freedom in the short term to change the internal representation (which I'm slightly worried might be necessary to get the accuracy guarantees we want as we add more conversions.
  • It gives us the flexibility to do the trick that the old elm-lang/core#Color and kuon/elm-hsluv use to switch on the fly to whatever representation is best suited to the manipulations being done, which can improve both performance and accuracy
  • the RGB representation is still "easily" available with myColor |> toStandardRgb
  • I think the opaque type makes it more likely for other package authors to use this Color type for input and output to their API because it doesn't feel tied to a particular color space
fromRgba : { red : Float, green : Float, blue : Float, alpha : Float } -> Color
fromHsla : { hue : Float, saturation : Float, lightness : Float, alpha : Float } -> Color
  • Note: the floats are all in the range [0..1], with the thought that if you have values that are in some other base (like 255, or 100, or 360 for hue), you can just divide, but always using [0..1] for inputs in the packages makes things consistent and flexible.
  • The name "standardRgb" is meant to indicate these are interpreted as sRGB values (details would be included in the function docs), see discussion at #3 (comment)
  • Should the from* functions take a record instead of separate parameters?
rgb255 : Int -> Int -> Int -> Color
withAlpha : Float -> Color -> Color
rgb : Float -> Float -> Float -> Color
rgba : Float -> Float -> Float -> Float -> Color
hsl : Float -> Float -> Float -> Color
hsla : Float -> Float -> Float -> Float -> Color
  • Note: the floats are all in the range [0..1], with the thought that if you have values that are in some other base (like 255, or 100, or 360 for hue), you can just divide, but always using [0..1] for inputs in the packages makes things consistent and flexible.
  • Should "Rgb255" be "Rgb8" instead? I think 255 is more familiar to web developers.
  • Do we want all combinations of xxx/xxxa, or just the ones that seem most common, or just the ones without alpha since withAlpha can be used?
toRgba : Color -> { red : Float, green : Float, blue : Float, alpha : Float }
toRgb255 : Color -> { red : Int, green : Int, blue : Int, alpha : Float }
toHsla : Color -> { hue : Float, saturation : Float, lightness : Float, alpha : Float }
  • Again, all floats are in the range [0..1] which is meant to be consistent and flexible; worst case is the user just multiplies by the range they need
  • Here it's easy to always include the alpha, since the user can just ignore it if they don't want it.
  • Should toRgb255 return alpha as an Int? That would make sense from reading it, but I believe in practice you tend to need the alpha as a float for most web dev cases.
toHex : Color -> { hex : String, alpha : Float }
  • this returns 6-digit hex
  • it returns a record to make it clear that the string doesn't include the alpha, and to make it readily available for callers that need it
  • should toHex8 be included? It's not supported on all browsers yet
fromHex : String -> Maybe Color
  • Would support 3, 4, 6, and 8 digit hex strings (with or without the leading '#')
  • Is this actually needed? Isn't it a pain to deal with the Maybe?
  • Would it be best to just have this be fromHex : String -> Color, and have it fallback to returning black if the string is invalid? I think this would be easier to use for most cases where people want to use hex color values. What are the downsides?
  • Should there instead or additionally be fromHexInt : Int -> Color that would be used with fromHexInt 0xaacc00 ? I guess there's no reliable way to know how many digits the input has, so I guess that's not feasible.
toCssRgba : Color -> String
toCssHsla : Color -> String

Are these appropriate to include here vs being left to another package?

Basic colors

red, orange, yellow, ...
  • All the colors from the old elm-lang/core#Color module.
  • I think the idea behind that was good: it gives people easy access to simple colors, and also gives nice versions of those colors (that is, it's not the ugly #ff0000 for red, etc).
grayscale : Float -> Color
greyscale : Float -> Color

Is this needed? Has it been particularly useful to anyone?

For later discussion (for a future version)

The following are things that probably make sense to include, but I think are less urgent than everything above and can be postponed for now:

  • Color manipulation: darken/lighten/saturate/etc
  • Color accessibility: calculate contrast, or produce a contrasting color
  • Conversion to other color spaces or data formats: are there more spaces and formats that should be included vs being left to other packages?

Discussion: palette and colorspace packages

In addition to this package. I think it would make sense to define a short spec for palette and colorspace packages.

Common

  • Package naming convention
  • Module naming convention
  • Function naming convention
  • What function they must provide

Colorspace

  • Can/should use a type
  • How and what to test
  • How to work with the color package (which construtor to use preferably...)

Palette

  • Maybe a palette package generator? Maintain a JSON and get the elm generated with nice documentation with palette preview. I could write a small utility to do that.

Should fromHex return a Maybe/Result, or just a value?

Currently, fromHex is fromHex : String -> Color, meant for convenience in getting colors specified in hex into Elm, and returns rgb 0 0 0 if the hex string is invalid. Should it instead return a Maybe or Result so it can clearly indicate when a parse error occurs? Or should both functions be provided?

Questions:

  • How is fromHex commonly used?
  • Should fromHex be removed from the 1.0.0 release until more info can be obtained?

Does there need to be a way to create colors with RGB 255 and alpha?

Meaning, using r,g,b values in the range [0,255], and also using an alpha value != 1.0.

Questions:

  • Does anyone need to create colors this way?
  • When doing this, would the alpha value want to be specified in [0,255], or [0,1.0] ?
  • Is this common enough that it merits an additional convenience function?

Currently that could be done with

rgba (toFloat r / 255) (toFloat g / 255) (toFloat b / 255) a

But we could possibly make something more concise. Possibilities might be:

rgb255 r g b |> withAlpha a
rgba255 r g b a

Add hsla color space

Hi :)

I'm really interested in having one solution for color in the Elm ecosystem. One package I'd like to see use elm-color is tesk9/palette because it has a nice api for accessibility. The thing is, palette uses a Color type that can have both an hsl and an rgb representation. So to change the package to use elm-color there would have to be support for an hsla color space. Is this planned?

Discussion: CSS color parser

My use case for CSS color parser is a WYSIWYG editor that produces CSS colors, the rendering is done in elm, I adjust some of the colors before rendering (like ensuring contrast...), that's where I need a CSS color parser.

Follow up of: #4 (comment)

Fuzz Test Failure

After updating the test dependency to add

"elm-explorations/test": "2.0.0 <= v < 3.0.0"

and changing the implementation of tuple2 and tuple3 in tests/ColorTest.elm to the following:

tuple2 : Fuzzer a -> Fuzzer b -> Fuzzer ( a, b )
tuple2 a b =
    Fuzz.pair a b


tuple3 : Fuzzer a -> Fuzzer b -> Fuzzer c -> Fuzzer ( a, b, c )
tuple3 a b c =
    Fuzz.triple a b c

to allow the most recent versions of either elm-test or elm-test-rs to run tests, I got the following tests:


Running 8963 tests. To reproduce these results later,
run elm-test-rs with --seed 1137142392 and --fuzz 100

↓ Color
✗ can represent HSLA colors (fromHsla)

Given ((0.9999999999999998,1,0.9999999999999998),0)

    0
    ╷
    │ Expect.within Absolute 1e-10
    ╵
    0.9999999999999998

↓ Color
✗ can represent HSLA colors (hsl)

Given (0,1.0000000827403713e-10,0.9999999999999998)

    0
    ╷
    │ Expect.within Absolute 1e-10
    ╵
    1.0000000827403713e-10

↓ Color
✗ can represent HSLA colors (hsla)

Given ((0.9999999999999998,1,0.9999999999999998),0)

    0
    ╷
    │ Expect.within Absolute 1e-10
    ╵
    0.9999999999999998


TEST RUN FAILED

Duration: 4510 ms
Passed:   8960
Failed:   3

I'm not sure whether these tests are spuriously failing, whether this reflects a true bug, whether this reflects some error in how I've upgraded the tests (although I don't think this is the case), or whether this is a bug in elm-explorations/test.

FromHex function

Hello!

I'll appreciate if you create a function that reads a string to return Color where the string could be "#AB2727" or "rbg(12,12,22)" or rgba.

Regards.

Duplicating the API to accommodate regional spellings

I just wanted to bring to discussion "grey" vs "gray" and attempting to accommodate regional spellings.

In my opinion, we should settle on one spelling and remove duplicate definitions from the API. Regional spellings don't really matter. As a pertinent example, much of the world spells color as "colour" (essentially all English speaking countries apart from the US), and that's the name of the core data type and the package itself! I think it would be more confusing for users to encounter multiple versions than a single version that may not use their preferred spelling.

I would suggest we give this one to the Brits and steal the spelling of Earl Grey. My two cents.

Color manipulation API proposal

Rough ideas

contrast : Color -> Color -> Float  -- http://gka.github.io/chroma.js/#chroma-contrast
delta : Color -> Color -> Float  -- http://gka.github.io/chroma.js/#chroma-deltae

kuon: I wasn't clear, you can compute lightness with 0.299 * R + 0.587 * G + 0.114 * B (per https://www.w3.org/TR/AERT/#color-contrast) but for accessibility we need more tools, like given a source color, compute a color with enough contrast, taking into account color blindness... The accessibility function might grow quickly depending on user needs. I think this should stay out of the core lib.

I also found a few other ways to compute the lightness with RGB https://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color#596243

darkenBy : Float -> Color -> Color
lightenBy : Float -> Color -> Color  -- "brighten"?
saturateBy : Float -> Color -> Color
desaturateBy : Float -> Color -> Color
shiftHueBy : Float -> Color -> Color

darkenTo : Float -> Color -> Color
lightenTo : Float -> Color -> Color  -- "brighten"?
saturateTo : Float -> Color -> Color
desaturateTo : Float -> Color -> Color
shiftHueTo : Float -> Color -> Color

contrasting : Color -> Color

interpolate : Color -> Color -> Float -> Color -- HSLuv
mix : { color : Color, ... other params } -> { color : Color, ...} -> Color  -- https://stackoverflow.com/questions/1351442/is-there-an-algorithm-for-color-mixing-that-works-like-mixing-real-colors

Reference: list of color-related packages in Elm

For reference, a list of current (or Elm 0.18) packages that relate to colors

Manipulation

  • danielnarey/elm-color-math
  • mdgriffith/elm-color-mixing
  • eskimoblood/elm-color-extra
  • Janiczek/distinct-colors
  • kuon/elm-hsluv

Gradients / Colormaps

  • 2mol/elm-colormaps
  • dawehner/elm-colorbrewer

Palettes / Themes

(there were two or three of these, but Elm 0.18 can't be searched anymore)

Make PRs to other packages that should (and/or have been waiting to) use Color

The goal of this package is to get all Elm packages that produce colors and all Elm packages that consume colors will use this type, so this is a checklist of existing 0.19 packages that might want to switch to using Color.

Guidelines:

Make sure to understand the package author's needs and perspective rather than assuming that using the standard Color type will be the right choice for their package.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.