avh4 / elm-color Goto Github PK
View Code? Open in Web Editor NEWStandard representation of colors, encouraging sharing between packages. (This replaces elm-lang/core#Color from Elm 0.18.)
License: BSD 3-Clause "New" or "Revised" License
Standard representation of colors, encouraging sharing between packages. (This replaces elm-lang/core#Color from Elm 0.18.)
License: BSD 3-Clause "New" or "Revised" License
Questions:
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 }
What is the reason of Color type being opaque?
fromHex
is not exposed. It looks like a bug.
Who wants to be working on an elm-color package (and is this repo the best place for discussions to happen?)
Questions to answer:
Use-cases
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:
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
.
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 withfromHexInt 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?
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?
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:
In addition to this package. I think it would make sense to define a short spec for palette and colorspace packages.
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:
fromHex
commonly used?fromHex
be removed from the 1.0.0 release until more info can be obtained?Meaning, using r,g,b values in the range [0,255], and also using an alpha value != 1.0.
Questions:
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
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?
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)
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
.
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.
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.
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
For reference, a list of current (or Elm 0.18) packages that relate to colors
(there were two or three of these, but Elm 0.18 can't be searched anymore)
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.