Skip to content

Instantly share code, notes, and snippets.

@apipkin
Created August 3, 2012 21:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apipkin/1da5e3fb2f66a7068727 to your computer and use it in GitHub Desktop.
Save apipkin/1da5e3fb2f66a7068727 to your computer and use it in GitHub Desktop.

Color

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.

Proposal

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.

From Types

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'

To Types

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

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.

Retrieving Color Groups

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%)' ]

Color Keywords

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.

Proposed API

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
    
};
@solmsted
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment