I have personally tried to find this tool inside YUI a few times over the years and have been unsuccessful. An API for color conversions would go a long way for a theme roller and color picker (possibly to place in an RTE UI). There has also been expresion that a unified, documented, and maintained API would be beneficial for Charts.
To create a consistent cross module implementation for color conversion and color attributes. Provide a means to find similar, complementary, splits, hues, tints, and various other color groups from a provided color.
Converting from a given color value should specify the type it is to be converted from. In the event that no given type is provide, defined Regular Expressions will be used to find the best possible match.
Options include (with matched value type):
- keyword (string) // blue
- hex (string|array[3]) // 00f, 0000ff, #00f, #0000ff, [00, 00, 'ff']
- rgb (array[3]) // [0, 0, 255]
- rgbcss (string) // rgb(0, 0, 255)
- rgba (array[4]) // [0, 0, 255, 1]
- rgbacss (string) // rgba(0, 0, 255, 1)
- hsl (array[3]) // [240, 100, 50]
- hslcss (string) // hsl(240, 100%, 50%)
- hsla (array[4]) // [240, 100, 50, 1]
- hslacss (string) // hsla(240, 100%, 50%, 1)
- auto // 'auto'
Converting to a color value should specify the desired return type. If no return type is specified, a default return type (to be identified) will be used. Options requesting an alpha channel when no initial alpha channel is provided in the initial value will return with 1 (opaque).
Options include (with matched value type):
- hex (array[3]) // [00, 00, 'ff']
- hexcss (#string[6]) // #0000ff
- rgb (array[3]) // [0, 0, 255]
- rgbcss (string) // rgb(0, 0, 255)
- rgba (array[4]) // [0, 0, 255, 1]
- rgbacss (string) // rgba(0, 0, 255, 1)
- hsl (array[3]) // [240, 100, 50]
- hslcss (string) // hsl(240, 100%, 50%)
- hsla (array[4]) // [240, 100, 50, 1]
- hslacss (string) // hsla(240, 100%, 50%, 1)
Converting colors from Hex, RGB, HSL, or keyword to any given type.
Y.Color.convert({
'value': 'blue',
'type': 'keyword',
'to': 'rgb'
}); // [ 0, 0, 255 ]
Converting from a given type to a specified type.
Y.Color.toRGB({
'value': 'blue',
'type': 'keyword'
}); // [ 0, 0, 255 ]
Because there are already two methods in YUI relating to color conversion, toRGB() and toHex(), these methods would need to support backwards compatibility with a single value provided. These methods also take in the CSS value for the color property – rgb(0,0,255) – and will need to carry over this value type conversion.
A color group is a collection of colors harmonious to the provided color that may return a fixed number of values (complementary, triad, etc) or a varying number of values (hues, saturations, etc).
For methods returning a varying number of options, count
is provided to specify the number of options to return. The default value for this count is 4. The maximum value is 10. The first value returned is always the converted value initially provided.
Y.Color.getComplementary({
'value': 'blue',
'type': 'keyword',
'to': 'rgb'
}); // [ 255, 184, 0 ]
Y.Color.getSaturations({
'value': 'blue',
'type': 'keyword',
'to': 'hslcss',
'count': 5
}); // ['hsl(240, 100%, 50%)', 'hsl(240, 75%, 50%)', 'hsl(240, 50%, 50%)', 'hsl(240, 25%, 50%)', 'hsl(240, 0%, 50%)' ]
The existing set of keywords in Y.Color [https://github.com/yui/yui3/blob/master/src/dom/js/color.js] contains 16 keywords matched with their hex value. This list will be expanded to the extended list containing 147 svg colors from the W3C [http://www.w3.org/TR/css3-color/#svg-color] matched with hex values.
Y.Color = {
KEYWORDS: {},
REXP: {},
// Conversions
convert: function() {},
toHex: function() {},
toHexCSS: function() {},
toRGB: function() {},
toRGBCss: function() {},
toRGBA: function() {},
toRGBACss: function() {},
toHSL: function() {},
toHSLCss: function() {},
toHSLA: function() {},
toHSLACss: function() {},
// Color Groups
getComplementary: function() {},
getSplit: function() {},
getAnalogous: function() {},
getTriad: function() {},
getTetrad: function() {},
getMonochrome: function() {},
getSimilar: function() {},
getHues: function() {},
getSaturations: function() {}, // returns values from provided color to 0% saturation
getTints: function () {}, // returns values from provided color to 100% lightness
getShades: function () {}, // returns values from provided color to 0% lightness
getOffset: function () {}, // takes type (h,s,l) and an offset % and adjusts the color in that direction
getSimilarBrightness: function () {} // adjusts the provided color to the visible brightness of the match color
};
I am very excited to see a Color module coming to YUI. I do a lot of work with computer graphics and I do a lot of work with YUI so I'm happy when they come together. I'm going to throw out some ideas and some wish list items. I know my use cases are on the extreme end of the spectrum and I don't want to add too much noise to this discussion. I don't expect most of these ideas to be accepted into core but as you build this please consider how Y.Color could be extended.
It would be great to have compositing features. Methods which combine multiple colors in interesting ways, like the layer modes in Photoshop or GIMP. Methods like over, under, add, subtract, multiply, divide, screen, overlay, difference, lighten, darken, dodge, burn, hue, saturation, and value should be included for starters. The math involved with these operations is usually pretty trivial but the issue is getting the colors into and out of these methods, in the right formats, while keeping good performance. How are you intending to solve this in the proposed color groups methods?
It would be great to support more color modes. Not all colors are made with 3 or 4 channels of unsigned 8-bit integers. For example HDR images may store colors as 32-bit floats. RAW images and video formats can store colors with differing bit widths per channel. Many 3D lighting and rendering engines will produce images with many more color channels; in addition to rgba channels there might be other encoded information like z-depth, xyz normals, velocity vectors, etc. CMYK and single channel grayscale are also common color modes. Also HSV is a good color mode to support; it's only slightly different from HSL and despite the CSS standard I feel like HSV is actually more commonly used in graphics.
I would definitely like to be able to see a Y.Image or Y.Video object in the future with the ability to manipulate individual pixels. While it seems like you're building Y.Color mostly for operating on some CSS rules, please consider how it will scale when operating on megapixels.
Other comments:
I don't understand how most of the proposed color groups methods are intended to be used. I feel like most designers like to manually pick their colors and won't try to find colors programmatically. For some applications I can understand something like, find me a text color that will be readable on this background color or vice-versa.
A method like getEyeballLightness sounds really awesome, but isn't that very dependant upon the display device that's being used? Especially if someone has screwed with a monitor's advanced color settings, which I've seen happens frequently and usually improperly. I'm not sure how this could be implemented reliably. Maybe I'm wrong and there are enough displays that render color lightness the same way, but I know just switching from my laptop screen to my monitor makes the whole world look a bit different.